MyBatis笔记

MyBatis

视频链接:https://www.bilibili.com/video/BV1NE411Q7Nx

MyBatis官方文档:https://mybatis.org/mybatis-3/zh/index.html

学习时间:2022/03/23

1,Mybatis简介

image-20220326212833461

1.1、什么是MyBatis

 

  • MyBatis 是一款优秀的持久层框架

  • MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程

  • MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【PlainOld Java Objects,普通的 Java对象】映射成数据库中的记录。

  • MyBatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache 迁移到了google code,并且改名为MyBatis 。

  • 2013年11月迁移到Github .

  • Mybatis官方文档 : http://www.mybatis.org/mybatis-3/zh/index.html

  • GitHub : https://github.com/mybatis/mybatis-3

2, MyBatis第一个程序

思路流程:搭建环境-->导入Mybatis--->编写代码--->测试

 

结构:

image-20220326220128845

maven:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>org.example</groupId>
   <artifactId>MyBatis-01</artifactId>
   <version>1.0-SNAPSHOT</version>

   <properties>
       <maven.compiler.source>8</maven.compiler.source>
       <maven.compiler.target>8</maven.compiler.target>
   </properties>
   <dependencies>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.28</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/junit/junit -->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.13.2</version>
       </dependency>
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.5.9</version>
       </dependency>

       <!-- https://mvnrepository.com/artifact/log4j/log4j -->
       <dependency>
           <groupId>log4j</groupId>
           <artifactId>log4j</artifactId>
           <version>1.2.17</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>1.18.22</version>
           <scope>provided</scope>
       </dependency>
   </dependencies>
   <build>
       <resources>
           <resource>
               <directory>src/main/resources</directory>
               <includes>
                   <include>**/*.properties</include>
                   <include>**/*.xml</include>
               </includes>
               <filtering>true</filtering>
           </resource>
           <resource>
               <directory>src/main/java</directory>
               <includes>
                   <include>**/*.properties</include>
                   <include>**/*.xml</include>
               </includes>
               <filtering>true</filtering>
           </resource>
       </resources>
   </build>
</project>

 

mysql:

CREATE DATABASE `mybatis`; 
USE `mybatis`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
   `id` int(20) PRIMARY KEY NOT NULL,
    `name` varchar(30) DEFAULT NULL, `pwd` varchar(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`name`,`pwd`) values (1,'张三','123456'),(2,'李四','123456'),(3,'王二','123456');

 

resources:

 

mybatis-config.xml: MyBatis核心配件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <environments default="development">
       <environment id="development">
           <transactionManager type="JDBC"/>
           <dataSource type="POOLED">
               <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://47.99.49.255:9000/mybatis?useSSL=true&amp;characterEncoding=UTF-8&amp;useUnicode=true&amp;serverTimezone=GMT"/>
               <property name="username" value="root"/>
               <property name="password" value="root"/>
           </dataSource>
       </environment>
   </environments>
   <mappers>
       <mapper resource="top/hanbing777/dao/UserMapper/xml"/>
   </mappers>
</configuration>

 

 

dao层:

 

UserMapper:

package top.hanbing777.dao;

import top.hanbing777.pojo.User;

import java.util.List;

public interface UserMapper {
   List<User> getUserList();
}

UserMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.hanbing777.dao.UserMapper">
   <select id="getUserList" resultType="top.hanbing777.pojo.User">
      select * from mybatis.user
   </select>
</mapper>

 

pojo层:

 

User:

package top.hanbing777.pojo;

public class User {
   private int id;
   private String name;
   private String pwd;


   public int getId() {
       return id;
  }

   public void setId(int id) {
       this.id = id;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public String getPwd() {
       return pwd;
  }

   public void setPwd(String pwd) {
       this.pwd = pwd;
  }

   public User(int id, String name, String pwd) {
       this.id = id;
       this.name = name;
       this.pwd = pwd;
  }

   @Override
   public String toString() {
       return "User{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", pwd='" + pwd + '\'' +
               '}';
  }
}

 

 

utils层:

 

MybatisUtils:

MyBatis必须配置

package top.hanbing777.utils;

import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

//String resource = "org/mybatis/example/mybatis-config.xml";
//InputStream inputStream = Resources.getutSResourceAsStream(resource);
//SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inptream);
public class MybatisUtils {
   private  static SqlSessionFactory sqlSessionFactory;
   static {
       try {
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      } catch (IOException e) {
           e.printStackTrace();
      }
  }

   public static SqlSession getSqlSession(){
       SqlSession sqlSession = sqlSessionFactory.openSession();
       return sqlSession;
  }

}

 

test:

@Test
public void getUserList(){
   UserMapper mapper = sqlSession.getMapper(UserMapper.class);
   List<User> userList = mapper.getUserList();
   for (User user : userList) {
       System.out.println(user);
  }
   sqlSession.close();
}

3, 增删改查

注意:删改查的时候,需要提交事务

UserMapper:

    //添加用户
  int InsertUser(User user);

  //删除用户
  int deleteUser(int id);

  //修改用户
  int updateUser(User user);

//根据id查询用户
  User getUserById(int a);

UserMapper.xml:

    <select id="getUserById" resultType="User" parameterType="int">
      select * from user where id = #{id}
   </select>

   <delete id="deleteUser" parameterType="int" >
      delete from user where id = #{id}
   </delete>

   <update id="updateUser" parameterType="top.hanbing777.pojo.User">
      update user set name=#{name},pwd=#{pwd} where id = #{id}
   </update>

   <select id="getUserById" resultType="User" parameterType="int">
      select * from user where id = #{id}
   </select>

@Test

    @Test
   public void testInsert(){
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       int hahaha = mapper.InsertUser(new User(4, "hahaha", "233333"));
       if(hahaha>0){
           System.out.println("增加成功");
      }
       sqlSession.commit();
       sqlSession.close();
  }

   @Test
   public void testDelete(){
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       mapper.deleteUser(4);
       sqlSession.commit();
       sqlSession.close();
  }

   @Test
   public void testUpdate(){
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       mapper.updateUser(new User(4,"haha","233"));
       sqlSession.commit();
       sqlSession.close();
  }

   @Test
   public void testById(){

       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       User user = mapper.getUserById(1);
       System.out.println(user);
       sqlSession.close();
  }

 

4,万能的Map

  1. 在接口方法中,参数直接传递Map;

    User getUserById2(Map<String,Object> map);
  2. 编写sql语句的时候,需要传递参数类型,参数类型为map

        <select id="getUserById2" resultType="top.hanbing777.pojo.User" parameterType="map">
    select * from user where id = #{id} and name = #{name}
    </select>
  3. 在使用方法的时候,Map的 key 为 sql中取的值即可,没有顺序要求!

        @Test
       public void testById2(){
           UserMapper mapper = sqlSession.getMapper(UserMapper.class);
           Map<String , Object> map = new HashMap<>();
           map.put("id",1);
           map.put("name","张三");
           User user = mapper.getUserById2(map);
           System.out.println(user);
      }

总结:

如果参数过多,我们可以考虑直接使用Map实现,如果参数比较少,直接传递参数即可

5,Like模糊]查询

List<User> getUserLike(String value);
    <select id="getUserLike" resultType="top.hanbing777.pojo.User">
      SELECT * from user WHERE name like #{value}
   </select>
    @Test
   public void testLike(){
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       List<User> users = mapper.getUserLike("%李%");
       for (User user : users) {
           System.out.println(user);
      }
       sqlSession.close();
  }

注意:在java中添加通配符,在xml中添加会产生sql注入漏洞 举个例子:

    <select id="getUserLike" resultType="top.hanbing777.pojo.User">
      SELECT * from user WHERE name like "%"#{value}"%"
   </select>

这时候就会产生注入漏洞

 

6, 配置解析

6.1 核心配置文件

  • mybatis-confifig.xml 系统核心配置文件

  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。

  • 能配置的内容如下:

configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
<!-- 注意元素节点的顺序!顺序不对会报错 -->

6.2 environments元素

    <environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>

配合db.properties使用:

 <properties resource="db.properties"/>

db.properties文件:

driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://ip:3306/mybatis?useSSL=true&characterEncoding=UTF-8&useUnicode=true&serverTimezone=GMT
username=root
password=root

6.3 mappers元素

6.3.1

  1. 映射器 : 定义映射SQL语句文件

  2. 既然 MyBatis 的行为其他元素已经配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。 Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。映射器是MyBatis中最核心的组件之一,在MyBatis 3之前,只支持xml映射器,即:所有的SQL语句都必须在xml文件中配置。而从MyBatis 3开始,还支持接口映射器,这种映射器方式允许以Java代码的方式注解定义SQL语句,非常简洁。

6.3.2 引入资源方式

    <mappers>
<mapper resource="top/hanbing777/dao/UserMapper.xml"/>
<mapper class="top.hanbing777.dao.UserMapper"/>
<package name="top.hanbing777.dao"/>

<!--url这种我这里报错了-->
<mapper url="file:///top/hanbing777/UserMapper.xml.xml"/>
</mappers>

 

6.3.3 Mapper文件(Dao层中相当于接口的实现类)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.hanbing777.dao.UserMapper">


</mapper>
  • namespace中文意思:命名空间,作用如下:

    1. namespace和子元素的id联合保证唯一 , 区别不同的mapper

    2. 绑定DAO接口

      • namespace的命名必须跟某个接口同名

      • 接口中的方法与映射文件中sql语句id应该一一对应

    3. namespace命名规则 : 包名+类名

MyBatis 的真正强大在于它的映射语句,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 为聚焦于 SQL 而构建,以尽可能地为你减少麻烦。

6.3.4 typeAliases优化(给类起别名)

类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

    <typeAliases>
       <typeAlias type="top.hanbing777.pojo.User" alias="User"></typeAlias>
       <typeAlias type="top.hanbing777.pojo.Teacher" alias="Teacher"></typeAlias>
       <typeAlias type="top.hanbing777.pojo.Student" alias="Student"></typeAlias>
   </typeAliases>

当这样配置时, User 可以用在任何使用 com.kuang.pojo.User 的地方。

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

<typeAliases> 
   <package name="top.hanbing777.pojo"/>
</typeAliases>

若有注解,则别名为其注解值。见下面的例子:

(不好使,我测试没成功)

@Alias("User")
public class User {
   private int id;
   private String name;
   private String pwd;
}

7, ResultMap(结果映射)

当数据库字段名个实体类名不一致是,需要映射

eg: 实体类是pwd,而数据库字段为password,此时,需要把password映射为pwd

方法:ResultMap映射

UserMapper.xml:

    <select id="getUserList" resultMap="userResultMap">
select * from user
</select>

<resultMap id="userResultMap" type="User">
<result property="password" column="pwd"/>
</resultMap>

User实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String password;
}

数据库:

image-20220329084939172

结果:

image-20220329084959842

8, 注解开发

 

1,Mapper中的注解:

public interface UserMapper {
   //注解查询
   @Select("select * from user")
   List<User> getUsersZhujie();

   @Select("select * from user where id = #{id1}")
   User getUserById3(@Param("id1") int id);

   @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
   int InsertUser2(Map map);

   @Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
   int UptateUser2(User user);

   @Delete("delete from user where id = #{id}")
   int DeleteUser2(@Param("id") int a);
}

直接把注解写到UserMapper的接口中即可

其中@Param("id") int a,是把参数名改成id

 

2,lombok

@Data @AllArgsConstructor @NoArgsConstructor

加上这三条注解,实体类相当于有了get,set,有参构造,无参构造,toString

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
   private int id;
   private String name;
   private String password;
}

9, 多对一与一对多:

1, 多对一:

image-20220329090702936

image-20220329090721297

如图,当student的tid和teacher的id字段相关联:

查询多个学生时会指向一个老师

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor

public class Teacher {
   private int id;
   private String name;
   private List<Student> students;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

   private int id;
   private String name;
   private Teacher teacher;

}

Mapper.xml:

<!--多对一方法1:-->
   <select id="getStudents1" resultMap="getStudents1">
      select * from student
   </select>
   <resultMap id="getStudents1" type="Student">
       <collection property="teacher" column="tid" javaType="teacher" select="getTeacher"/>
   </resultMap>
   <select id="getTeacher" resultType="Teacher">
      select * from teacher where id =#{id}
   </select>

<!--多对一方法2:-->

   <select id="getStudents2" resultMap="getStudents2">
      select s.name sname,s.id sid, t.name tname,t.id tid from student s,teacher t where s.tid = t.id
   </select>
   <resultMap id="getStudents2" type="Student">
       <result property="id" column="sid"/>
       <result property="name" column="sname"/>
       <association property="teacher" javaType="teacher">
           <result property="name" column="tname"/>
           <result property="id" column="tid"/>
       </association>
   </resultMap>

测试类:

public class UserDaoTest {
Logger logger = Logger.getLogger(UserDaoTest.class);
SqlSession sqlSession = MybatisUtils.getSqlSession();

//多对一
@Test
public void testGetStudent1(){
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudents1();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}


@Test
public void testGetStudent2(){
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudents2();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
}

结果:

image-20220329200524356

2, 一对多:

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
   public int id;
   private String name;
   private List<Student> students;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
   private int id;
   public String name;
   public int tid;
}

Mapper.xml:

<!--    连表查询-->
   <resultMap id="getTeacherMap1" type="Teacher">
       <result property="name" column="tname"/>
       <result property="tid" column="id"/>
       <collection property="students" ofType="Student" >
           <result property="id" column="sid"/>
           <result property="name" column="sname"/>
           <result property="tid" column="tid"/>
       </collection>
   </resultMap>

   
<!--   嵌套查询-->
   <select id="getTeacher2" resultMap="getTeacherMap2">
      select * from teacher where id=#{id}
   </select>

   <resultMap id="getTeacherMap2" type="Teacher">
       <collection property="students" column="id" ofType="Student" javaType="ArrayList"
                   select="getSTid"/>
   </resultMap>

   <select id="getSTid" resultType="Student">
      select * from student where tid = #{id}
   </select>

测试类:

    @Test
public void testGetTeacher1(){
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher1(1);
System.out.println(teacher);
sqlSession.close();
}

@Test
public void testGetTeacher2(){
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher);
sqlSession.close();
}

结果:

image-20220329200137198

10, 动态SQL(if,where,set,choose,foreach)

注意:当sql表的字段名和实体类不一样时:需要在mybatis-config.xml中开启驼峰转换

    <settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

 

1, 建立一个新表

1,建表

CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量' )
ENGINE=InnoDB DEFAULT CHARSET=utf8

2, UUID类

import java.util.UUID;

public class getUUID {
public static String getID(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}

2, addBlog(插入数据)

public class addBlog {
   @Test
   public void addInitBlog(){
       SqlSession session = MybatisUtils.getSqlSession();
       BlogMapper mapper = session.getMapper(BlogMapper.class);
       Blog blog = new Blog();
       blog.setId(getUUID.getID());
       blog.setTitle("Mybatis如此简单");
       blog.setAuthor("狂神说");
       blog.setCreateTime(new Date());
       blog.setViews(9999);
       mapper.addBlog(blog);
       blog.setId(blog.getId());
       blog.setTitle("Java如此简单");
       mapper.addBlog(blog);
       blog.setId(blog.getId());
       blog.setTitle("Spring如此简单"); mapper.addBlog(blog);
       blog.setId(blog.getId());
       blog.setTitle("微服务如此简单");
       mapper.addBlog(blog);
       session.commit();
       session.close();

  }

}

3, 结果

image-20220329201404121

2, blog实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {

   private String id;
   public String title;
   public String author;
   public Date createTime;
   public int views;
}

3, Mapper

public interface BlogMapper {
int addBlog(Blog blog);
List<Blog> queryBlogif(Map map);
int updateBlog(Map map);
List<Blog>queryBlogChoose(Map map);
List<Blog> queryBlogForeach(Map map);
}

4, Mapper.xml(包含sql片段)

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.hanbing777.dao.BlogMapper">

   <insert id="addBlog" parameterType="Blog">
      insert into blog values (#{id},#{title},#{author},#{createTime},#{views})
   </insert>
   
   <!--sql片段,可将重复性的代码写到这里-->
   <sql id="testSQL">
       <if test="title!=null">
          title = #{title}
       </if>
       <if test="author != null">
          and author = #{author}
       </if>
   </sql>
   
<!--   if&where-->
   <select id="queryBlogif" parameterType="map" resultType="Blog">
      select * from blog
       <where>
           <!--调用sql片段-->
           <include refid="testSQL"></include>
       </where>
   </select>
   
<!--   set-->
   <update id="updateBlog" parameterType="map">
      update blog
       <set>
           <if test="title!=null">
              title = #{title},
           </if>
           <if test="author != null">
                author = #{author},
           </if>
       </set>
          where id = #{id}
   </update>
   

<!-- choose-->
   <select id="queryBlogChoose" parameterType="map" resultType="Blog">
      select * from blog
       <where>
           <choose>
               <when test="title!=null">
                  title = #{title}
               </when>
               <when test="author">
                  author = #{author}
               </when>
               <when test="views">
                  views= #{views}
               </when>
           </choose>
       </where>
   </select>


<select id="queryBlogForeach" parameterType="map" resultType="blog">
  select * from blog
   <where>
       <foreach collection="ids" item="id" open="(" separator="or" close=")">
          id = #{id}
       </foreach>
   </where>
</select>
</mapper>

5, 改一下blog

image-20220329202056314

6, @Test

//if
   @Test
   public void queryBlogif(){
       BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
       Map<String, Object> map = new HashMap<>();
       //map.put("title","Mybatis如此简单");
       map.put("author","狂神说1");
       List<Blog> blogs = mapper.queryBlogif(map);
       for (Blog blog : blogs) {
           System.out.println(blog);
      }
       sqlSession.close();
  }

   //set
   @Test
   public void testSet(){
       BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
       Map<String, Object> map = new HashMap<>();
       map.put("id","936bba9fd75c4daeaa9efce83fa14313");
       //map.put("title","Mybatis如此简单");
       map.put("author","狂神说1");
       mapper.updateBlog(map);
       sqlSession.commit();
       sqlSession.close();
  }

   @Test
   //choose
   public void testChoose(){
       BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
       Map<String, Object> map = new HashMap<>();
       map.put("title","Java如此简单");
       //map.put("author","狂神说1");
       //map.put("views",1000);
       List<Blog> blogs = mapper.queryBlogChoose(map);
       for (Blog blog : blogs) {
           System.out.println(blog);
      }
  }


   @Test
   public void testForeach(){
       BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
       HashMap<String,ArrayList> hashMap = new HashMap();
       ArrayList<Integer> integers = new ArrayList<>();
       integers.add(1);
       integers.add(2);
       integers.add(3);
       integers.add(4);
       hashMap.put("ids",integers);
       List<Blog> blogs = mapper.queryBlogForeach(hashMap);
       for (Blog blog : blogs) {
           System.out.println(blog);
      }
       sqlSession.commit();
  }

11, 缓存(了解即可,境界达不到)

  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。

  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存

    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)

    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。

    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

1, 一级缓存(SqlSession级别的缓存)

1, 测试

1, Mapper.xml
    <select id="getUser" resultType="top.hanbing777.pojo.User">
      select * from user
   </select>
2, @Test
    @Test
   public void testUser(){
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       List<User> users1 = mapper.getUser();
       List<User> users2 = mapper.getUser();
       for (User user : users1) {
           System.out.println(user);
      }
       System.out.println("==============================");
       for (User user : users2) {
           System.out.println(user);
      }
       System.out.println("==============================");

       System.out.println(users1==users2);

       sqlSession.close();
  }
3, 结果

image-20220329203848560

2,一级缓存失效的四种情况

  1. sqlSession不同

  2. 一级缓存失效情况:没有使用到当前的一级缓存,效果就是,还需要再向数据库中发起一次查询请求!

  3. sqlSession相同,两次查询之间执行了增删改操作!

  4. sqlSession相同,手动清除一级缓存(sqlSession.clearCache();)

加上sqlSession.clearCache();后

    @Test
   public void testUser(){
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       List<User> users1 = mapper.getUser();
       sqlSession.clearCache();
       List<User> users2 = mapper.getUser();
       for (User user : users1) {
           System.out.println(user);
      }
       System.out.println("==============================");
       for (User user : users2) {
           System.out.println(user);
      }
       System.out.println("==============================");

       System.out.println(users1==users2);

       sqlSession.close();
  }

结果:

image-20220329204351502

2, 二级缓存

  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存

  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;

  • 工作机制

    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;

    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;

    • 新的会话查询信息,就可以从二级缓存中获取内容;

    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

1, 使用步骤

  1. 在mybatis-confifig.xml中开启全局缓存

    <setting name="cacheEnabled" value="true"/>

3, EhCache

第三方缓存实现

posted @   Null777  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示