Mybatis延迟加载
1.1 延迟加载
- 又称懒加载,即推迟加载
- 什么时候使用,什么时候加载
- 加载: 从数据库表中加载
- 延迟加载使用在多表关联查询中。
-association,collection具备延迟加载功能。 - 原理:
-
- 内部使用到动态代理的方式对实体的方法进行增强
-
- 在调用该方法时,发送sql查询结果并返回
1.2 延迟加载的使用
1.2.1 在核心配置文件 (sqlMapConfig.xml)开启延迟加载
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 开启全局延迟加载开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
1.2.2 在一对一映射文件(AccountDao.xml)中,配置加载延迟
- resultMap:用来描述如何从数据库结果集中来加载对象。
- Type: 实体中属性的类型
<select id="findAccountAll" resultMap="accountMap">
SELECT * FROM account ;
</select>
<!--
resultMap:用来描述如何从数据库结果集中来加载对象。
-->
<resultMap id="accountMap" type="account">
<id column="id" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
- 配置一对一加载延迟
-
- property: 实体中属性的名称
-
- javaType: 实体中属性的类型
-
- select: 定位关联的sql语句。
<association property="user" javaType="user"
select="com.itheima.dao.UserDao.findUserById"
column="uid">
</association>
</resultMap>
1.2.2 测试类
@Test
public void testFindAccountAll(){
SqlSession sqlSession = sessionFactory.openSession(true);
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
List<Account> list = accountDao.findAccountAll();
for (int i = 0; i < list.size(); i++) {
Account account = list.get(i);
System.out.println(account.getId()+" :"+account.getMoney());
if (i==1){
System.out.println(account.getUser());
}
}
}
@Test
public void testfindUserById(){
SqlSession sqlSession = sessionFactory.openSession(true);
//获取接口的实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
User userById = userDao.findUserById(9);
System.out.println(userById);
}
二、 Mybatis缓存
-缓存: 内存中的一块空间,可以减少数据库的查询次数,提高执行效率。
2.1 一级缓存
- 定义: 一级缓存是SqlSession级别的缓存,只要SqlSession没有flush或close,它就存在。
- 一级缓存不能被清除。
2.2 二级缓存
- 实体类对象需要实现序列化接口
implements Serializable
User中
public class User implements Serializable {
private Integer id;
private String username;
private String sex;
private String address;
private Date birthday;
}
- 需要在核心配置文件中开启二级缓存
< setting name=“cacheEnabled” value=“true”/>
在开启延迟加载下面添加
3. 需要在sql映射文件 中开启二级缓存
< cache/>
- UserDao.xml映射文件中
<!--声明映射文件可以进行二级缓存-->
<cache/>
<!--根据id查询用户信息-->
<select id="findUserById" parameterType="int" resultType="user" useCache="true">
SELECT * from USER WHERE id= #{id} ;
</select>
- 需要在缓存的sql语句中配置使用二级缓存
userCache=“true”
在第三步的java代码中
- 操作的过程中需要提交之后才会存入到缓存中
sqlSession.commit();
sqlSession.close();
- 在测试类中:
@Test
public void testfindUserById(){
SqlSession sqlSession = sessionFactory.openSession(true);
//获取接口的实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
User userById = userDao.findUserById(9);
System.out.println(userById);
//调用SQLSession的close或commit方法
//提交之后才会读缓存
//sqlSession.close();
sqlSession.commit();
System.out.println("------------------");
SqlSession session = sessionFactory.openSession(true);
//获取dao接口的实现类
UserDao dao = session.getMapper(UserDao.class);
User user = dao.findUserById(9);
System.out.println(user);
}
三、 Mybatis注解开发
3.1 mybatis的注解说明
- @Insert: 实现新增
- @Update:实现更新
- @Delete:实现删除
- @Select:实现查询
- @Result:实现结果集封装
- @Results:可以与@Result 一起使用,封装多个结果集
- @One:实现一对一结果集封装
- @Many:实现一对多结果集封装
- @SelectProvider: 实现动态 SQL映射
3.2 Mybatis的常用注解
-
@Insert: 实现新增
-
- value属性:sql语句
-
@Options :可选配置(获取主键)
-
- userGeneratedKeys:开关
-
- keyProperty:对象属性
-
@Update:实现更新
-
- value:sql语句
-
@Delete
-
- value:sql语句
-
@Delete
-
- value:sql语句
-
@ SelectProvider:拼接动态sql
-
配置查询结果和实体属性的映射关系
-
@Results:声明映射关系的配置
-
- Value:接受@Result的数组
-
-
- @Result:
-
-
-
-
- 1.id: true(默认值为false)
2.property = “实体中的属性名”
3.column = “查询结果列名”
- 1.id: true(默认值为false)
-
-
-
@Result:配置映射关系
-
- Id:(boolean)声明是否为主键配置
Property:对象中的属性名
Column:查询的字段名
- Id:(boolean)声明是否为主键配置
3.3 增删改查
3.3.1新增
@Insert(value = "insert into user (username,sex,birthday,address)\n" +
" values (#{username},#{sex},#{birthday},#{address}) ;")
/**
* useGeneratedKeys:使用最新的id
* keyProperty:将返回的id设置到id字段上
*/
@Options(useGeneratedKeys = true, keyProperty = "id")
void addUser(User user);
3.3.2 更新
@Update(value = " UPDATE user set sex = #{sex} WHERE id = #{id};")
int updateUser(User user);
3.3.3 删除
//删除用户信息
@Delete(value = "DELETE FROM USER WHERE id= #{id};")
void deleteUser(int id);
3.3.4 查询
- 根据id查询
@Select("select * from user where id = #{id} ")
User findUserById(int id);
- 模糊查询用户
%${value}% 大括号里的值必须是value!!,否则不报错也查不到信息
@Select( " SELECT * FROM USER WHERE username LIKE '%${value}%' ;")
List<User> findUserByName(String username);
- 根据用户名或性别查询用户信息
@SelectProvider(type = SqlProviderUtil.class,method = "getSql")
List<User> findUserByTiaoJian(User user);
3.4 一对一映射
//1.查询所有账号
@Select("select * from account ")
/**
* 配置延迟加载:
* Results:
* value:配置查询结果与实体字段的对应关系
*/
@Results(value = {
//设置主键的对应关系
@Result(id =true,column = "id",property = "id"),
//设置普通字段的对应关系
@Result(column = "uid",property = "uid"),
//设置普通字段的对应关系
@Result(column = "money",property = "money"),
//配置一对一延迟加载
@Result(
property = "user",
javaType = User.class,
column="uid",
one = @One(
select = "com.itheima.dao.UserDao.findUserById",
fetchType= FetchType.EAGER
)
)
})
List<Account> findAccountAll();
3.5 注解的一对多映射
@Results(
{
@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(
property="accountList",
javaType=List.class,
column="id",
many=@Many(
select = "com.itheima.dao.AccountDao.findAccountByUid",
fetchType = FetchType.LAZY
)
) // 配置一对多的延迟加载
}
)