Mybatis(四)——缓存、注解开发

延迟加载

在一对多的例子中,一个用户加入对应100个账户,但是如果我们只需要用户的信息,那么同时把这100个账户信息也查询出来开销是非常大的。所以在查询信息的时候,我们需要弄明白 需要什么信息,什么时候需要。

  • 延迟加载:
    1.在真正使用数据时才发起查询,不用的时候不查询。按需查询(懒加载)
    2.在多对多,一对多关系中,通常情况下使用延迟加载
  • 立即加载:
    1.不管用不用,只要调用方法,马上发起查询
    2.在多对一,一对一关系中,通常情况下使用立即加载

一对一实现延迟加载

要实现延迟加载,需要在配置文件中设置两个参数:

  • SqlMapConfig.xml
<!--    配置参数 configuration标签下-->
    <settings>
<!--        开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--        开启方法触发延迟加载 按需加载【而不是全部都是延迟加载】,3.4.1之后默认为false-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

配置好参数之后,在IAccountDao.xml中调用IUserDao.xml中的findById方法即可。

    <resultMap id="accountUserMap" type="domain.account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
<!--        一对一的封装映射,也就是封装user的内容
            select 属性指定的内容,查询用户的唯一标识
            column指定的属性,用户根据id查询时,所需要的参数的值
-->
        <association property="user" column="uid" javaType="domain.User" select="dao.IUserDao.findById">

        </association>
    </resultMap>
<!--    查询所有-->
    <select id="findAll" resultMap="accountUserMap">
        select * from account;
    </select>

之后我们可以发现,Account中的User列表只在输出时,查询:

在这里插入图片描述

一对多实现延迟加载

方法和一对一基本相同,配置好参数后,在IUserDao.xml中调用IAccountDao.xml的findById方法,不同的是,这次要用collection标签

  • IUserDao.xml:
    <resultMap id="findAllRole" type="domain.User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <result property="birthday" column="birthday"></result>
        <!-- 注意使用 collection 标签 -->
        <collection property="accounts" ofType="domain.account" select="dao.IAccountDao.findById" column="id">
        </collection>
    </resultMap>
    <select id="findAll" resultMap="findAllRole">
        select * from user;
    </select>

在这里插入图片描述

缓存

  • 缓存:存在于内存中的临时数据。
  • 用处:减少和数据库的交互次数,提高执行效率。
  • 范围:经常查询并且不经常改变,同时数据的正确与否对最终结果影响不大的数据。

一级缓存

Mybatis中sqlSession对象的缓存。
当我们执行查询之后,查询的结果会同时存放于SqlSession提供的一块区域中。该区域的结构是一个Map,存放的是对象。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿来用。
当SqlSession对象消失时,mybatis的一级缓存也就消失了。

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

二级缓存

Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory创建的SqlSession共享其缓存。
二级缓存存放的是数据,不是对象。

二级缓存的使用步骤:

  • 让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
<settings>
<!-- 开启缓存 默认是true-->
    <setting name="cacheEnabled" value="true"/>
</settings>
  • 让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
<mapper namespace="cn.ykf.mapper.UserMapper">
    <!-- 使用缓存 -->
    <cache/>
</mapper>
  • 让当前的操作支持二级缓存(在select标签中配置)
<select id="listAllUsers" resultMap="UserWithAccountsMap" useCache="true">
    SELECT * FROM user
</select>

注解开发

在mybatis中针对crud,一共有四个注解

注解作用
@Select查询
@Insert插入
@Update更新
@Delete删除

单表查询

注解开发只需要在接口方法上写注解即可实现:

package dao;

import domain.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    List<User> findAll();

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

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

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

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

    /**
     * 根据名字查询用户
     * @param username
     * @return
     */
    @Select("select * from user where username like '%${value}%'")
    List<User> findByName(String username);

    /**
     * 查询所有
     * @return
     */
    @Select("select count(*) from user")
    int findTotal();
}

如果属性名和列名不同,可以使用Results和ResultMap注解。

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id = "userMap",value = {
            @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"),
    })
    List<User> findAll();

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

多表查询

多对一

在Results注解中有 @One注解用来执行子查询返回单一对象

    /**
     * 查询所有账户,并且获取对应用户信息
     * @return
     */
    @Select("select * from account")
    @Results(id = "accountMap",value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "uid",property = "uid"),
            @Result(column = "money",property = "money"),
            @Result(property = "user",column = "uid",one = @One(select = "dao.IUserDao.findOneById",fetchType = FetchType.EAGER))
    })
    List<Account> findAll();
一对多
    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id = "userMap",value = {
            @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 = "accounts",column = "id",many = @Many(select = "dao.IAccountDao.findById",fetchType = FetchType.LAZY))
    })
    List<User> findAll();

注解使用二级缓存

在Mybatis中开启全局配置:

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

在持久层接口使用注解:

@CacheNamespace(blocking = true)
public interface UserMapper {
	// .....
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值