Mybatis框架学习4【开发优化】

目录

延时加载

缓存

注解开发


延时加载

概念:当我们查询一些信息时,我们需要的部分进行查询,而暂时不需要的部分不进行查询,从而减轻数据库查询压力

实现:

 需要在sqlMapConfig中设置延迟加载相关配置,即前两项

 <setting name="cacheEnabled" value="true"/>
 <setting name="lazyLoadingEnabled" value="true"/>

缓存

分为一级缓存和二级缓存:

一级缓存在sqlSession域中,当sqlSession没有执行close或是commit方法时,sqlSession会开辟一个缓存域,该域的结构是一个Map,当我们查询同样的数据,mybatis会先去sqlSession中查询是否有,有的话直接拿来用。其所取的是对象。所以两种==返回true。

二级缓存在sqlSessionFactory中,同一个sqlSessionFactory的openSession里,访问相同数据源会先查看有无缓存,有的话直接拿来用。

二级缓存的相关配置:

<setting name="cacheEnabled" value="true"/>

同时在相关Dao.xml配置文件中加入(这里我们以一个UserDao的findById方法举例):

<?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">
<mapper namespace="com.yz.dao.UserDaoImp"><!--这里的namespace对于Dao中接口的位置-->
<!--令Dao支持二级缓存-->
  <cache/>

<!--这里注意将useCache设为true-->
  <select id="findById" parameterType="int" resultType="User" useCache="true">
        select *
        from new_user
        where id like #{uid};
  </select>
</mapper>

 写一个测试方法:

    @Test
    public void testCache(){
        SqlSession session1=factory.openSession();
        UserDaoImp daoImp1=session1.getMapper(UserDaoImp.class);
        User user1=daoImp1.findById(1);
        System.out.println(user1);
        session1.close();

        SqlSession session2=factory.openSession();
        UserDaoImp daoImp2=session2.getMapper(UserDaoImp.class);
        User user2=daoImp2.findById(1);
        System.out.println(user2);
        session1.close();

        System.out.println(user1==user2);
    }

用同一个factory创建不同的sqlSession,去查找同一个对象;会发现user1进行了查询,而user2会直接返回缓存中的内容 。(这里要注意,虽然最后返回的为false,但并不代表两次查找的对象不同,而是缓存中储存的是数据而不是对象,其信息是相同的但无法进行比较)

注解开发

即在Dao接口的方法上使用:@Select(),@Update(),@Insert(),@Delete();后面的括号写上对应的sql语句。

疑惑解答1:为什么在注解里写sql语句就实现了xml配置开发的相同功能?

在这里依然以UserDaoImp的查询所有方法为例进行解析:

package com.yz.dao;

import com.yz.domain.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserDaoImp {
    @Select("select * from new_user")
    List<User> findAll();

}
    <select id="findAll" resultType="com.yz.domain.User"><!--这里必须注意要指定查询结果的封装对象resultType-->
        SELECT * from new_user
    </select>

通过对比,我们可以发现在xml中的信息,在dao接口均可获得:

  • id ---> findAll 方法名
  • resultType ---> <User>
  • sql语句 ---> @Select("select * from new_user")

 所以注解开发仅写入sql语句就可以到达xml配置相同的功能了,这里要注意:这两种方式不能同时存在和使用,否则会导致Mybatis无法识别你要用那种配置,导致报错

疑惑解答2:注解开发如何解决类属性名和表列名不对应的情况?

mybatis给我提供了相关的方法:

@Select("sql语句")
@Results(value = {
            @Result(id = true,column = "",property = ""),
            @Result(id = false,column = "",property = ""),
            @Result(id = false,column = "",property = ""),
            @Result(id = false,column = "",property = ""),
            @Result(id = false,column = "",property = "")
    }/*若不为属性不为id,则id=false可省略,因为其默认值就是false*/

@Results(id = "userMap", value = {
            @Result(id = true,column = "",property = ""),
            @Result(id = false,column = "",property = ""),
            @Result(id = false,column = "",property = ""),
            @Result(id = false,column = "",property = ""),
            @Result(id = false,column = "",property = "")
    }/*若不为属性不为id,则id=false可省略,因为其默认值就是false*/
    )


@Select("sql语句")
@ResultMap("userMap")

上述两种均可使用。

补充:注解开发的一对一,一对多查询配置

1)一对一:依然以一个账户对应一个用户为例说明:

public interface AccountDaoImp {
    /**
     * 查询所有的账号
     * @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 = "com.yz.dao.UserDaoImp.findById",fetchType = FetchType.EAGER))/*一对一查询一般设置其为快加载*/
    })
    List<Account> findAll();
}
public interface UserDaoImp {
    @Select("select * from new_user")
    @Results(id = "userMap", value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(id = false,column = "username",property = "username"),
            @Result(id = false,column = "birthday",property = "birthday"),
            @Result(id = false,column = "sex",property = "sex"),
            @Result(id = false,column = "address",property = "address"),
    } )/*若不为属性不为id,则id=false可省略,因为其默认值就是false*/
    List<User> findAllByAnnotation();


    @Select("select * from new_user where id =#{id}")
    @ResultMap("userMap")
    User findById(int id);
    
}

2)一对多:以一个用户有多个账户为例说明:

@CacheNamespace(blocking = true)//这里是开启二级缓存
public interface UserDaoImp {
    /**
     * 基于注解进行查询
     */
    @Select("select * from new_user")
    @Results(id = "userMap", value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(id = false,column = "username",property = "username"),
            @Result(id = false,column = "birthday",property = "birthday"),
            @Result(id = false,column = "sex",property = "sex"),
            @Result(id = false,column = "address",property = "address"),
            @Result(property = "accounts",column = "id",many = @Many(select = "com.yz.dao.AccountDaoImp.findByUId",fetchType = FetchType.LAZY))/*一对多一般用懒加载*/
    } )/*若不为属性不为id,则id=false可省略,因为其默认值就是false*/
    List<User> findAllByAnnotation();
}
public interface AccountDaoImp {

     /**
     * 根据uid查询账户
     * @param uid
     * @return
     */
    @Select("select * from account where uid = #{uid}")
    List<Account> findByUId(Integer uid);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值