网站建设资讯

NEWS

网站建设资讯

MyBatis的知识点有哪些

这篇文章将为大家详细讲解有关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=uidorderuid作为参数去查询结果。

// 订单一对一查询
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);
}

注解和标签对应关系总结:

注解标签
@Selectselect
@ResultsresultMap
@Resultid和
@Oneassociation
4.1.3 一对多查询

执行过程:

1)执行@Select标签的sql语句。

2)执行@Results标签的语句封装@Select的查询结果。

3)封装结果的时候有一个属性是orderList ,内部的Many属性关联到了另外一个查询结果。所以就会去OrderMapper中执行selectByUId 根据 column=idUserid作为参数去查询结果。

// 用户查询一对多
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=idUserid作为参数去查询结果。

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);
}

注解和标签对应关系总结:

注解标签
@Selectselect
@ResultsresultMap
@Resultid和result
@Manycollection
4.1.5 注解的动态SQL

MyBatis提供的动态Sql标签在注解模式中也是一样适用,但是写法和刚才的一对一一对多多对多的查询有所差异。作用和效果是一样的。所以这里只给出一个案例即可。

    @Update({""})
    void updateAuthorValues(Author author);

如果想在注解的映射器接口中使用动态SQL,那么可以使用script元素。

4.2 缓存机制
	Mybatis 使用到了两种缓存:本地缓存(local cache)和二级缓存(second level cache)。 两个缓存的关系如下图:

MyBatis的知识点有哪些

每当一个新 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();
}

MyBatis的知识点有哪些

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();
}

MyBatis的知识点有哪些

总结:

1)第一次查询用户的时候,会在一级缓存中去查询用户信息,如果查询不到就去数据库中查询。并将查询到的结果更新到以及缓存中。

2)如果同一个SqlSession中执行了commit事务提交操作(增加、更新、删除),那么就会清空SqlSession中的缓存信息,避免下次查询的时候出现脏数据。

3)第二次查询的时候同样去一级缓存查询,如果有值就获取返回,如果没有就查询数据库并添加到一级缓存中。

4.2.2 验证二级缓存

二级缓存和一级缓存原理类似,只不过缓存的级别更高而已。一级缓存针对sqlSession,但是二级缓存就针对Mapper文件。所以二级缓存可以被多个sqlSession共享。

二级缓存和一级缓存不一样,一级缓存默认都是开启的,二级缓存默认是关闭的。所以需要配置开启。二级缓存的开启需要配置2个地方。

  • 总开关开启二级缓存SqlMapConfig.xml配置文件开启。



    
  • 由于二级缓存是Mapper级别的缓存,所以可以针对单个Mapper配置是否需要开启。


MyBatis的知识点有哪些

基于上诉流程测试二级缓存

@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学习思维导图(提供参考)

MyBatis的知识点有哪些

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

MyBatis的知识点有哪些

关于“MyBatis的知识点有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


名称栏目:MyBatis的知识点有哪些
网站链接:http://cdweb.net/article/pdssed.html