延迟加载
延迟加载(lazyLoading):
在需要用到数据时才加载,不需要用到数据时就不加载数据,也叫懒加载,按需加载。应用场景:一对多,多对多
立即加载(eager):
无论数据是否有用,立刻加载。应用场景:一对一,多对一
实现延迟加载案例:
< resultMap id = " accountUser" type = " com.baidu.domain.Account" >
.....
< collection ofType = " com.baidu.domain.User" property = " users"
column = " aid" select = " com.baidu.dao.IUserDao.findUserById" >
.....
</ collection>
</ resultMap>
< select id = " findAccount" resultMap = " accountUser" >
select * from account
</ select>
< select id = " findUserById" resultType = " com.baidu.domain.User" parameterType = " int" >
select * from user where uid = #{aid}
</ select>
collection select : 指定从表的sql(namespace + methodName)
collection column : 指定主表的外键,并由它对从表的参数赋值
association也有select属性,用法类似,但没什么作用
< properties> </ properties>
< settings>
< setting name = " lazyLoadingEnabled" value = " true" > </ setting> //延迟加载的全局开关
< setting name = " aggressiveLazyLoading" value = " false" > </ setting> //侵略性延迟加载
</ settings>
< typeAliases> </ typeAliases>
延迟加载的全局开关:设置为true,表示支持延迟加载配置
侵略性延迟加载: 设置为true,表示任何方法的调用都会加载该对象的所有属性。相当于延迟加载只对这个对象生效第一次,只要一触发一次按需加载,就会立刻加载完这个对象的所有数据;设置为false,表示该对象的所有属性都会按需加载,通常都设置为false。
mybatis缓存(cache)
一级缓存:
一级缓存是sqlSession范围,不需要配置直接就可以使用,当用户第一次查询数据后,mybatis一级缓存就会将该数据的对象存储在sqlSession范围,当再次查询这条数据,就把这个对象直接从缓存中返回。只要sqlSession不调用以下方法,sqlSession的缓存就一直存在: sqlSession.clearCache(), sqlSession.commit(),sqlSession.close(), 增删改(DML)语句,也就是说执行这些方法都会清空一次sqlSession缓存
二级缓存:
二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。由同一个SqlSessionFactory对象生产的同一种SqlSession对象共用二级缓存,
SqlSession session1 = factory.openSession();
SqlSession session2 = factory.openSession();
session1.getMapper(IUserDao.class);
session2.getMapper(IUserDao.class);
一二级缓存注意:
1.使用二级缓存时,所缓存的类必须实现java.io.Serializable 接口,使用序列化方式来保存对象,否则报错。
2.一级缓存保存的是对象;二级缓存保存的是序列化数据,不是对象。
使用一级缓存:user1 == user2 //true,地址值相等 ; 使用二级缓存: user 1 == user 2 //false,地址值不相等
配置二级缓存:
第一步:在SqlMapConfig.xml文件开启二级缓存
< settings>
< setting name = " cacheEnabled" value = " true" > </ setting>
</ settings>
第二步:配置相关mapper的映射文件
< cache/>
第三步:配置statement的useCache属性,目前已知只有select标签支持useCache属性
< select id = " queryUser" resultType = " User" useCache = " true" >
select * from user
</ select>
使用注解开发时,只要跟接口对应的包下存在跟IUserDao接口同名IUserDao.xml映射配置文件,无论这个配置文件是否使用,都会报错。
< mapper class = " com.baidu.dao.IUserDao" > </ mapper>
< package name = " com.baidu.dao" > </ package>
注解开发
1.增
@Insert(value={"insert into user values(#{id},#{username})"}) //标准写法
void insertUser(User user);
2.删
@Delete({"delete from user where id = #{id}"}) //注解的属性是value,并且只有一个属性,可以省略
void deleteUser(Integer id);
3.改
@Update("Update user set username = #{username} where id = #{id}") //注解数组的值只有一个,{}省略
void updateUser(User user);
4.查
@Select("select * from user)
List< User> selectUser();
实体类属性跟数据库字段不匹配
处理方式一:起别名
处理方式二:
@Results(id="resultMap",value={
@Result(id=true,column="id",property="myId"),
@Result(column="username",property="myUsername") //最后一个","可有可无
})
@Select("select * from user)
List< User> selectUser();
多表查询:
多对一,一对一:
public class User{
privatre Account account;
}
@Results(id="resultMap",value={
@Result(id=true,column="id",property="myId"),
@Result(column="username",property="myUsername"),
@Result(column="id",property="account",one=@One(
select="com.baidu.dao.IAccountDao.findAccount",fatchType=""))
})
@Select("select * from user)
List< User> selectUser(); //domain.user
@Select("select * from account where uid = #{uid}")
Account findAccount(Integer id);
@Results > id : 唯一标识,供其他注解引用,使用@ResultMap(value="resultMap")注解引用
@Results > value : Result[]用来指定实体类跟数据库的对应关系
@Result > id : 指定主表主键
@Result > column : 指定数据库的列名
@Result > property : 指定实体类的属性
@Result > column : 主表的外键对应的数据库的列名
@Result > property : 指定从表对应的实体类的属性
@result > one : one = @One{
select="指定用来多表查询的sqlStatement"
fetchType = FetchType.LAZY (延迟加载) / FetchType.EAGER (立即加载)
}
@result > many : many = @Many{ ... } //一对多,多对多
@One默认fetchType是立即加载,@Many默认fetchType是延迟加载
注解开发实现二级缓存:
第一步:在SqlMapConfig.xml配置使用二级缓存
< setting name = " cacheEnabled" value = " true" > </ setting>
第二步:在IUserDao接口名上加@CacheNamespace(blocking=true)注解
@CacheNamespace(blocking=true)
public interface IuserDao{}