Mybatis学习02---mybatis查询和多表查询

这篇博客详细介绍了Mybatis的查询操作,包括resultMap的使用、单表查询、多条件与模糊查询,以及${}与#{ }的区别。接着深入探讨了Mybatis映射文件,包括返回主键、动态SQL(if、set、foreach)和SQL片段。最后,博主回顾了表关系,并讲解了一对一、一对多和多对多的多表查询实现,包括实体映射、Mapper接口和XML配置,以及如何进行优化测试。
摘要由CSDN通过智能技术生成

mybatis查询和多表

一 Mybatis单表查询

1.1 resultMap标签

-数据库列名和要封装的实体的属性名完全一致:用 resultType 属性

  • 数据库列名和要封装的实体的属性名有不一致:用 resultMap 属性
① UserMapper接口
    // ResultMap标签
    public List<User> findAllResultMap();
② UserMapper.xml
    <!--
           resultMap 手动建立映射
               id="userResultMap"
               type="com.mybatis.pojo.User" 建立映射的java类型
           id 标签 主键
               column="uid" 列名
               property="id" 实体属性名
          result 标签 普通字段
               column="name" 列名
               property="username" 实体属性名
       -->
    <resultMap id="userResultMap" type="User">
        <id column="uid" property="id"></id>
        <result column="name" property="username"></result>
        <result column="bir" property="birthday"></result>
        <result column="gender" property="sex"></result>
        <result column="address" property="address"></result>
    </resultMap>
    <!--查询所有-->
    <!-- 模拟表与实体的属性名不一致情况-->
    <select id="findAllResultMap" resultMap="userResultMap">
         SELECT id AS uid, username AS `name`,birthday AS bir ,sex AS gender ,address FROM `user`
    </select>
③ 测试
 public static SqlSession sqlSession;

    @Before
    public void before(){
        sqlSession = MyBatisUtils.openSession();
    }

    public void after(){
        MyBatisUtils.close(sqlSession);
    }

    // resultMap标签
    @Test
    public void testFindAllResultMap() throws Exception {
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 执行sql
        List<User> list = userMapper.findAllResultMap();
        for (User user : list) {
            System.out.println(user);
        }
    }

1.2 多条件查询(二种)

需求

根据id和username查询user表

① UserMapper接口
// 多条件查询,方式一
public List<User> findByIdAndUsername1(@Param("id") Integer id, @Param("username") String username);

// 多条件查询,方式二
public List<User> findByIdAndUsername2(User user);
② UserMapper.xml
 <!--
        多条件查询方式一
            如果传递多个参数 parameterType属性省略不写...
    -->
    <select id="findByIdAndUsername1" resultType="com.mybatis.pojo.User">
         SELECT * from user where id = #{id} and username = #{username}
    </select>

    <!--
            多条件查询方式二
                其实mybatis传递一个参数 parameterType也可以省略【不太建议...】
        -->
    <select id="findByIdAndUsername2" parameterType="com.mybatis.pojo.User" resultType="com.mybatis.pojo.User">
          SELECT * from user where id = #{id} and username = #{username}
    </select>
③ 测试
 // 多条件查询
    @Test
    public void test01() throws Exception {
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 方式一
       /* List<User> list = userMapper.findByIdAndUsername1(41, "老王");
        System.out.println(list);*/

        // 方式二
        User user = new User();
        user.setId(41);
        user.setUsername("老王");
        List<User> list = userMapper.findByIdAndUsername2(user);
        System.out.println(list);
    }

1.3 模糊查询(四种)

需求

根据username模糊查询user表

① UserMapper接口
    // 模糊查询,方式一
    public List<User> findByUsername1(String username);

    // 模糊查询,方式二
    public List<User> findByUsername2(String username);

    // 模糊查询,方式三
    public List<User> findByUsername3(String username);

    // 模糊查询,方式四
    public List<User> findByUsername4(String username);
② UserMapper.xml
    <!--
        模糊查询,方式一
            java代码与sql语句有耦合
    -->
    <select id="findByUsername1" parameterType="string" resultType="User">
        select * from user where username like #{username}
    </select>

    <!--
        模糊查询,方式二【了解】
            mysql5.5版本之前,此拼接不支持多个单引号
            oracle数据库,除了别名的位置,其余位置都不能使用双引号
    -->
    <select id="findByUsername2" parameterType="string" resultType="User">
        select * from user where username like "%" #{username} "%"
    </select>

    <!--
        模糊查询,方式三【此方式,会出现sql注入...】
            ${} 字符串拼接,如果接收的简单数据类型,表达式名称必须是value
    -->
    <select id="findByUsername3" parameterType="string" resultType="User">
        select * from user where username like '%${value}%'
    </select>

    <!--
        模糊查询,方式四【掌握】
            使用concat()函数拼接
            注意:oracle数据库 concat()函数只能传递二个参数...  可以使用函数嵌套来解决
    -->
    <select id="findByUsername4" parameterType="string" resultType="User">
        select * from user where username like concat(concat('%',#{username}),'%')
    </select>
③ 测试
    // 模糊查询
    @Test
    public void test02()throws Exception{
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 方式一
        // List<User> list = userMapper.findByUsername1("%王%");
        // 方式二
        // List<User> list = userMapper.findByUsername2("王");
        // 方式三
        // List<User> list = userMapper.findByUsername3("王");
        // 方式四
        List<User> list = userMapper.findByUsername4("王");
        System.out.println(list);
    }

1.4 ${} 与 #{} 区别

${}:底层 Statement

  1. sql与参数拼接在一起,会出现sql注入问题
  2. 每次执行sql语句都会编译一次
  3. 接收简单数据类型,命名:${value}
  4. 接收引用数据类型,命名: ${属性名}
  5. 字符串类型需要加 ‘${value}’

#{}:底层 PreparedStatement

  1. sql与参数分离,不会出现sql注入问题
  2. sql只需要编译一次
  3. 接收简单数据类型,命名:#{随便写}
  4. 接收引用数据类型,命名:#{属性名}

二 Mybatis映射文件深入

环境搭建

把mybatis02_condition复制一份,并重命名,导入已有模块的方式导入
在这里插入图片描述

2.1 返回主键

应用场景

向数据库保存一个user对象后, 然后在控制台记录下此新增user的主键值(id)

① UserMapper接口
public interface UserMapper {

    // 返回主键,方式一
    public void save1(User user);

    // 返回主键,方式二
    public void save2(User user);
}
② UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">

    <!--
        返回主键,方式一 useGeneratedKeys属性
            useGeneratedKeys="true" 开启新增主键返回功能
            keyColumn="id"  user表中主键列
            keyProperty="id" user实体主键属性

            注意:仅支持主键自增类型的数据库 MySQL 和 SqlServer , oracle不支持

    -->
    <insert id="save1" parameterType="User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into user(username,birthday,sex,address)
          values(#{username},#{birthday},#{sex},#{address})
    </insert>

    <!--
        返回主键,方式二  <selectKey>
             keyColumn="id" user表中主键列
             keyProperty="id" user实体主键属性
             resultType="int" user实体主键属性类型
             order="AFTER"  表示此标签内部sql语句在insert执行之前(执行),还是之后执行(执行)
                AFTER 之后执行【在自增主键时】
                BEFORE 之前执行【使用指定主键时】

    -->
    <insert id="save2" parameterType="User" >
        <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into user(username,birthday,sex,address)
          values(#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>
③ 测试
public class UserMapperTest {

    private SqlSession sqlSession = null;

    // 此方法在测试方法执行之前,执行
    @Before
    public void before() {
        // 获取sqlSession对象
        sqlSession = MyBatisUtils.openSession();// 此方法必须线程内独享....
    }

    // 此方法在测试地方法执行之后,执行
    @After
    public void after() {
        // 关闭sqlSession
        MyBatisUtils.close(sqlSession);
    }

    // 返回主键
    @Test
    public void test01() throws Exception {
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setUsername("xiao六");
        user.setBirthday(new Date());
        user.setAddress("中国");
        user.setSex("男");
        // 方式一
        // userMapper.save1(user);
        userMapper.save2(user);

        System.out.println("新增时,主键返回:" + user.getId());
    }
}

2.2 动态SQL

2.2.1 什么是动态SQL

需求

把id和username封装到user对象中,将user对象中不为空的属性作为查询条件
在这里插入图片描述

这个时候我们执行的sql就有多种可能

-- 如果id和用户名不为空
select * from user where id= #{id} and username = #{username}

-- 如果只有id
select * from user where id= #{id} 

-- 如果只有用户名
select * from user where username = #{username}

-- 如果id和用户名都为空
select * from user

像上面这样, 根据传入的参数不同, 需要执行的SQL的结构就会不同,这就是动态SQL

2.2.2 if 条件判断

需求

把id和username封装到user对象中,将user对象中不为空的属性作为查询条件

① UserMapper接口
    // if 条件判断
    public List<User> findByIdAndUsernameIf(User user);
② UserMapper.xml
    <!--
        if标签 条件判断
        where标签  相当于 where 1=1 功能,如果没有条件情况下 where语句不在sql语句拼接
            可以去掉第一个 and 或者 or
    -->
    <select id="findByIdAndUsernameIf" parameterType="User" resultType="User">
        select * from user
        <where>
            <if test="id != null">
                and id= #{id}
            </if>
            <if test="username !=null">
                and username = #{username}
            </if>
        </where>
    </select>
③ 测试
    // if判断
    @Test
    public void test02()throws Exception{
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 拼接条件
        User param = new User();
       // param.setId(41);
        // param.setUsername("老王");

        List<User> list = userMapper.findByIdAndUsernameIf(param);

        for (User user : list) {
            System.out.println(user);
        }
    }

2.2.3 set 用于update语句

需求

动态更新user表数据,如果该属性有值就更新,没有值不做处理

① UserMapper接口
    // set 更新
    public void updateIf(User user);
② UserMapper.xml
<!--
        set标签 更新 ,将条件中的最后一个逗号抹除
    -->
<update id="updateIf" parameterType="User">
    update user
    <set>
        <if test="username !=null">
            username = #{username} ,
        </if>
        <if test="birthday !=null">
            birthday = #{birthday} ,
        </if>
        <if test="sex !=null">
            sex = #{sex} ,
        </if>
        <if test="address != null">
            address = #{address},
        </if>
    </set>
    where id = #{id}
</update>
③ 测试
    @Test
    public void test03()throws Exception{
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 设置更新内容
        User user = new User();
        user.setId(50);
        user.setUsername("小四");

        userMapper.updateIf(user);
    }

2.2.4 foreach 用于循环遍历

需求

根据多个id查询,user对象的集合

select * from user where id in (41,43,46);
* <foreach>标签用于遍历集合,它的属性:

    • collection:代表要遍历的集合元素

    • open:代表语句的开始部分

    • close:代表结束部分

    • item:代表遍历集合的每个元素,生成的变量名

    • sperator:代表分隔符
  1. 普通list集合
  2. 普通array数组
  3. 实体属性list集合
① UserMapper
    // foreach标签,普通list集合
    public List<User> findByList(List<Integer> ids);

    // foreach标签,普通array数组
    public List<User> findByArray(Integer [] ids);

    // foreach标签,实体属性list集合
    public List<User> findByQueryVo(QueryVo queryVo);
② UserMapper.xml
    <!--
        foreach标签,普通list集合
            传递 普通类型list集合   collection="list" 属性取值:collection、list
    -->
    <select id="findByList" parameterType="list" resultType="User">
        select * from user where id in
        <foreach collection="list" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>


    <!--
        foreach标签,普通array数组
            传统 普通类型array数组  collection="array" 属性取值 array
    -->
    <select id="findByArray" parameterType="int" resultType="User">
         select * from user where id in
         <foreach collection="array" open="(" close=")" item="id" separator=",">
             #{id}
         </foreach>
    </select>

    <!--
        foreach标签,实体属性list集合
            传递 实体中list属性集合的话,collection="ids" 取值,实体的属性名
    -->
    <select id="findByQueryVo" parameterType="QueryVo" resultType="User">
         select * from user where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>
③ 测试
    //  foreach标签
    @Test
    public void test04()throws Exception{
        // 获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 普通list集合
       /* List ids = new ArrayList();
        ids.add(41);
        ids.add(46);
        List list = userMapper.findByList(ids);*/
       // 普通array数组
      /* Integer[] ids = {41,46,49};
        List<User> list = userMapper.findByArray(ids);*/

      // 实体属性list集合
        List ids = new ArrayList();
        ids.add(41);
        ids.add(46);
        QueryVo queryVo = new QueryVo();
        queryVo.setIds(ids);
        List<User> list = userMapper.findByQueryVo(queryVo);
        System.out.println(list);
    }

2.3 SQL片段

应用场景

映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

    <!--
        foreach标签,普通list集合
            传递 普通类型list集合   collection="list" 属性取值:collection、list
    -->
    <select id="findByList" parameterType="list" resultType="User">
        <include refid="selectUser"></include> where id in
        <foreach collection="list" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>


    <!--
        foreach标签,普通array数组
            传统 普通类型array数组  collection="array" 属性取值 array
    -->
    <select id="findByArray" parameterType="int" resultType="User">
        <include refid="selectUser"></include>  where id in
         <foreach collection="array" open="(" close=")" item="id" separator=",">
             #{id}
         </foreach>
    </select>

    <!--
        foreach标签,实体属性list集合
            传递 实体中list属性集合的话,collection="ids" 取值,实体的属性名
    -->
    <select id="findByQueryVo" parameterType="QueryVo" resultType="User">
         <include refid="selectUser"></include> where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>


    <!--
        将当前映射文件的共同的sql代码抽取一个片段,实现sql的复用性...
         id="selectUser" 当前sql片段的唯一标识
    -->
    <sql id="selectUser">
         select id,username,birthday,sex,address from user
    </sql>

2.4 小结

MyBatis映射文件配置

<select>:查询

<insert>:插入

<update>:修改

<delete>:删除

<selectKey>:返回主键

<where>:where条件

<if>:if判断

<foreach>:for循环

<set>:set设置

<sql>:sql片段抽取

三 表关系回顾

在关系型数据库当中,表关系分为三种

* 特殊情况:
	一个订单只能从属于一个用户,mybatis框架就把这个多对一看做成一对一来实现
	
* 数据建立表关系:通过主外键关联

* 实体建立关系:通过属性关联

在这里插入图片描述

四 MyBatis多表查询

在这里插入图片描述

4.1 一对一(多对一)

一对一查询模型

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

在这里插入图片描述

① 实体和表映射关系
SELECT * FROM orders o INNER JOIN `user` u ON o.`uid` = u.`id` WHERE o.`id` = 1

在这里插入图片描述

② Order实体类
// 订单实体类
public class Order {

    private Integer id;

    private Date ordertime;

    private Double money;

    // 一个订单从属于一个用户
    private User user;
}
③ OrderMapper接口
public interface OrderMapper {

    // 一对一关联查询
    public Order findByIdWithUser(Integer id);
}
④ OrderMapper.xml

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.OrderMapper">
    <resultMap id="orderResultMap" type="com.mybatis.pojo.Order">
        <id column="id" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="money" property="money"></result>
        <!--
         一对一关联查询 association标签
             resultType:单表映射封装
             resultMap:多表查询必须手动映射封装
         -->
        <association property="user" javaType="com.mybatis.pojo.User">
            <id column="uid" property="id"></id>
            <result column="username" property="username"></result>
            <result column="birthday" property="birthday"></result>
            <result column="sex" property="sex"></result>
            <result column="address" property="address"></result>
        </association>
    </resultMap>

    
    <select id="findByIdWithUser" parameterType="int" resultMap="orderResultMap">
        SELECT * FROM orders o INNER JOIN user u ON o.uid=u.id  WHERE o.id=#{id}
    </select>
</mapper>
⑤ 测试
public class OrderMapperTest {

    private SqlSession sqlSession = null;

    // 此方法在测试方法执行之前,执行
    @Before
    public void before() {
        // 获取sqlSession对象
        sqlSession = MyBatisUtils.openSession();// 此方法必须线程内独享....
    }

    // 此方法在测试地方法执行之后,执行
    @After
    public void after() {
        // 关闭sqlSession
        MyBatisUtils.close(sqlSession);
    }


    // 一对一关联测试
    @Test
    public void test01()throws Exception{
        // 获取代理对象
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);

        // 根据id查询
        Order order = orderMapper.findByIdWithUser(1);
        System.out.println(order);
    }
}

4.2 一对多

一对多查询模型

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
在这里插入图片描述

① 实体和表关系
SELECT *,o.id AS oid FROM `user` u INNER JOIN orders o ON u.`id` = o.`uid` WHERE u.`id`=41

在这里插入图片描述

② User实体类
public class User {

    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    // 一个用户具有多个订单
    private List<Order> orderList;
}
③ UserMapper接口
public interface UserMapper {

    // 一对多关联
    public User findByIdWithOrders(Integer id);
}
④ UserMapper.xml

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">

    <resultMap id="userMap" type="com.mybatis.pojo.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>

        <!--
           一对多关联 collection标签
               property="orderList" 关联实体集合的属性名
               ofType="com.mybatis.pojo.Order" 关联实体的java类型(集合泛型的类型)
       -->
        <collection property="orderList" ofType="com.mybatis.pojo.Order">
            <id column="oid" property="id"></id>
            <result column="ordertime" property="ordertime"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>
    <select id="findByIdWithOrders" parameterType="int" resultMap="userMap">
        SELECT *,o.id AS oid FROM user u INNER JOIN orders o ON u.id = o.uid WHERE u.id=#{id}
    </select>
</mapper>
⑤ 测试

在这里插入图片描述

public class UserMapperTest extends BaseMapperTest {

    // 一对多测试
    @Test
    public void test01() throws Exception {
        // 获取代理
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user = userMapper.findByIdWithOrders(41);

        System.out.println(user);
    }
}

4.3 多对多(由二个一对多组成)

多对多查询的模型

用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用

多对多查询的需求:查询用户同时查询出该用户的所有角色

在mybatis中多对多实现,跟一对多步骤是一样,区别就在于sql语句

在这里插入图片描述

① 实体和表关系
SELECT * FROM `user` u 
	INNER JOIN user_role ur ON u.`id` = ur.`uid`  -- 用户连接中间表
	INNER JOIN role r ON ur.`rid` = r.`id`  -- 再根据中间表连接角色
	WHERE u.id = 41 -- 用户id 作为条件

在这里插入图片描述

② User和Role实体
public class Role {

    private Integer id;

    private String roleName;

    private String roleDesc;
}
public class User {

    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    // 一个用户具有多个角色
    private List<Role> roleList;
}
③ UserMapper接口
    // 多对多关联
    public User findByIdWithRoles(Integer id);
④ UserMapper.xml

在这里插入图片描述

<resultMap id="userWithRoleMap" type="com.mybatis.pojo.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
        <!--
           多对多实现步骤和一对多是一样的(区别在于sql语句)
       -->
        <collection property="roleList" ofType="com.mybatis.pojo.Role">
            <id column="rid" property="id"></id>
            <result column="role_name" property="roleName"></result>
            <result column="role_desc" property="roleDesc"></result>
        </collection>
    </resultMap>
    <!--
       多对多关联
   -->
    <select id="findByIdWithRoles" parameterType="int" resultMap="userWithRoleMap">
        SELECT * FROM user u INNER JOIN user_role ur ON u.id=ur.uid INNER JOIN role r ON r.id=ur.rid WHERE u.id=#{id}
    </select>
⑤ 测试
    // 多对多测试(根据用户查询角色)
    @Test
    public void test02()throws Exception{
        // 获取代理
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user = userMapper.findByIdWithRoles(41);

        System.out.println(user);
    }

4.4拓展

以角色为中心,查询多个用户

SELECT * FROM `role` r INNER JOIN `user_role` ur ON r.`id`=ur.`rid` INNER JOIN `user` u ON u.`id`=ur.`uid` WHERE r.`id`=1

①实体与表关系

在这里插入图片描述

②Role实体类

public class Role {

    private Integer id;

    private String roleName;

    private String roleDesc;

    //一个角色对应多个用户
    private List<User> userList;
}

③RoleMapper接口

public interface RoleMapper {

    // 一对多关联
    Role findByIdWithUser(Integer id);
}

④RoleMapper.xml
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.RoleMapper">

    <resultMap id="roleWithUserMap" type="com.mybatis.pojo.Role">
        <id column="id" property="id"></id>
        <result column="role_name" property="roleName"></result>
        <result column="role_desc" property="roleDesc"></result>
        <!-- 一对多-->
        <collection property="userList" ofType="com.mybatis.pojo.User">
        <id column="uid" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
        </collection>
    </resultMap>

    <select id="findByIdWithUser" resultMap="roleWithUserMap">
        SELECT * FROM role r INNER JOIN user_role ur
        ON r.id=ur.rid INNER JOIN user u ON u.id=ur.uid WHERE r.id=#{id}
    </select>
</mapper>

⑤测试

public class RoleMapperTest {

    protected SqlSession sqlSession = null;

    // 此方法在测试方法执行之前,执行
    @Before
    public void before() {
        // 获取sqlSession对象
        sqlSession = MyBatisUtils.openSession();// 此方法必须线程内独享....
    }

    // 此方法在测试地方法执行之后,执行
    @After
    public void after() {
        // 关闭sqlSession
        MyBatisUtils.close(sqlSession);
    }

    @Test
    public void test1(){
         // 获取代理对象
        RoleMapper mapper = sqlSession.getMapper(RoleMapper.class);
        Role role = mapper.findByIdWithUser(1);
        System.out.println(role);
    }
}

4.5小结

一对一配置:使用<resultMap>+<association>做配置
	association:
    	property:关联的实体属性名
    	javaType:关联的实体类型(别名)

一对多配置:使用<resultMap>+<collection>做配置
	collection:
		property:关联的集合属性名
		ofType:关联的集合泛型类型(别名)

多对多配置:使用<resultMap>+<collection>做配置
	collection:
		property:关联的集合属性名
		ofType:关联的集合泛型类型(别名)
		
多对多的配置跟一对多很相似,难度在于SQL语句的编写。

4.6 优化测试

public class BaseMapperTest {

    protected SqlSession sqlSession = null;

    // 此方法在测试方法执行之前,执行
    @Before
    public void before() {
        // 获取sqlSession对象
        sqlSession = MyBatisUtils.openSession();// 此方法必须线程内独享....
    }

    // 此方法在测试地方法执行之后,执行
    @After
    public void after() {
        // 关闭sqlSession
        MyBatisUtils.close(sqlSession);
    }
}
public class OrderMapperTest extends BaseMapperTest { // 继承父类,就可以直接使用 父类的方法和成员变量了

    // 一对一关联测试
    @Test
    public void test01() throws Exception {
        // 获取代理对象
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);

        // 根据id查询
        Order order = orderMapper.findByIdWithUser(1);
        System.out.println(order);
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值