这篇文章将为大家详细讲解有关MyBatis的知识点有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
创新互联-成都网站建设公司,专注成都网站设计、成都做网站、网站营销推广,主机域名,网站空间,网站改版维护有关企业网站制作方案、改版、费用等问题,请联系创新互联。
4.1 注解模式开发
初期的 MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,映射语句也是定义在 XML 中的。而在 MyBatis 3 中,提供了其它的配置方式。MyBatis 3 构建在全面且强大的基于 Java 语言的配置 API 之上。它是 XML 和注解配置的基础。注解提供了一种简单且低成本的方式来实现简单的映射语句。
提示:Java 注解的表达能力和灵活性十分有限。尽管MyBatis团队花了很多时间在调查、设计和试验上,但最强大的 MyBatis 映射并不能用注解来构建。
经验对于单表的操作使用注解更加便利,但是对于复杂的多表,使用注解模式就显得难以维护建议使用XML。
常用注解
| 注解 | 用途 |
|---|---|
| @Insert | 新增 |
| @Update | 更新 |
| @Delete | 删除 |
| @Select | 查询 |
| @Result | 封装结果集 |
| @Results | 与@Result配合,封装多个结果集 |
| @One | 实现一对一结果集封装 |
| @Many | 实现一对多结果集封装 |
以下的查询案例和要求均和XML模式一致,只是将xml操作替换为注解操作
对于注解的查询操作是不需要Mapper.xml配置文件的,因为sql的配置和结果映射都通过注解实现了
SqlMapConfig.xml更新
4.1.1简单操作
对于基础的单表新增、更新、查询、删除操作如下,sql语句和xml一致,这里不多介绍。
public interface UserMapper {
// 新增
@Insert(value = "insert into user(id, username, `password`, birthday) values (#{id}, #{username}, #{password}, #{birthday})")
void addUser(User user);
// 更新
@Update(value = "update user set username = #{username}, `password` = #{password}, birthday = #{birthday} where id = #{id}")
void updateUser(User user);
// 查询
@Select(value = "select * from user")
List selectAll();
// 删除
@Delete(value = "delete from user where id = #{id}")
void deleteUser(Integer id);
} 4.1.2 一对一查询
执行过程:
1)执行@Select标签的sql语句。
2)执行@Results标签的语句封装@Select的查询结果。
3)封装结果的时候有一个属性是user ,内部的one属性关联到了另外一个查询结果。所以就会去UserMapper中执行selectById 根据 column=uid 将 order 的uid作为参数去查询结果。
// 订单一对一查询
public interface OrdersMapper {
// select * from orders o left join user u on o.uid = u.id
@Results({
@Result(property = "id", column = "id"),
@Result(property = "ordertime", column = "ordertime"),
@Result(property = "total", column = "total"),
@Result(
javaType = User.class,
property = "user",
column = "uid",
one = @One(select = "com.zyj.mapper.UserMapper.selectById"))
})
@Select(value = "select * from orders")
List findAllOrderAndUser();
} // 用户查询
public interface UserMapper {
@Select(value = "select * from user where id = #{id}")
User selectById(Integer id);
}注解和标签对应关系总结:
| 注解 | 标签 |
|---|---|
| @Select | select |
| @Results | resultMap |
| @Result | id和 |
| @One | association |
4.1.3 一对多查询
执行过程:
1)执行@Select标签的sql语句。
2)执行@Results标签的语句封装@Select的查询结果。
3)封装结果的时候有一个属性是orderList ,内部的Many属性关联到了另外一个查询结果。所以就会去OrderMapper中执行selectByUId 根据 column=id 将 User 的id作为参数去查询结果。
// 用户查询一对多
public interface UserMapper {
// select * from user u left join orders o on u.id = o.uid;
@Results({
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "password", column = "password"),
@Result(property = "birthday", column = "birthday"),
@Result(
property = "orderList",
column = "id",
javaType = List.class,
many = @Many(select = "com.zyj.mapper.OrdersMapper.selectByUId")
)
})
@Select(value = "select * from user")
List findAllUserAndOrder();
} // 根据用户id查询用户订单
public interface OrdersMapper {
// 根据用户id返回查询结果
@Select(value = "select * from orders where uid = #{uid}")
List selectByUId(Integer uid);
} 注解和标签对应关系总结:
| 注解 | 标签 |
|---|---|
| @Select | |
| @Results | |
| @Result | |
| @Many |
4.1.4多对多查询
执行过程:
1)执行@Select标签的sql语句。
2)执行@Results标签的语句封装@Select的查询结果。
3)封装结果的时候有一个属性是roleList ,内部的Many属性关联到了另外一个查询结果。所以就会去RoleMapper中执行selectByUserId 根据 column=id 将 User 的id作为参数去查询结果。
public interface UserMapper {
// select * from user u left join sys_user_role ur on u.id = ur.userid left join sys_role r on ur.roleid = r.id;
@Results({
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "password", column = "password"),
@Result(property = "birthday", column = "birthday"),
@Result(
property = "roleList",
column = "id",
javaType = List.class,
many = @Many(select = "com.zyj.mapper.RoleMapper.selectByUserId")
)
})
@Select(value = "select * from user")
List findAllUserAndRole();
} // 根据用户id查询角色
public interface RoleMapper {
@Select(value = "select r.* from sys_role r inner join sys_user_role ur on r.id = ur.roleid where userid = #{uid}")
List selectByUserId(Integer uid);
} 注解和标签对应关系总结:
| 注解 | 标签 |
|---|---|
| @Select | select |
| @Results | resultMap |
| @Result | id和result |
| @Many | collection |
4.1.5 注解的动态SQL
MyBatis提供的动态Sql标签在注解模式中也是一样适用,但是写法和刚才的一对一、一对多、多对多的查询有所差异。作用和效果是一样的。所以这里只给出一个案例即可。
@Update({""})
void updateAuthorValues(Author author);如果想在注解的映射器接口中使用动态SQL,那么可以使用script元素。
4.2 缓存机制
Mybatis 使用到了两种缓存:本地缓存(local cache)和二级缓存(second level cache)。 两个缓存的关系如下图:

每当一个新 session 被创建,MyBatis 就会创建一个与之相关联的本地缓存。任何在 session 执行过的查询结果都会被保存在本地缓存中,所以,当再次执行参数相同的相同查询时,就不需要实际查询数据库了。本地缓存将会在做出修改、事务提交或回滚,以及关闭 session 时清空。
4.2.1 验证一级缓存
1)在同一个sqlSession中,对User用户表根据id进行2次查询,观察控制台的sql打印情况。
@Test
public void test1(){
// 获取一个sqlSession
SqlSession sqlSession = sessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用sqlSession执行第一次查询
User u1 = userMapper.selectUserByUserId(1);
System.out.println(u1);
// 使用sqlSession执行第二次查询
User u2 = userMapper.selectUserByUserId(1);
System.out.println(u2);
sqlSession.close();
}
2)在同一个sqlSession中,对User用户表根据id进行2次查询。但是,中间对查询到的用户执行Update更新操作,并提交事务,观察控制台的sql打印情况。
@Test
public void test2(){
// 获取一个sqlSession
SqlSession sqlSession = sessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用sqlSession执行第一次查询
User u1 = userMapper.selectUserByUserId( 1 );
System.out.println(u1);
// 第二次查询之前执行更新操作并提交事务
u1.setSex("女");
userMapper.updateUserByUserId(u1);
sqlSession.commit();
// 使用sqlSession执行第二次查询
User u2 = userMapper.selectUserByUserId(1);
System.out.println(u2);
sqlSession.close();
}
总结:
1)第一次查询用户的时候,会在一级缓存中去查询用户信息,如果查询不到就去数据库中查询。并将查询到的结果更新到以及缓存中。
2)如果同一个SqlSession中执行了commit事务提交操作(增加、更新、删除),那么就会清空SqlSession中的缓存信息,避免下次查询的时候出现脏数据。
3)第二次查询的时候同样去一级缓存查询,如果有值就获取返回,如果没有就查询数据库并添加到一级缓存中。
4.2.2 验证二级缓存
二级缓存和一级缓存原理类似,只不过缓存的级别更高而已。一级缓存针对sqlSession,但是二级缓存就针对Mapper文件。所以二级缓存可以被多个sqlSession共享。
二级缓存和一级缓存不一样,一级缓存默认都是开启的,二级缓存默认是关闭的。所以需要配置开启。二级缓存的开启需要配置2个地方。
总开关开启二级缓存SqlMapConfig.xml配置文件开启。
由于二级缓存是Mapper级别的缓存,所以可以针对单个Mapper配置是否需要开启。

基于上诉流程测试二级缓存
@Test
public` `void` `testTwoCache(){
// 获取sqlSession
SqlSession sqlSession1 = sessionFactory.openSession();
SqlSession sqlSession2 = sessionFactory.openSession();
SqlSession sqlSession3 = sessionFactory.openSession();
String statement = "com.zyj.UserMapper.selectById" ;
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper. class );
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper. class );
UserMapper userMapper3 = sqlSession2.getMapper(UserMapper. class );
// 第一次执行查询,结果会放入二级缓存中
User u1 = userMapper1.selectById( 1 );
System.out.println(u1);
sqlSession1.close(); // 关闭第一个session
// 执行更新操作,并提交
u1.setUsername("知春秋");
userMapper3.selectById(u1);
sqlSession3.commit();
// 第二次查询,由于更新操作导致二级缓存被更新,所以会重新查询数据库
User u2 = userMapper2.selectById( 1 );
System.out.println(u2);
sqlSession2.close();
}4.3 MyBatis学习思维导图(提供参考)

4.4 MyBatis源码剖析思维导图(提供参考)

关于“MyBatis的知识点有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
本文题目:MyBatis的知识点有哪些
文章路径:http://www.jxjierui.cn/article/pdssed.html


咨询
建站咨询
