D39-Mybatis(04)

Mybatis延迟加载

1.1 延迟加载

  • 又称懒加载,即推迟加载
  • 什么时候使用,什么时候加载
  • 加载: 从数据库表中加载
  • 延迟加载使用在多表关联查询中。
    -association,collection具备延迟加载功能。
  • 原理:
    • 内部使用到动态代理的方式对实体的方法进行增强
    • 在调用该方法时,发送sql查询结果并返回

1.2 延迟加载的使用

1.2.1 在核心配置文件 (sqlMapConfig.xml)开启延迟加载

<properties resource="jdbc.properties"></properties>
    <settings>
        <!-- 开启全局延迟加载开关 -->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

1.2.2 在一对一映射文件(AccountDao.xml)中,配置加载延迟

  • resultMap:用来描述如何从数据库结果集中来加载对象。
  • Type: 实体中属性的类型
 <select id="findAccountAll" resultMap="accountMap">
        SELECT * FROM account ;
    </select>
    <!--
        resultMap:用来描述如何从数据库结果集中来加载对象。
    -->
    <resultMap id="accountMap" type="account">
        <id column="id" property="id"></id>
        <result column="uid" property="uid"></result>
        <result column="money" property="money"></result>
  • 配置一对一加载延迟
    • property: 实体中属性的名称
    • javaType: 实体中属性的类型
    • select: 定位关联的sql语句。
<association property="user" javaType="user"
                     select="com.itheima.dao.UserDao.findUserById"
                     column="uid">
        </association>
    </resultMap>

1.2.2 测试类

@Test
    public void testFindAccountAll(){
      SqlSession sqlSession = sessionFactory.openSession(true);
      AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
      List<Account> list = accountDao.findAccountAll();
      for (int i = 0; i < list.size(); i++) {
          Account account = list.get(i);
          System.out.println(account.getId()+" :"+account.getMoney());
          if (i==1){
              System.out.println(account.getUser());
          }
      }
  }
  @Test
    public void testfindUserById(){
      SqlSession sqlSession = sessionFactory.openSession(true);
      //获取接口的实现类
      UserDao userDao = sqlSession.getMapper(UserDao.class);
      User userById = userDao.findUserById(9);
      System.out.println(userById);
  }

二、 Mybatis缓存

-缓存: 内存中的一块空间,可以减少数据库的查询次数,提高执行效率。

2.1 一级缓存

  • 定义: 一级缓存是SqlSession级别的缓存,只要SqlSession没有flush或close,它就存在。
  • 一级缓存不能被清除。

2.2 二级缓存

  1. 实体类对象需要实现序列化接口

implements Serializable

User中
public class User implements Serializable {
    private Integer id;
    private String username;
    private String sex;
    private String address;
    private Date birthday;
}
  1. 需要在核心配置文件中开启二级缓存

< setting name=“cacheEnabled” value=“true”/>

在开启延迟加载下面添加
3. 需要在sql映射文件 中开启二级缓存

< cache/>

  • UserDao.xml映射文件中
 <!--声明映射文件可以进行二级缓存-->
    <cache/>
    <!--根据id查询用户信息-->
    <select id="findUserById" parameterType="int" resultType="user" useCache="true">
        SELECT * from USER WHERE id= #{id} ;
    </select>
  1. 需要在缓存的sql语句中配置使用二级缓存

userCache=“true”
在第三步的java代码中

  1. 操作的过程中需要提交之后才会存入到缓存中

sqlSession.commit();
sqlSession.close();

  • 在测试类中:
 @Test
    public void testfindUserById(){
      SqlSession sqlSession = sessionFactory.openSession(true);
      //获取接口的实现类
      UserDao userDao = sqlSession.getMapper(UserDao.class);
      User userById = userDao.findUserById(9);
      System.out.println(userById);

      //调用SQLSession的close或commit方法
    //提交之后才会读缓存
    //sqlSession.close();
    sqlSession.commit();

      System.out.println("------------------");
      SqlSession session = sessionFactory.openSession(true);
      //获取dao接口的实现类
      UserDao dao = session.getMapper(UserDao.class);
      User user = dao.findUserById(9);
      System.out.println(user);
  }

三、 Mybatis注解开发

3.1 mybatis的注解说明

  • @Insert: 实现新增
  • @Update:实现更新
  • @Delete:实现删除
  • @Select:实现查询
  • @Result:实现结果集封装
  • @Results:可以与@Result 一起使用,封装多个结果集
  • @One:实现一对一结果集封装
  • @Many:实现一对多结果集封装
  • @SelectProvider: 实现动态 SQL映射

3.2 Mybatis的常用注解

  • @Insert: 实现新增

    • value属性:sql语句
  • @Options :可选配置(获取主键)

    • userGeneratedKeys:开关
    • keyProperty:对象属性
  • @Update:实现更新

    • value:sql语句
  • @Delete

    • value:sql语句
  • @Delete

    • value:sql语句
  • @ SelectProvider:拼接动态sql

  • 配置查询结果和实体属性的映射关系

  • @Results:声明映射关系的配置

    • Value:接受@Result的数组
      • @Result:
        • 1.id: true(默认值为false)
          2.property = “实体中的属性名”
          3.column = “查询结果列名”
  • @Result:配置映射关系

    • Id:(boolean)声明是否为主键配置
      Property:对象中的属性名
      Column:查询的字段名

3.3 增删改查

3.3.1新增

@Insert(value = "insert into user (username,sex,birthday,address)\n" +
            " values (#{username},#{sex},#{birthday},#{address}) ;")
/**
 * useGeneratedKeys:使用最新的id
 * keyProperty:将返回的id设置到id字段上
 */
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void addUser(User user);

3.3.2 更新

@Update(value = " UPDATE user set sex = #{sex} WHERE  id = #{id};")
    int updateUser(User user);

3.3.3 删除

//删除用户信息
    @Delete(value = "DELETE FROM USER WHERE  id= #{id};")
    void deleteUser(int id);

3.3.4 查询

  • 根据id查询
@Select("select * from user where id = #{id} ")
    User findUserById(int id);
  • 模糊查询用户

%${value}% 大括号里的值必须是value!!,否则不报错也查不到信息

 @Select( " SELECT * FROM USER  WHERE  username LIKE  '%${value}%' ;")
    List<User> findUserByName(String username);
  • 根据用户名或性别查询用户信息
 @SelectProvider(type = SqlProviderUtil.class,method = "getSql")
    List<User> findUserByTiaoJian(User user);

3.4 一对一映射

//1.查询所有账号
    @Select("select * from account ")
    /**
     * 配置延迟加载:
     *          Results:
     *              value:配置查询结果与实体字段的对应关系
     */
    @Results(value = {
            //设置主键的对应关系
            @Result(id =true,column = "id",property = "id"),
            //设置普通字段的对应关系
            @Result(column = "uid",property = "uid"),
            //设置普通字段的对应关系
            @Result(column = "money",property = "money"),
            //配置一对一延迟加载
            @Result(
                    property = "user",
                    javaType = User.class,
                    column="uid",
                    one = @One(
                            select = "com.itheima.dao.UserDao.findUserById",
                            fetchType= FetchType.EAGER
                    )
            )
    })
    List<Account> findAccountAll();

3.5 注解的一对多映射

 @Results(
       {
        @Result(id = true,column="id" ,property="id"),
        @Result(column="username" ,property="username"),
        @Result(column="sex" ,property="sex"),
        @Result(column="address", property="address"),
        @Result(column="birthday", property="birthday"),
           @Result(
                property="accountList",
                javaType=List.class,
                column="id",
                 many=@Many(
                      select = "com.itheima.dao.AccountDao.findAccountByUid",
                      fetchType = FetchType.LAZY
                   )
           ) // 配置一对多的延迟加载
         }
    )

猜你喜欢

转载自blog.csdn.net/qq_33852347/article/details/84983019
39