延迟加载

实现多对一的延迟加载(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. Delphi MD5加密

    Delphi MD5加密   1. 引用两个单元        uses   IdHash,IdHashMessageDigest;    2.编写加密函数    function TEncrypti ...

  2. SqlBulkCopy快速插入datatable到数据库中参考代码,以及要注意的问题

    参考代码如下: public class Examination { #region 批量插入一个sheet的专业对应的学科 /// <summary> /// 批量插入一个sheet的专 ...

  3. 右键计算机->属性->高级系统设置->高级->环境变量,添加环境变量(推荐)

    (1)右键计算机->属性->高级系统设置->高级->环境变量,添加环境变量(推荐) QTDIR:D:\Software\Qt\Qt5.2.0\5.2.0\msvc2010_op ...

  4. Leetcode 100 Same Tree 二叉树

    就是判断两棵树的值和结构是否相同 注意:要判断是否所有的树节点是否为NULL /** * Definition for a binary tree node. * struct TreeNode { ...

  5. ude—基于udp的全双工可靠传输协议

    ude是一款基于udp的可靠传输协议,专门用于在数据传输方面对实时性要求较高的应用领域.    tcp协议虽然能保证数据的可靠传输,但它有以下几个缺点:1.tcp的数据确认机制会导致发送方重复发送一些 ...

  6. ios 拿到第一响应者的当前视图

    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; UIView *firstResponder = [keyWi ...

  7. WPF不明内存泄露已解决,白头发也没了

    原文:WPF不明内存泄露已解决,白头发也没了 在使用OpenExpressApp进行WPF应用开发过程中遇到多个内存泄漏的地方,在上一篇中求助了一个内存泄露问题[WPF不明内存泄露原因,头发都白了几根 ...

  8. 图片处理拓展篇 : 图片转字符画(ascii)

    首先要明确思路, 图片是由像素组成的, 不同的像素有不同的颜色(rgb), 那么既然我们要转化为字符画, 最直接的办法就是利用字符串来替代像素, 也就是用不同的字符串来代表不同的像素. 另外图片一般来 ...

  9. 关于C#的可变长参数

    可变参数 params===>> params int[] list,传入参数的类型必须是一种类型 static void Main(string[] args) { , , , ); C ...

  10. 图像滤镜艺术---Photoshop实现Instagram之Sierra滤镜

    原文:图像滤镜艺术---Photoshop实现Instagram之Sierra滤镜 本文介绍PS实现Instagram中的Sierra滤镜,内容如下: 先看下效果图: 下面是具体实现步骤: 1. To ...