Mybatis(四)

 一、延迟加载

什么是延迟加载

resultMap中的association和collection标签具有延迟加载的功能。

延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息。需要关联信息时再去按需加载关联信息。这样会大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

 

设置延迟加载

Mybatis默认是不开启延迟加载功能的,我们需要手动开启。

需要在SqlMapConfig.xml文件中,在<settings>标签中开启延迟加载功能。

lazyLoadingEnabledaggressiveLazyLoading

 

设置项

描述

允许值

默认值

lazyLoadingEnabled

全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。

true | false

false

aggressiveLazyLoading

当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。

true | false

true

1在SqlMapConfig.xml中配置延迟加载

2在OrderMapper.xml中设置sql语句(按需加载)

3创建OrderMapper接口

4创建Usermapper接口

5创建Usermapper.xml

6测试

 

//1在SqlMapConfig.xml中配置延迟加载
 <!--开启延迟加载的功能-->
    <settings>
        <!--lazyLoadingEnabled :延迟加载启动   默认是false-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--aggressiveLazyLoading:默认是true,就是积极加载,  false按需加载,需要的时候再加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

 

//2在OrderMapper.xml中设置sql语句(按需加载)
  <resultMap id="OrderUserLazyLoadingMap" type="com.javacto.po.Orders">
        <id column="id" property="id"></id>
        <result column="order_Number" property="orderNumber"></result>
        <result column="createtime" property="createtime"></result>
        <result column="describer" property="describer"></result>
        <result column="user_id" property="userId"></result>

        <!--通过 user_id关联查询出用户信息,按需加载
            select 就是我们的
            column:传过去的值
        -->
        <association property="user" select="com.javacto.mapper.UserMapper.findById" column="user_id">

        </association>

    </resultMap>

    <!--查询订单信息,并关联查询出用户信息-->
    <select id="queryOrderUserLazyLoadingMap" resultMap="OrderUserLazyLoadingMap">
        SELECT * FROM orders
    </select>

 

//3创建OrderMapper接口
    //查询订单信息,并关联查询出用户信息
    public List<Orders> queryOrderUserLazyLoadingMap();

 

//4创建Usermapper接口
public interface UserMapper {

    public User findById(int uid);
}

 

//5创建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">
<!--namespace :命名空间,必需是接口全限定名-->
<mapper namespace="com.javacto.mapper.UserMapper">



    <select id="findById" parameterType="int" resultType="User">
        SELECT * FROM t_user WHERE tid=#{tid }
    </select>

</mapper>

 

//6测试
    //3.查询用户信息及用户购买的商品信息,多对多
    @Test
    public void testqueryOrderUserLazyLoadingMap(){
        //1.创建SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //2。
        OrderMapper orderMapper =sqlSession.getMapper(OrderMapper.class);
        //3.调用方法
        List<Orders> list =  orderMapper.queryOrderUserLazyLoadingMap();
        for(Orders o:list){
            //这里我没有显示用户的信息,就没有查询
            System.out.print(o.getId());
            System.out.println(o.getDescriber());

            //现在想显示用户信息,
            System.out.println(o.getUser());


        }
        sqlSession.close();
    }

 

二、缓存

mybatis缓存分析

mybatis提供查询缓存,如果缓存中有数据就不用从数据库中获取,用于减轻数据压力,提高系统性能。

 

 

一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的

 

一、一级缓存

 

第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。

得到用户信息,将用户信息存储到一级缓存中。

如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

Mybatis默认支持一级缓存

 

 

二、二级缓存

下图是多个sqlSession请求UserMapper的二级缓存图解。

 

二级缓存是mapper级别的。

第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。

第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。

如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。

 

开启二级缓存

在核心配置文件SqlMapConfig.xml中加入以下内容(开启二级缓存总开关):

1在settings标签中添加以下内容:

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

 

2在UserMapper映射文件中,加入以下内容,开启二级缓存:

<?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">
<!--namespace :命名空间,必需是接口全限定名-->
<mapper namespace="com.javacto.mapper.UserMapper">

    <!--哪个mapper需要使用, 就在哪个mapper中加cache-->
    <cache ></cache>

    <select id="findById" parameterType="int" resultType="User">
        SELECT * FROM t_user WHERE tid=#{tid }
    </select>


    <!--添加用户
       parameterType 我们需要传参数,参数类型是什么?  对象
   -->


    <insert id="insertUser" parameterType="com.javacto.po.User">
       INSERT INTO t_user VALUES(#{tid},#{uname},now(),#{sex},#{address})

    </insert>

</mapper>

 

3实现序列化

由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。

如果该类存在父类,那么父类也要实现序列化。

 

 

三、注解开发

第一步.Mapper配置类指定接口

<mapper class="com.javacto.day01.UserMapper2"></mapper>

第二步、接口

public interface UserMapper2 {

    //以一起使用注解,同时可以使用xml  我可以再创建一个 UserMapper2.xml
    //根据查询
    @Select("SELECT * FROM t_user WHERE tid=#{tid }")
    public User findUserById002(@Param("tid") int tid);
    //模糊查询
    @Select("SELECT * FROM TUSER WHERE uname LIKE concat(concat('%',#{uname}),'%')")
    public List<User> findByName(String uname);
    //查询所有
    @Select("SELECT * FROM TUSER")
    public List<User> findUserList();
    //添加
    @Insert("INSERT INTO t_user VALUES(#{tid},#{uname},now(),#{sex},#{address})")
    public int insertUser(User user);
    //删除
    @Delete("DELETE FROM TUSER WHERE tid=${id}")
    public int deleteUser(@Param(("id")) int id);

}

 

第三步、测试

public class UserMapper2Test002 {

    //因为现在测试,这里还是有些代码, 以后都不用写
    SqlSessionFactory sqlSessionFactory =null;
    @Before
    public  void setUp() throws IOException {
        //1.获取SqlMapConfig.xml
        String path = "SqlMapConfig.xml";
        //import org.apache.ibatis.io.Resources; 一定不要导错包
        InputStream is = Resources.getResourceAsStream(path);
        //2.创建SqlSessionFactory  我可不可以定义一全局的
        sqlSessionFactory= new SqlSessionFactoryBuilder().build(is);
    }

    @Test
    public void testqueryOrderAndUserRetType(){
        //1.创建SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //2。
        UserMapper2 userMapper2 =sqlSession.getMapper(UserMapper2.class);
        //3.调用方法
        User user = userMapper2.findUserById002(1001);
        System.out.println(user);
        sqlSession.close();

    }


}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值