【1】动态sql之if
    UserMapper.xml中
    if标签中是条件

    1. <select id="findUser" parameterType="user" resultType="User">
    2. select * from test03
    3. <where>
    4. <if test="username != null">
    5. username=#{username}
    6. </if>
    7. <if test="password != null">
    8. and password=#{password}
    9. </if>
    10. </where>
    11. </select>

    测试

    1. @Test
    2. public void test01(){
    3. UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    4. User user = new User();
    5. user.setUsername("张三");
    6. user.setPassword("1232");
    7. List<User> user1 = mapper.findUser(user);
    8. for (User user2 : user1) {
    9. System.out.println(user2);
    10. }
    11. }

    image.png
    【2】mybatis中一对一、一对多、多对一以及多对多的配置
    一对一:账单对用户,一个账单对应一个用户,此时将账单作为主表,用户为从表,主表的实体类中需要聚合一个从表的引用。如果两个表涉及业务,则都需要对应一个Mapper接口与xml文件。
    工程结构:
    image.png
    配置:

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <!--namespace 命名空间 其中内容为持久层接口全类名-->
    6. <mapper namespace="com.jy.mapper.AccountMapper">
    7. <!--建立起实体属性和表字段的对应关系-->
    8. <resultMap id="accountVo" type="account">
    9. <!--匹配主键字段-->
    10. <id column="tid" property="tid"></id>
    11. <!--匹配非主键字段-->
    12. <result column="money" property="money"></result>
    13. <result column="uid" property="uid"></result>
    14. <!--配置一对一的关系-->
    15. <!--association标签的property属性填主表实体类聚合的从表的引用-->
    16. <association property="user" column="uid" javaType="user">
    17. <id column="uid" property="uid"></id>
    18. <result column="username" property="username"></result>
    19. <result column="password" property="password"></result>
    20. </association>
    21. </resultMap>
    22. <select id="findAccountAll" resultType="User" resultMap="accountVo">
    23. select * from ts_account a left join tb_user u on a.uid=u.uid
    24. </select>
    25. </mapper>

    image.png
    一对多:用户对账单 一个用户对应多个账单,此时用户表为主表,在主表中聚合从表的集合引用
    多对一:反过来,多个账单对应一个用户,一对多与多对一只是角度不同
    image.png
    UserMapper.xml

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <!--namespace 命名空间 其中内容为持久层接口全类名-->
    6. <mapper namespace="com.jy.mapper.UserMapper">
    7. <!--建立起实体属性和表字段的对应关系-->
    8. <resultMap id="userVo" type="user">
    9. <!--匹配主键字段-->
    10. <id column="uid" property="uid"></id>
    11. <!--匹配非主键字段-->
    12. <result column="username" property="username"></result>
    13. <result column="password" property="password"></result>
    14. <!--配置一对多的关系,此时不能用association,而是用collection-->
    15. <!--
    16. collection标签的property属性填主表实体类聚合的从表的集合引用
    17. ofType 集合引用的泛型,即account全类名,因设置了别名,所以写account
    18. -->
    19. <collection property="accounts" ofType="account">
    20. <!--匹配主键字段-->
    21. <id column="tid" property="tid"></id>
    22. <!--匹配非主键字段-->
    23. <result column="money" property="money"></result>
    24. <result column="uid" property="uid"></result>
    25. </collection>
    26. </resultMap>
    27. <select id="getUserList" resultMap="userVo">
    28. select * from tb_user u left join ts_account a on u.uid = a.uid
    29. </select>
    30. </mapper>

    多对多:用户和角色,一个用户可以对应多个角色,一个角色也可以对应多个用户.所以各自要聚合另一张表的集合引用。
    多对多在设计表结构的时候,需要指定一个中间表
    image.png
    image.png
    image.png
    查询时将用户表作为的主表,所以在UserMapper.xml 中进行配置,如果将角色表作为主表也可以
    UserMapper.xml

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <!--namespace 命名空间 其中内容为持久层接口全类名-->
    6. <mapper namespace="com.jy.mapper.UserMapper">
    7. <!--建立起实体属性和表字段的对应关系-->
    8. <resultMap id="userVo" type="user">
    9. <!--匹配主键字段-->
    10. <id column="uid" property="uid"></id>
    11. <!--匹配非主键字段-->
    12. <result column="username" property="username"></result>
    13. <result column="password" property="password"></result>
    14. <!--配置多对多的关系-->
    15. <collection property="roles" ofType="role">
    16. <!--匹配主键字段-->
    17. <id column="rid" property="rid"></id>
    18. <!--匹配非主键字段-->
    19. <result column="role_name" property="roleName"></result>
    20. </collection>
    21. </resultMap>
    22. <select id="getUserList" resultMap="userVo">
    23. select u.*,r.* from tb_user u left join user_role ur on u.uid = ur.uid
    24. left join tb_role r on r.rid = ur.rid
    25. </select>
    26. </mapper>

    测试类

    1. /**
    2. * 多对多之查询用户的所有角色
    3. */
    4. @Test
    5. public void test04(){
    6. UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    7. List<User> userList = mapper.getUserList();
    8. for (User user : userList) {
    9. System.out.println(user);
    10. }
    11. }

    【3】懒加载(延迟加载)和立即加载
    什么是延迟加载?
    真正在使用数据时才发起查询,不用的时候不查询,按需加载(懒加载)
    什么是立即加载?
    不管用不用,一调用方法,马上发起查询

    • 针对一对和多对:通常使用延迟加载
    • 针对多对和一对:通常使用立即加载

    例如上面的一对多:用户对账单
    在查询用户数据时,有没有必要将账单数据带出?
    没有必要,采用延迟加载策略
    在查询账单数据时,有没有必要将用户数据带出?
    有必要,因为查询账单时需要知道账单对应的用户是谁,采用延迟加载策略。

    配置延迟加载,在mybatis-config.xml中,注意settings标签写在typeAliase之前

    1. <settings>
    2. <!--开启当前工程的延迟加载-->
    3. <setting name="lazyLoadingEnabled" value="true"/>
    4. <setting name="aggressiveLazyLoading" value="false"/>
    5. </settings>

    (1)一对一示例:
    AccountMapper.xml中进行单表查询:
    image.png
    在一对一关系配置标签association中设置select属性,关联UserMapper.xml中的方法
    image.png
    image.png
    立即加载结果:日志中显示进行了多个表的查询
    image.png
    开启延迟加载结果:只查询了一张表
    image.png
    (2)一对多示例
    UserMapper.xml中进行单表查询
    image.png
    在一对多关系配置标签collection中设置select属性,关联AccountMapper.xml中的方法
    image.png
    image.png
    立即加载结果:进行了多表查询
    image.png
    开启延迟加载:只查询了一张表
    image.png