延迟加载

实现多对一的延迟加载(association)

例如下面的:有很多个账户信息(招商\工商\农商)是属于一个用户人的 
【需求】 
查询账户(Account)信息并且关联查询用户(User)信息。如果先查询账户(Account)信息即可满足要求, 
当我们需要查询用户(User)信息时,再去查询用户信息。

第一步:创建工程

第二步:导入配置文件

第三步:Account.java 
【需求】:查询账户信息同时查询用户信息。

那么大概要用到是两对Dao和Dao.xml以及两个实体类 
Account实体类中加入一个User类的对象

  1. /**
  2. */
  3. public class Account implements Serializable {
  4. private Integer id;
  5. private Integer uid;
  6. private Double money;
  7. private User user;
  8. public User getUser() {
  9. return user;
  10. }
  11. public void setUser(User user) {
  12. this.user = user;
  13. }
  14. }

第四步:AccountDao.java 
AccountDao类中添加查询账户信息的方法:

  1. /**
  2. * 查询账号和客户的信息
  3. */
  4. List<Account> findByAccountUser();

第五步:AccountDao.xml

  1. <!--定义resultMap对象,用来封装账号信息-->
  2. <resultMap id="accountMap" type="account">
  3. <id property="id" column="id"></id>
  4. <result property="uid" column="uid"></result>
  5. <result property="money" column="money"></result>
  6. <!--association用来关联对象,
  7. property代表加载对象,
  8. javaType代表加载对象的数据类型,可以写成com.it.domain.User
  9. select 属性指定的内容:查询用户的唯一标识,指延迟加载要执行的statement的id
  10. 要使用UserDao.xml中的findById完成根据用户id查询用户信息
  11. column 属性指定的内容:用户根据id查询时,所需要的参数的值
  12. -->
  13. <association property="user" column="uid" javaType="user" select="com.it.dao.UserDao.findById">
  14. </association>
  15. </resultMap>
  16. <!-- 查询所有账号 -->
  17. <select id="findByAccountUser" resultMap="accountMap">
  18. select * from account;
  19. </select>

第六步:UserDao.java

  1. /**
  2. * 根据id查询用户信息
  3. * @param id
  4. * @return
  5. */
  6. User findById(Integer id);

第七步:UserDao.xml

  1. <!-- 根据id查询用户 -->
  2. <select id="findById" parameterType="INT" resultType="com.it.domain.User">
  3. select * from user where id = #{uid}
  4. </select>

第八步:测试MybatisTest.java

  1. /**
  2. * 查询所有账户和客户信息(方案二,直接使用Account对象)
  3. */
  4. @Test
  5. public void testFindAllAccountUser(){
  6. //5.执行查询所有方法
  7. List<Account> list = accountDao.findByAccountUser();
  8. }

测试: 
查看sql语句,并没有实现延迟检索,而是立即检索(默认)。 
即【查询账号信息,同时把用户的信息也查询】 

第九步:开启Mybatis的延迟检索策略 
进入Mybaits的官方文档,找到settings的说明信息 
http://www.mybatis.org/mybatis-3/ 

我们发现lazyLoadingEnabled属性的默认是false,表示不会延迟加载。 

配置SqlMapConfig.xml 
这里注意:标签的加载顺序:settings需放到typeAliases的前面

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <properties resource="jdbcConfig.properties"></properties>
  7. <!--需要配置延迟加载策略-->
  8. <settings>
  9. <!--打开延迟加载的开关-->
  10. <setting name="lazyLoadingEnabled" value="true"/>
  11. <!--将积极加载改为消息加载,即按需加载-->
  12. <setting name="aggressiveLazyLoading" value="false"/>
  13. </settings>

第十步:测试MybatisTest.java

  1. /**
  2. * 查询所有账户和客户信息(方案二,直接使用Account对象)
  3. */
  4. @Test
  5. public void testFindAllAccountUser(){
  6. //5.执行查询所有方法
  7. List<Account> list = accountDao.findByAccountUser();
  8. }

查看控制台,此时因为没有查询用户信息,所以只查询了账号的信息。 

我们发现,因为本次只是将Account对象查询出来放入List集合中,并没有涉及到User对象,所以就没有发出SQL语句查询账户所关联的User对象的查询。

我们也可以在AccountDao.xml中使用fethcType属性用来控制延迟检索和立即检索:

fetchType:         eager:立即检索         lazy:延迟检索 
  1. <association property="user" javaType="user" select="com.it.dao.UserDao.findById" column="uid" fetchType="eager">
  2. </association>

实现一对多的延迟加载(collection)

第一步:User.java 
【需求】:查询用户信息同时查询账号信息。 
一个人用户下有多个账号((招商\工商\农商),通常一对多,这个多的账号信息用List封装起来对应Colletion

  1. User实体类中加入一个List<Account>类的对象
  2. public class User implements Serializable {
  3. private Integer id;
  4. private String username;
  5. private String address;
  6. private String sex;
  7. private Date birthday;
  8. private List<Account> accounts;
  9. public List<Account> getAccounts() {
  10. return accounts;
  11. }
  12. public void setAccounts(List<Account> accounts) {
  13. this.accounts = accounts;
  14. }
  15. }

第二步:UserDao.java 
UserDao类中添加查询用户信息和账号信息的方法:

  1. /**
  2. * 根据用户账号的信息
  3. * @param
  4. * @return
  5. */
  6. List<User> findUserAccountList();

第三步:UserDao.xml

  1. <!--定义用户和账号的查询-->
  2. <resultMap id="userMap" type="user">
  3. <id property="id" column="id"></id>
  4. <result property="username" column="username"></result>
  5. <result property="address" column="address"></result>
  6. <result property="sex" column="sex"></result>
  7. <result property="birthday" column="birthday"></result>
  8. <collection property="accounts" ofType="account" select="com.it.dao.AccountDao.findAccountByUid" column="id">
  9. </collection>
  10. </resultMap>
  11. <!-- 根据用户和账号的信息 -->
  12. <select id="findUserAccountList" resultMap="userMap">
  13. SELECT * FROM user
  14. </select>

标签主要用于加载关联的集合对象 
select属性用于指定查询account列表的sql语句,所以填写的是该sql映射的id 
column属性用于指定select属性的sql语句的参数来源,上面的参数来自于user的id列,所以就写成id这一个字段名了 
fetchType:立即和延迟检索的开关 
lazy:延迟检索 
eager:立即检索 
第四步:AccountDao.java

  1. /**
  2. * 根据用户id查询账号信息
  3. * @return
  4. */
  5. List<Account> findAccountByUid(Integer uid);

第五步:AccountDao.xml

  1. <!-- 更加用户id查询账号列表 -->
  2. <select id="findAccountByUid" resultType="account" parameterType="int">
  3. select * from account where uid = #{uid};
  4. </select>

第六步:测试MybatisTest.java

  1. /**
  2. * 查询所有用户和账号信息
  3. */
  4. @Test
  5. public void testFindUserAccountList(){
  6. //5.执行查询所有方法
  7. List<User> list = userDao.findUserAccountList();
  8. for(User user : list){
  9. System.out.println(user);
  10. System.out.println(user.getAccounts().size());
  11. }
  12. }

测试: 
即【查询用户信息,采用延迟检索,需要账号的信息,才查询账号】 

小结:延迟检索会对系统查询数据库做性能的优化 
多对一,一对一的查询,默认是立即检索(不管用没用到一的一端的属性值,因为只查询一次,所以立即检索不会浪费太多性能) 
一对多,多对多的查询,默认是延迟检索(不管用没用到多的一端的属性值,因为会查询多次,所以立即检索会浪费太多性能)

总结:通过本示例,我们可以发现Mybatis的延迟加载还要有很明显效果,对于提升软件性能这是一个不错的手段。 
用的时候:一般项目经理采用延迟检索,用的时候再查询数据库,有助于程序健壮,减少操作数据库的频率。 
如果我们开发,大家记住2点: 
1:可以使用联合查询语句,完成多表的查询(用的比较多,联合查询的sql语句不会出现立即检索和延迟检索) 
2:可以使用select的单独查询(通过主外键),完成多表的查询(考虑立即检索和延迟检索)


Mybatis缓存

像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。 
Mybatis中缓存分为一级缓存,二级缓存 
 
一级缓存:是SqlSession级别的缓存(线程级别的缓存) 
二级缓存:是SqlSessionFactory级别的缓存(进程级别的缓存) 
一个SqlSessionFactory存在多个SqlSession。

一级缓存

指的是Mybatis中SqlSession对象的缓存 
当SqlSession对象消失时,mybatis的一级缓存也就消失了。

两个对象不是同一个对象,SqlSession关闭,缓存消失,会再次查询数据库。

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

第一次发起查询用户id 为1 的用户信息,先去找缓存中是否有id 为1 的用户信息,如果没有,从数据库查询用户信息。 得到用户信息,将用户信息存储到一级缓存中。 如果sqlSession 去执行commit 操作(执行插入、更新、删除),清空SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。 
第二次发起查询用户id 为1 的用户信息,先去找缓存中是否有id 为1 的用户信息,缓存中有,直接从缓存中获取用户信息。

二级缓存

指的是Mybatis中SqlSessionFactory对象的级别缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

二级缓存的使用步骤: 
第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置) 
第二步:让当前的映射文件支持二级缓存(在UserDao.xml中配置) 
第三步:让当前的操作支持二级缓存(在select标签中配置) 
二级缓存结构图 

经过上面的测试,我们发现执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现并没有对数据库发出sql 语句,所以此时的数据就只能是来自于我们所说的二级缓存。 
但是为什么2个对象不一致呢?原理二级缓存中存放的是对象的散装数据,每次查询的时候需要重新封装实体对象。 

SqlSessionFactory存放缓存的地方: 

考虑二级缓存的应用场景: 
适应放置到二级缓存的数据:经常不会发生变化的数据,例如地区编码 
不适合放置到二级缓存的数据:经常变化的数据 
--------------------------------财务数据

Mybatis注解开发

查询所有

把所有的接口配置文件都删除了 
实体类 
src/main/java,创建包com.it.domain,创建User.java

  1. public class User implements Serializable{
  2. private Integer id;
  3. private String username;
  4. private String address;
  5. private String sex;
  6. private Date birthday;
  7. }

接口 
Src/main/java,创建包com.it.dao,创建UserDao.java

  1. /**
  2. * 在mybatis中针对,CRUD一共有四个注解
  3. * @Select @Insert @Update @Delete
  4. */
  5. public interface UserDao {
  6. /**
  7. * 查询所有用户
  8. * @return
  9. */
  10. @Select(value="select * from user")
  11. List<User> findAll();
  12. }

测试MybatisTest.java

  1. /**
  2. */
  3. public class MybatisAnnoTest {
  4. /**
  5. * 测试基于注解的mybatis使用
  6. * @param args
  7. */
  8. public static void main(String[] args) throws Exception{
  9. //1.获取字节输入流
  10. InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
  11. //2.根据字节输入流构建SqlSessionFactory
  12. SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
  13. //3.根据SqlSessionFactory生产一个SqlSession
  14. SqlSession session = factory.openSession();
  15. //4.使用SqlSession获取Dao的代理对象
  16. UserDao userDao = session.getMapper(UserDao.class);
  17. //5.执行Dao的方法
  18. List<User> users = userDao.findAll();
  19. for(User user : users){
  20. System.out.println(user);
  21. }
  22. //6.释放资源
  23. session.close();
  24. in.close();
  25. }
  26. }

使用Mybatis注解实现基本CRUD

UserDao.java

  1. /**
  2. * 在mybatis中针对,CRUD一共有四个注解
  3. * @Select @Insert @Update @Delete
  4. */
  5. public interface UserDao {
  6. /**
  7. * 查询所有用户
  8. * @return
  9. */
  10. @Select("select * from user")
  11. List<User> findAll();
  12. /**
  13. * 保存用户
  14. * @param user
  15. */
  16. @Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
  17. @SelectKey(statement = "SELECT LAST_INSERT_ID()",keyProperty = "id",keyColumn = "id",before = false,resultType = Integer.class)
  18. void saveUser(User user);
  19. /**
  20. * 更新用户
  21. * @param user
  22. */
  23. @Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
  24. void updateUser(User user);
  25. /**
  26. * 删除用户
  27. * @param userId
  28. */
  29. @Delete("delete from user where id=#{id} ")
  30. void deleteUser(Integer userId);
  31. /**
  32. * 根据id查询用户
  33. * @param userId
  34. * @return
  35. */
  36. @Select("select * from user where id=#{uid} ")
  37. User findById(@Param(value = "uid")Integer userId);
  38. /**
  39. * 根据用户名称模糊查询
  40. * @param username
  41. * @return
  42. */
  43. // @Select("select * from user where username like #{username} ")
  44. @Select("select * from user where username like '%${value}%' ")
  45. List<User> findUserByName(String username);
  46. /**
  47. * 查询总用户数量
  48. * @return
  49. */
  50. @Select("select count(*) from user ")
  51. int findTotalUser();
  52. // 传递2个条件或者多个条件
  53. @Select(value = "select * from user where username like #{name} and sex = #{sex}")
  54. List<User> findByNameAndSex(@Param(value = "name") String username, @Param(value = "sex") String sex);
  55. @Select(value = "select * from user where username like #{name} and sex = #{sex}")
  56. List<User> findByNameAndSex2(Map map);
  57. }

当遇到传递非单个参数时需要注意: 
当使用@Param标签作为参数时,测试类只要按照参数的顺序传入即可.
当使用map作为参数导入时,需注意map的key的名字需与注释中设置的{}中的一样 

使用注解实现复杂关系映射开发

实现复杂关系映射之前我们可以在映射文件中通过配置来实现,但通过后我们发现并没有@ResultMap这个注解。下面我们一起来学习@Results注解,@Result注解,@One注解,@Many注解。

修改 UserDao.java 
添加注解:@Results和@Result,在其他的方法中,可以使用@ResultMap指定id的名称。

  1. /**
  2. * 在mybatis中针对,CRUD一共有四个注解
  3. * @Select @Insert @Update @Delete
  4. */
  5. public interface UserDao {
  6. /**
  7. * 查询所有用户
  8. * @return
  9. */
  10. @Select("select * from user")
  11. @Results(id="userMap",value = {
  12. @Result(id = true,property = "userId",column = "id"),
  13. @Result(property = "userName",column = "username"),
  14. @Result(property = "userAddress",column = "address"),
  15. @Result(property = "userSex",column = "sex"),
  16. @Result(property = "userBirthday",column = "birthday")
  17. })
  18. List<User> findAll();
  19. /**
  20. * 根据id查询用户
  21. * @param userId
  22. * @return
  23. */
  24. @Select("select * from user where id=#{uid} ")
  25. @ResultMap(value="userMap")
  26. User findById(Integer userId);
  27. /**
  28. * 根据用户名称模糊查询
  29. * @param username
  30. * @return
  31. */
  32. @Select("select * from user where username like #{username} ")
  33. @ResultMap(value="userMap")
  34. List<User> findUserByName(String username);
  35. }

第三步:测试: 
AnnotationCRUDTest.java

  1. @Test
  2. public void testFindAll(){
  3. List<User> list = userDao.findAll();
  4. for(User user:list){
  5. System.out.println(user);
  6. }
  7. }
  8. @Test
  9. public void testFindOne(){
  10. User user = userDao.findById();
  11. System.out.println(user);
  12. }
  13. @Test
  14. public void testFindByName(){
  15. List<User> users = userDao.findUserByName("%mybatis%");
  16. for(User user : users){
  17. System.out.println(user);
  18. }
  19. }

这里: 
@Results注解 
代替的是标签 
该注解中可以使用单个@Result注解,也可以使用@Result集合 
@Results({@Result(),@Result()})或@Results(@Result()) 
@Result注解 
代替了 标签和标签 
@Result 中 属性介绍: 
id boolean类型,是否是主键,默认是false(非主键) 
column 数据库的列名 
property对象中需要装配的属性名 
one 需要使用的@One注解(@Result(one=@One)())) 
many 需要使用的@Many注解(@Result(many=@many)())) 
@One注解(一对一) 
代替了标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。 
@One注解属性介绍: 
select 指定用来多表查询的sqlmapper 
fetchType会覆盖全局的配置参数lazyLoadingEnabled。。 
使用格式: 
@Result(column=" ",property="",one=@One(select="")) 
@Many注解(一对多) 
代替了标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。 
注意:聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList)但是注解中可以不定义; 
使用格式: 
@Result(property="",column="",many=@Many(select=""))


@One(多对一和一对一场景)

添加User实体类及Account实体类 
【需求】:查询账号信息,同时查询用户信息。 
定义:Account.java实体类

  1. public class Account implements Serializable{
  2. private Integer id;
  3. private Integer uid;
  4. private Double money;
  5. private User user;
  6. }

定义:User.java实体类

  1. public class User implements Serializable{
  2. private Integer userId;
  3. private String userName;
  4. private String userAddress;
  5. private String userSex;
  6. private Date userBirthday;
  7. }

添加UserDao接口及AccountDao接口 
AccountDao.java

  1. public interface AccountDao {
  2. /**
  3. * 查询所有账号
  4. * @return
  5. */
  6. @Select("select * from account")
  7. @Results(id="accountMap",value = {
  8. @Result(id = true,property = "id",column = "id"),
  9. @Result(property = "uid",column = "uid"),
  10. @Result(property = "money",column = "money"),
  11. @Result(property = "user",column = "uid",one=@One(select = "com.it.dao.UserDao.findById",fetchType = FetchType.LAZY))
  12. })
  13. List<Account> findAll();
  14. }

UserDao.java

  1. // 查询所有
  2. @Select(value = "select * from user")
  3. @Results(id="userMap",value = {
  4. @Result(id = true,property = "userId",column ="id" ),
  5. @Result(property = "userName",column ="username" ),
  6. @Result(property = "userAddress",column ="address" ),
  7. @Result(property = "userSex",column ="sex" ),
  8. @Result(property = "userBirthday",column ="birthday" )
  9. })
  10. public List<User> findAll();
  11. /**
  12. * 根据id查询用户
  13. * @param userId
  14. * @return
  15. */
  16. @Select("select * from user where id=#{uid} ")
  17. @ResultMap(value="userMap")
  18. User findById(Integer userId);

测试:AnnotationCRUDTest.java

  1. private InputStream in;
  2. private SqlSessionFactory factory;
  3. private SqlSession session;
  4. private UserDao userDao;
  5. private AccountDao accountDao;
  6. @Before
  7. public void init()throws Exception{
  8. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  9. factory = new SqlSessionFactoryBuilder().build(in);
  10. session = factory.openSession();
  11. userDao = session.getMapper(UserDao.class);
  12. accountDao = session.getMapper(AccountDao.class);
  13. }
  14. @Test
  15. public void testFindAllAccount(){
  16. List<Account> list = accountDao.findAll();
  17. for(Account account:list){
  18. System.out.println(account);
  19. }
  20. }

测试一下:延迟检索和立即检索 
在SqlMapConfig.xml中配置:

  1. <settings>
  2. <!--开启延迟检索策略-->
  3. <setting name="lazyLoadingEnabled" value="true"/>
  4. <setting name="aggressiveLazyLoading" value="false"/>
  5. </settings>

@Many(一对多和多对多)

【需求】:查询所有的用户,将所有用户所对应的账号信息集合查询出来 
添加User实体类及Account实体类 
第一步:定义User.java

  1. public class User implements Serializable{
  2. private Integer userId;
  3. private String userName;
  4. private String userAddress;
  5. private String userSex;
  6. private Date userBirthday;
  7. List<Account> accounts;
  8. }

4.4.3.2添加UserDao接口及AccountDao接口 
第二步:UserDao.java

  1. /**
  2. * 查询所有用户
  3. * @return
  4. */
  5. @Select("select * from user")
  6. @Results(id="userMap",value = {
  7. @Result(id = true,property = "userId",column = "id"),
  8. @Result(property = "userName",column = "username"),
  9. @Result(property = "userAddress",column = "address"),
  10. @Result(property = "userSex",column = "sex"),
  11. @Result(property = "userBirthday",column = "birthday"),
  12. @Result(property = "accounts",column = "id",many = @Many(select = "com.it.dao.AccountDao.findByUid",fetchType = FetchType.LAZY))
  13. })
  14. List<User> findAll();

@Many:相当于的配置

select属性:代表将要执行的sql语句 
fetchType属性:代表加载方式,一般如果要延迟加载都设置为LAZY的值 
column = "id":表示拿主键作为参数,去Account表去查询。 
AcctounDao.java

@Select(value = "select * from account where uid = #{uid}") List<Account> findByUid(Integer uid); 

第三步:AnnotationCRUDTest.java

  1. @Test
  2. public void testFindAll(){
  3. List<User> list = userDao.findAll();
  4. for(User user:list){
  5. System.out.println(user);
  6. System.out.println(user.getAccounts());
  7. }
  8. }

测试立即检索和延迟检索。

使用联合查询的sql语句

【需求】:查询所有的账号信息,同时将账号信息对应的用户信息也查询出来。(使用联合查询) 
第一步:定义sql 
SELECT u.*,a.id AS aid,a.uid,a.money FROM account a,USER u WHERE a.uid = u.id

第二步:Account.java对象

  1. public class Account implements Serializable {
  2. private Integer id;
  3. private Integer uid;
  4. private Double money;
  5. private User user;
  6. }

第三步:在AccountDao.java中定义方法,同时定义@Select注解和@Results注解

  1. // 查询所有的账号,同时关联出所有的用户
  2. @Select(value = "SELECT u.*,a.id AS aid,a.uid,a.money FROM account a,USER u WHERE a.uid = u.id")
  3. @Results(id = "accountUserMap",value = {
  4. @Result(id = true,property = "id",column = "aid"),
  5. @Result(property = "uid",column = "uid"),
  6. @Result(property = "money",column = "money"),
  7. @Result(property = "user.userId",column = "id"),
  8. @Result(property = "user.userName",column = "username"),
  9. @Result(property = "user.userSex",column = "sex"),
  10. @Result(property = "user.userAddress",column = "address"),
  11. @Result(property = "user.userBirthday",column = "birthday"),
  12. })
  13. List<Account> findAllAccountUser2();

第四步:测试

  1. // 查询账号,同时将账号下的用户信息也查询出来
  2. @Test
  3. public void testFindAccountUser2() throws Exception {
  4. List<Account> list = accountDao.findAllAccountUser2();
  5. for (Account account : list) {
  6. System.out.println(account);
  7. }
  8. }

使用注解配置二级缓存

测试类SecondLevelCacheTest .java:

  1. /**
  2. */
  3. public class SecondLevelCacheTest {
  4. private InputStream in;
  5. private SqlSessionFactory factory;
  6. @Before
  7. public void init()throws Exception{
  8. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  9. factory = new SqlSessionFactoryBuilder().build(in);
  10. }
  11. @After
  12. public void destroy()throws Exception{
  13. in.close();
  14. }
  15. @Test
  16. public void testSecondLevelCache(){
  17. SqlSession session = factory.openSession();
  18. UserDao userDao = session.getMapper(UserDao.class);
  19. User user = userDao.findById();
  20. System.out.println(user);
  21. session.close();
  22. // 重新开启
  23. SqlSession session1 = factory.openSession();
  24. UserDao userDao1 = session1.getMapper(UserDao.class);
  25. User user1 = userDao1.findById();
  26. System.out.println(user1);
  27. session1.close();
  28. }
  29. }

添加二级缓存 
第一步:配置SqlMapConfig.xml 

  1. <settings>
  2. <!--开启二级缓存-->
  3. <setting name="cacheEnabled" value="true"/>
  4. </settings>

第二步:配置UserDao.xml

  1. @CacheNamespace(blocking = true) // 使用二级缓存
  2. public interface UserDao {
  3. }

再次测试,发现二级缓存可以使用。 

Mybatis_three的更多相关文章

随机推荐

  1. Docker container 集装箱说明

    容器操作 使用 docker 命令行操作 docker 容器 启动容器 core@localhost ~ $ docker run Usage: docker run [OPTIONS] IMAGE ...

  2. delphi json uLkJSON

    delphi 7 json 做个笔记,留着以后用 --源码 unit Umain; interface uses Windows, Messages, SysUtils, Variants, Clas ...

  3. WPF 控制程序只能启动一次

    原文:WPF 控制程序只能启动一次 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/jsyhello/article/details/7411898 ...

  4. 在.net core不同的版本中 webabi引用的包不同

    core2.0中: 为了要使用MVC Controller 要安装 Microsoft.AspNetCore.Mvc.Core包 Core2.1中:Microsoft.AspNetCore.App

  5. Chrome浏览器离线安装 Postman 5.X 报错

    下载和安装请参考 博友文章http://www.cnblogs.com/wangfeng520/p/5892125.html 尝试安装此扩展程序时出现以下警告: Ignored insecure CS ...

  6. OpenGl(二)点线设置、多边形镂空

    1. 改变点的大小 OpenGL中默认点的大小是1个像素,使用函数glPointSIze可以调整点的大小,入参是GLfloat,相当于是浮点数. 相关代码: void myDisplay(void) ...

  7. Qt Installer Framework 3.0.1 Released(功能比较强)

    We are happy to announce the release of Qt IFW 3.0.1. 3.0.1 is fully compatible with 2.0.5, which me ...

  8. Linux crontab 语法和具体的例子

    基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4列表示 ...

  9. Keil c中自定义带可变参数的printf函数

    在嵌入式c中,往往采用串口打印函数来实现程序的调试,而在正式程序中一般是不需要这些打印代码的,通常做法是在这些调试用打印代码的前后设置一个宏定义块来实现是否启用这段代码,比如: // other us ...

  10. Win8Metro(C#)数字图像处理--2.20图像垂直镜像

    原文:Win8Metro(C#)数字图像处理--2.20图像垂直镜像  [函数名称] 图像垂直镜像函数MirrorYProcess(WriteableBitmap src) [函数代码]      ...