Mybatis学习--ResultMap、动态sql、关联查询




学习目标

  • (1)ResultMap(重要)

    查询数据封装的原理
    字段名和成员名不一致
    ResultMap标签
    
  • (2)动态sql(重要)

    动态sql-if标签
    动态sql-foreach标签
    
  • (3)关联查询(重要)

      关联查询-一对一
      关联查询-一对多
      关联查询-综合案例
    

一、ResultMap

1、ResultMap有什么用?

建立查询字段与实体类成员变量的映射关系

  • 字段名与变量名不一致,可以赋值
    如果查询字段和数据库字段不符,mybatis也可以给它赋值
  • 实现一对多,多对多的查询

2、字段名和成员名不一致

  • (1)为什么id属性能被Mybatis赋值?
    》底层使用id生成setId
    》使用反射调用setId方法,setId(10) 方法内完成赋值 id = 10
  • (2)为什么user_id属性能被Mybatis赋值?
    》底层使用user_id生成setUser_id
    》使用反射调用setUser_id方法,类中只有setUserId
  • (3)所以 为什么强调表与类的对应关系?
    》 字段名和成员名要一致

3、ResultMap标签映射关系,ResultMap使用

<!--
     id是唯一标识,给select 的resultMap属性使用
     -->
    <resultMap id="OrderMap" type="com.smp.bean.Order">
<!--        主键部分-->
        <id column="id" property="id"/>
<!--        非主键部分-->
        <result column="user_id" property="userId"/>
        <!--查询字段名与类的变量名一样的可以不写  -->
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
    </resultMap>
    <select id="findAll" resultMap="OrderMap">
        select * from `order`;
    </select>

二、动态标签介绍

  • (1)动态标签是什么?
    由于mybatis将sql与java代码分离(sql写在xml中)
    if标签,forEach标签
  • (2)动态标签有什么用?
    用来根据数据的不同来生成对应的sql
  • (3)应用场景
    高级搜索功能
    搜索有多个条件,不是每个条件输入框都有值 ,此时需根据值来生成where条件
    在这里插入图片描述

1、动态sql-if标签与where标签

  • (1)if标签
    if标签:可以判断传入的参数是否为空,如果不为空则拼接sql
  • (2)where标签:添加了where标签
    1:不用在初始sql后边写where 1=1
    2: 不用在第一个拼接的sql前写and,但是你也可以手动写and

UserDao.xml

<select id="findByUser" resultType="user">
        select * from user
        <where>
            <if test="username !=null and username !='' ">
                and username like #{
    
    username}
            </if>
            <if test="address !=null and address !='' ">
                and address like #{
    
    address}
            </if>
            <if test="sex !=null and sex !='' ">
                and sex = #{
    
    sex}
            </if>
        </where>
    </select>

Test02.java

public class Test02 {
    
    
    @test
    public void test01(){
    
    

        SqlSession session= MySessionUtils.getSession();
        //开发的 搜索用户,可以根据名字搜索,也可以根据地址搜索。。。

        User user=new User();

        user.setUsername("张%");
        user.setAdress("北京市");

        //由dao执行
        UserDao dao=session.getMapper(UserDao.class);
        List<User> list=dao.findByUser(user);

        System.out.println(list);

        //关闭资源
        session.commit();
        session.close();

2、动态sql-foreach标签

(1)foreach标签
向sql传递数组或List,mybatis使用foreach解析
(2)如何使用
collection:表示方法传入的集合对象的名字
item:遍历集合时,会将集合中的元素赋值给item
open表示你要拼接的sql以什么开始
close:表示你拼接的sql以什么结束
separator:表示拼接的分隔符
接口中的变量名不能被标签识别,必须在参数的前边加注解@Param(“xxx”)

UserDao.xml

<select id="findByIds" parameterType="list" resultType="user">
        select * from user
        <where>
            <foreach collection="ids" item="id" open="id in(" close=")" separator=",">
                #{
    
    id}
            </foreach>
        </where>
    </select>

Test03.java

public class Test03 {
    
    
    //@Test
    public void test01(){
    
    


        SqlSession session = MySessionUtils.getSession();


        UserDao dao = session.getMapper(UserDao.class);

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        //根据多个id值 查找用户
        List<User> users = dao.findByIds(list);
        System.out.println(users);
        //关闭资源
        session.commit();
        session.close();


    }
}

在这里插入图片描述

三、关联查询

(1)项目不可能只有一个表,一般是多表
(2)多表关系为,一对一,一对多,多对多
(3)查询的数据来自多个表,要使用多表查询
笛卡尔集,显示内连接inner join,左外连接left outer join,右外连接right outer join,子查询select嵌套select
(4)查询的结果要封装成javaBean对象 ,在Mybatis中重点掌握resultType与resultMap
在这里插入图片描述

1、关联查询-一对一(1)

(1)关联查询的中的一对一是指,站在订单的角度看,一个订单有一个用户跟它对应
(2)数据来自两个表,使用连接查询,需要输出所有订单,使用左外连接

(3)查询结果可以有两种方式封装数据
》resultType 指定一个自定义javaBean类
》resultMap 指定映射关系

sql语句

select o.id as oid,
	o.user_id ,
	o.number,
	o.createtime,
	o.note,
	u.id as uid,
	u.username,
	u.birthday,
	u.sex,u.address
	from `order` o left join `user` u 
	on o.user_id=u.id;

在这里插入图片描述
测试Test04.java

public class Test04 {
    
    
    @Test
    public void test01(){
    
    

        //ResultType=>类
        SqlSession session = MySessionUtils.getSession();
        //update  insert delete find
        OrderDao orderDao =  session.getMapper(OrderDao.class);
        //List<OrderUer> list=orderDao.findAllOrderUser();
        List<OrderUser> list=orderDao.findAllOrderUser();
        System.out.println(list);
        //关闭资源
        session.commit();
        session.close();


    }
}

在这里插入图片描述

创建新类OrderUser

public class OrderUser {
    
    
    //订单的属性
    //订单id
    private int id;
    //用户id
    private Integer userid;
    //订单号
    private String number;
    //创建时间
    private Date createtime;
    //备注
    private String note;
    //用户的属性
    //用户id
    private int uid;
    //用户名
    private String username;
    //用户生日
    private Date birthday;
    //用户性别
    private String sex;
    //用户地址
    private String address;
  }

ResultType映射OrderDao.xml

<!--    查询结果可以使用resultType来指定每一行记录要保存到哪个javaBean-->
<!--    更多的是使用resultMap-->
    <select id="findAllOrderUser" resultType="com.smp.bean.OrderUser">
    select o.id as oid,
    o.user_id ,
    o.number,
    o.createtime,
    o.note,
    u.id as uid,
    u.username,
    u.birthday,
    u.sex,
    u.address
    from  `order` o left join `user` u
    on o.user_id=u.id;
    </select>

2、关联查询-一对一(2)

(1)分析下属性
(2)association 标签
成员变量的类型为实体类型
(3)如果是关联查询,则必须添加属性:autoMapping=“true”,自动映射

测试Test05.java

public class Test05 {
    
    
    @Test
    public void test01(){
    
    

        //ResultMap=>原来的Order类
        SqlSession session = MySessionUtils.getSession();
        //update  insert delete find
        OrderDao orderDao =  session.getMapper(OrderDao.class);
        List<Order> list=orderDao.findAllOrder2();
        System.out.println(list);
        //关闭资源
        session.commit();
        session.close();


    }
}

在这里插入图片描述
修改Order类Order.java

public class Order {
    
    
    private int id;
    private Integer user_id;
    private String number;
    private Date createtime;
    private String note;
    //增加User成员变量来记录用户的查询字段
    private User user;

定义接口OrderDao.java

/*

    select o.id as id,
	o.user_id as userId,
	o.number,
	o.createtime,
	o.note,
	u.id as uid,
	u.username,
	u.birthday,
	u.sex,
	u.address
 from  `order` o left join `user` u
 on o.user_id=u.id;
     */
    List<Order> findAllOrder2();

ResultType映射与association
OrderDao.xml

如果是关联查询,则必须添加属性:autoMapping="true",自动映射

<resultMap id="findAllOrder2Map" type="com.smp.bean.Order" autoMapping="true">
            <id property="id" column="id"></id>
            <association  property="user" javaType="com.smp.bean.User"  autoMapping="true">
                <id column="uid" property="id"/>

            </association>
    </resultMap>
    <select id="findAllOrder2" resultMap="findAllOrder2Map">
    select o.id as id,
    o.user_id as userId,
    o.number,
    o.createtime,
    o.note,
    u.id as uid,
    u.username,
    u.birthday,
    u.sex,
    u.address
    from  `order` o left join `user` u
    on o.user_id=u.id;
    </select>

3、关联查询-一对多

(1)分析下属性
从用户表的角度看,一个用户可以多次购买,产生多个订单。使用左连接查询每个用户的订单。
(2)查询结果如何转换成JavaBean?
User {
List orders;
}
(3)如何映射关系?
使用resultMap
》映射 id
》映射 集合 collection

测试类Test06.java

public class Test06 {
    
    
    @Test
    public void test01(){
    
    

        //ResultMap=>原来的User类
        SqlSession session = getSession();

        UserDao userDao =  session.getMapper(UserDao.class);
        List<User> list=userDao.findAllUsers();
        //获取用户,然后调用用户的getOrders()
        System.out.println(list);

        session.commit();
        session.close();


    }
}

在这里插入图片描述

修改User类User.java

public class User {
    
    
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String adress;
    //变量类型是集合List
    private List<Order> orders;

定义接口UserDao.java

/*
     select u.id as id,
	u.username,
	u.birthday,
	u.sex,
	u.address,
	o.id,
	o.user_id as userId,
	o.number,
	o.createtime,
	o.note
    from `user` u left join `order` o
    on u.id=o.user_id;

     */
    List<User> findAllUsers();

ResultType映射与collection
UserDao.xml

<!-- 如果字段名与变量名一样,则不需要映射
    如果一个类中出现集合类型,List,则需要使用collection标签了映射,字段与变量的关系
    -->
    <resultMap id="findAllUsersMap" type="com.smp.bean.User" autoMapping="true">
        <id property="id" column="uid"></id>
        <collection property="orders" ofType="com.smp.bean.Order" autoMapping="true">
            <id property="id" column="oid"></id>
        </collection>
    </resultMap>


    <select id="findAllUsers" resultMap="findAllUsersMap">
    select u.id as uid,
    u.username,
    u.birthday,
    u.sex,
    u.address,
    o.id as oid,
    o.user_id as userId,
    o.number,
    o.createtime,
    o.note
    from `user` u left join `order` o
    on u.id=o.user_id;

    </select>

Mybatis学习就到这里,欢迎大家提出意见,到评论区评论哦(o)/

猜你喜欢

转载自blog.csdn.net/qq_41209886/article/details/108802533