MyBatis学习笔记(四)

MyBatis学习笔记(四)

一、MyBatis的延迟加载

问题:

​ 在一对多中,我们有一个用户,它有100个账户,

​ 在查询用户时,要不要吧关联的账户查出来?

​ 在查询账户是,要不要把关联的用户查出来?

答案:

​ 在查询用户时,用户下的账户信息应随用随查(延迟加载)

​ 在查询账户时,账户的所属用户应立即查出来(立即加载)

延迟加载:

​ 在使用数据时才发起查询,不用的时候不查询,又称按需加载(懒加载)

立即加载:

​ 不管用不用,只要调用方法,马上发起查询

一对多,多对多采用延迟加载

一对一,多对一采用立即加载

二、MyBatis延迟加载的实现

举例

​ 使用User与Account模型分别实现一对一与一对多的延迟加载

核心思想:

​ 将sql语句中的多表关联查询改成单表查询,并在需要访问关联数据时,再通过按需查询的方式取出关联数据。

一对一延迟加载实现:

​ 1.在sqlMapConfig.xml配置文件中打开延迟缓存的全局开关

<settings>
	<setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"></setting>
</settings>

​ 1.将account对象中的findAll方法的xml配置文件中的sql语句改成

select * from account

​ 2.在IAccountDao.xml中的resultMap属性中的association中,我们不再配置id与result元素,而是添加select和colomn属性

<association property="user" column="uid" javaType="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>
</association>

-------->

<association property="user" javaType="user" select="com.itheima.dao.IUserDao.findUserById" colomn="uid" ></association>

​ 3.保证IUserDao有findUserById方法及其实现即可

一对多延迟加载实现:

​ 1.将User对象中的findAll方法的xml配置文件中的sql语句改成

select * from user

​ 2.在IUserDao.xml中的resultMap属性中的collection中,我们不再配置id和result元素,而是添加select和colomn属性

 <collection property="accounts" ofType="account">
            <id column="id1" property="id"></id>
            <result column="uid" property="uid"></result>
            <result column="money" property="money"></result>
 </collection>

------------>

<collection type="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" colomn="id"></collection>

​ 3.保证在IAccountDao中有findAccountByUid方法及其实现

三、MyBatis缓存

​ 像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提 高性能。

​ Mybatis 中缓存分为一级缓存,二级缓存。

一级缓存:

​ 一级缓存是 SqlSession级别的缓存,只要SqlSession 没有 flush或 close,它就存在。

一级缓存的清空

​ 当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

二级缓存

​ 二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession可以共用二级缓存,二级缓存是跨 SqlSession 的,但是保存的散装的数据,而不是完整的对象。

二级缓存的开启与关闭:

​ 1.在sqlMapConfig中开启二级缓存

<settings>
    <!-- 开启二级缓存的支持 --> 
    <setting name="cacheEnabled" value="true"/>
</settings>
因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为
false代表不开启二级缓存。

​ 2.配置相关的Mapper映射文件

<mapper namespace="com.itheima.dao.IUserDao"> 
    <!-- 开启二级缓存的支持 --> 
    <cache></cache>
</mapper>

​ 3.配置statement上面的userCache属性

!-- 根据 id查询 -->
<select id="findById" resultType="user" parameterType="int" useCache="true">
    select * from user where id = #{uid}
</select>
将UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement要使用
二级缓存,如果不使用二级缓存可以设置为false。 
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。

四、MyBatis的注解开发

​ 除了通过配置xml文件的方式,MyBatis还支持注解开发。使用注解可以简化开发,提高开发效率,但是当程序体积增大,使用注解相对更加难以维护。

注意事项:

​ 若要使用注解开发,就不能创建接口对应的xml文件,否则MyBatis将会报错。

​ 而且注解开发在sqlMapConfig.xml中的Mapper中要配置class属性而不是resource属性。

<mappers>
	<mapper rescource="com/itheima/dao/IUserDao.xml"></mapper>
</mappers>

---------->

<mappers>
	<mapper class="com.itheima.dao.IUserDao"></mapper>
</mappers>

​ 或者使用package也可以

<mappers>
	<package name="com.itheim.dao"></package>
</mappers>

编写实现:

​ 注解开发可以省去接口对应的xml文件,采用在对应接口的方法前使用注解,并在注解括号中加入sql语句的方式来实现方法。

常用的注解有:

@Insert:实现新增

​ @Update:实现更新

​ @Delete:实现删除

​ @Select:实现查询

​ @Result:实现结果集封装

​ @Results:可以与@Result 一起使用,封装多个结果集

​ @ResultMap:实现引用@Results 定义的封装

​ @One:实现一对一结果集封装

​ @Many:实现一对多结果集封装

​ @SelectProvider: 实现动态SQL映射

​ @CacheNamespace:实现注解二级缓存的使用

1.注解开发实现CRUD操作示例:

增:

	 /**
     * 保存用户
     */
    @Insert("insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})")
    void saveUser(User user);

删:

	 /**
     * 删除用户
     * @param id
     */
    @Delete("delete from user where id =#{id}")
    void deleteUser(Integer id);

改:

	/**
     * 更新用户
     * @param user
     */
    @Update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id =#{id}")
    void updateUser(User user);

查:

	/**
     * 根据id查找
     * @param id
     * @return
     */
    @Select("select * from user where id =#{id}")
    User findById(Integer id);

    /**
     * 根据名称模糊查询
     * @param username
     * @return
     */
    @Select("select * from user where username like #{username}")
    List<User> findByName(String username);
    /**
     * 查询总记录条数
     * @return
     */
    @Select("select count(*) from user")
    Integer totalCount();

2.注解开发实现多表查询:

​ 多表查询通过注解开发也很容易实现,只需要配好@Results属性中的@Result中的@One或@Many即可。select属性配置从表被查询时会调用的方法,FetchType设置加载方式(延迟查询,立即查询)

一对一:

 /**
     * 查询所有账户
     * @return
     */
    @Select("select * from account")
    @Results(id="accountMap",value={
            @Result(property = "user",column ="uid",one=@One(select="com.itheima.dao.IUserDao.findById",fetchType = FetchType.EAGER))
    })
    List<Account> fndAll();

一对多:

 /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id="userMap",value={
            @Result(id=true,property = "id",column = "id"),
            @Result(property = "accounts",column="id",many=@Many(select="com.itheima.dao.IAccountDao.findByUid",fetchType = FetchType.LAZY))
    })
    public List<User> findAll();

3.注解开发使用二级缓存:

​ 不论是xml还是注解开发,一级缓存都是自动开启的。但是二级缓存,需要我们手动开启使用

​ 开启步骤:

​ (1)在sqlMapConfig.xml中开启全局二级缓存开关(自动开启,本步骤可省略)

<!-- 配置开启二级缓存-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

​ (2) 在要求开启的接口上开启二级缓存开关(写在整体接口前)

@CacheNamespace(blocking=true)

​ 开启完毕,直接使用即可

发布了14 篇原创文章 · 获赞 0 · 访问量 157

猜你喜欢

转载自blog.csdn.net/weixin_44580146/article/details/104171659