延迟加载与立即加载的概念
Mybatis中的延迟加载与立即加载
一、一对一实现延迟加载的步骤(多对一,看成一对一)
我们这里是利用account表中的一个方法来做
先来看IAccountDao里面的一个方法
然后再去看持久层IAccountDao.xml
这个方法给我们执行以后会返回如下结果
并且我们可以看到这个语句是一下全部执行完了
现在我们不想它一下执行完,我们想要一个延迟加载,那么就先来修改一下sql语句
就是先把账户信息拿出来,先不做用户信息
那么下面一段映射配置也就没有用了,因为不会马上把信息加载过来
做一下修改:
下面说一下怎么打开Mybatis的延迟策略,在我们下载的Mybatis中有一个参考手册
下面我们去SqlMapConfig.xml去配置一下
为了展示延迟加载,我们把这段代码给注释掉
然后出现一个结果
二、一对多来实现一个延迟加载的操作
上面多对一我们就用到了association来实现了一个延迟加载
下面其实就是用collection标签来实现一个延迟加载
这个涉及到的操作,就是查User类去找account信息,user是主表,account是从表,主表里面引入从表
之前在IUserDao.xml下面存在这样一个方法
这个 方法会查询用户信息,同时把账户信息封装到account里面
我们现在只要先去找到用户信息,然后延迟,需要的时候在加载账户信息,那么此时的账户信息,也就需要一个user的id来进行查找账户
OK,既然说到要用一个id去查找账户的信息,那么我们就要先去IAccountDao实现一个这样的方法
然后去配置IAccountDao.xml文件
下面再去修改IUserDao.xml文件
这上面sql语句肯定要改了
然后配置文件中映射account 对象的部分,也可以不要了,从新配置一下延迟加载方法
运行结果:
也就是user表的一个体现。
Mybatis缓存
一、缓存的概念
二、mybatis的一级二级缓存
先来说一级缓存
之前在IUserDao里面存在一个方法和这个方法的配置
然后我们去测试一下这个方法
测试结果:
我们如何清楚缓存,我们说了这个一级缓存是依赖于什么,依赖于sqlSession的,这个就是内部会给我们产生一个代理对象,然后调用方法
那么如果在执行完了之后,把sqlSession给关闭了呢
那我们下面测试一下,清除缓存
运行代码:
UserTest.java
测试结果:
下面看一级缓存分析
验证一下上面的行为
之前在IUserDao.xml里面存在一个方法
然后现在去UserTest.java里面做一个方法
执行结果
明显地址不一样
下面说一下二级缓存
然后第三步
下面说一下二级缓存存储数据原理
下面用代码测试一下
UserTest.java
在做测试之前,说一点啊,所缓存的类,一定要实现Serializable,这样才可以利用序列化来保存对象,好像也就是说,缓存技术用到了序列化
语句也只有一次执行
Mybatis的注解开发
因为这是注解开发,所以我把Mybatis3复制一份变成Mybatis4
先来说一下大体的一些东西:
1.只要你用了注解,就不能有配置文件
这两者同时存在会报错的, 我们把这个配置文件放到另外一个位置去吧
之前我们配了注解,一般还要去SqlMapConfig.xml里面的<mappers>
注解的话就是配置<mapper class ="com.pxx.dap.IUserDao">
但是我们已经配置了如下
另外说一下啊,常用四个CRUD注解
下面我们来说一下mybatis注解说明
1.类中属性与数据库的字段映射
2. 引用Results定义的封装
3.配置插入操作之后,获取插入数据的id
IUserDao的操作重新配置基本的CURD操作
1.删除或者把IUserDao.xml移动到另外一个,反正不要在resources正确的路径下面
然后在IUserDao.java上面添加注解
直接上代码
package com.pxx.dao;
import com.pxx.domain.QueryVo;
import com.pxx.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface IUserDao {
/**
* 查询所有操作
* @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();
/**
* 保存用户信息操作*/
@Insert("insert into user" +
"(username,address,sex,birthday)" +
"values" +
"(#{username},#{address},#{sex},#{birthday})")
@SelectKey(keyColumn = "id",keyProperty = "id",resultType = Integer.class,
before = false,statement = {"select last_insert_id()"})
void saveUser(User user);
/**
* 用户数据的更新操作*/
@Update(" update user set\n" +
" username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}")
void updateUser(User user);
/**
* 删除某一个用户的操作*/
@Delete(" delete from user where id=#{id}")
void deleteUser(int userId);
/**
* 根据id查询一个用户
* 注意的是这里有个结果集需要封装
* 引用上面配置的Results注解
* */
@Select("select * from user where id=#{id}")
@ResultMap("userMap")
User findById(Integer userId);
/**
* 通过名字进行模糊查询一个用户
* 注意这里也会给我们返回一个封装结果
* @param username
* @return
*/
@Select(" select * from user where username like #{username}")
@ResultMap("userMap")
List<User> findByName(String username);
/**
* 这种int返回数据结果集就可以不用管
* 查询总用户数*/
@Select("select count(id) from user")
int findTotal();
/* *//**
* 根据queryVo的条件来查询对象*//*
List<User> findUserByVo(QueryVo vo);
*//**
* 根据传入参数条件进行查询的例子*//*
List<User> findUserByCondition(User user);
*//**
* 根据queryvo中提供的id集合,查询用户信息*//*
List<User> findUserInIds(QueryVo vo);
*//**
* 查询所有用户信息,并且同时获取每个用户下面的账户信息
*//*
List<User> findAllUser();*/
}
使用注解实现复杂关系映射开发
上面是基本的CURD操作
具体信息
这里是操作IAccountDao.
首先把IAccountDao.xml移动到另外一个目录里面
测试运行
下面来做一个一对多的关系映射
这个就是通过user表来查询account,首先就是一个user对应的是多个account表
user是主表,account是从表,我们需要在主表里面引入从表
需求:查询所有用户信息以及相关相互信息的方法
首先去IAccountDao.java配置一下findByUid这个方法,因为延迟要用
package com.pxx.dao;
import com.pxx.domain.Account;
import com.pxx.domain.AccountUser;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface IAccountDao {
/**
* 查询所有账户,同时获取当前账户的所属信息
*/
@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"),
//这里配置account中的user类
@Result(column="uid",property = "user",
one=@One(select="com.pxx.dao.IUserDao.findById",fetchType= FetchType.LAZY))
}
)
List<Account> findAll();
/**
* 查询所有账户,同时获取账户所属用户名称以及它的地址信息
*/
List<AccountUser> findAllAccount();
/**
* 根据用户id查询账户信息
*/
@Select("select * from account where uid = #{uid}")
@ResultMap("accountMap")
List<Account> findByUid(int uid);
}
下面去IUserDao.java配置
package com.pxx.dao;
import com.pxx.domain.QueryVo;
import com.pxx.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface IUserDao {
/**
* 查询所有操作
* @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(column = "id", property = "accounts",
many = @Many(select = "com.pxx.dao.IAccountDao.findByUid", fetchType = FetchType.LAZY))
})
List<User> findAll();
/**
* 保存用户信息操作*/
@Insert("insert into user" +
"(username,address,sex,birthday)" +
"values" +
"(#{username},#{address},#{sex},#{birthday})")
@SelectKey(keyColumn = "id",keyProperty = "id",resultType = Integer.class,
before = false,statement = {"select last_insert_id()"})
void saveUser(User user);
/**
* 用户数据的更新操作*/
@Update(" update user set\n" +
" username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}")
void updateUser(User user);
/**
* 删除某一个用户的操作*/
@Delete(" delete from user where id=#{id}")
void deleteUser(int userId);
/**
* 根据id查询一个用户
* 注意的是这里有个结果集需要封装
* 引用上面配置的Results注解
* */
@Select("select * from user where id=#{id}")
@ResultMap("userMap")
User findById(Integer userId);
/**
* 通过名字进行模糊查询一个用户
* 注意这里也会给我们返回一个封装结果
* @param username
* @return
*/
@Select(" select * from user where username like #{username}")
@ResultMap("userMap")
List<User> findByName(String username);
/**
* 这种int返回数据结果集就可以不用管
* 查询总用户数*/
@Select("select count(id) from user")
int findTotal();
/* *//**
* 根据queryVo的条件来查询对象*//*
List<User> findUserByVo(QueryVo vo);
*//**
* 根据传入参数条件进行查询的例子*//*
List<User> findUserByCondition(User user);
*//**
* 根据queryvo中提供的id集合,查询用户信息*//*
List<User> findUserInIds(QueryVo vo);
/**
* 查询所有用户信息,并且同时获取每个用户下面的账户信息
*/
@Select("select * from user")
@ResultMap("userMap")
List<User> findAllUser();
}
这里来说一下这个位置
这个位置子啊某个方法配了就代表全局映射,群居都可以调用
在UserTest中测试一下运行结果:
运行结果:
下面说一下基于注解的二级缓存
在Dao上面配置一个注解