声明:本博客记录的是MyBatis的学习笔记,学习资源来自于MyBatis官网,以及B站up主狂神,以及有很多自己的见解,我的理解可能有错误希望可以指正。
1. 什么是MyBatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
上面这段话是来自于MyBatis官网的对MyBatis的介绍,大家轻微的看看就行,然后后续慢慢理解这段话。
2. 安装MyBatis
如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version> 这了是你想使用的版本
</dependency>
如果是其他方式,那就去下载jar包,然后导包就可以了
3. 首次尝试
3.1 数据库准备
在MySql上创建一个数据库,同时创建一个表,自己写自己能想到的,顺便联系一下sql语句,下面是我的表结构
3.2 创建一个Maven项目
这个我有一篇博客写了,大家也可以根据自己的idea版本上网查找相应的创建方式
3.3 导入依赖
这一步所在的目录:
必须导入的两个依赖:数据库驱动依赖、MyBatis依赖
<!--MySql驱动,或者你使用的数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!--MyBatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
可选择的依赖:lombok 和 junit(junit最好也选择)
下面是我的依赖配置,可以直接复制
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
3.4 编写核心配置文件
这一步所在的目录
在src/main/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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--这个mappers可以暂时不管-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
核心配置文件标签解读
<configuration>
:配置,这里面全是配置内容
<environments>
:环境,复数,里面可以有一个及一个以上的环境配置 ,default
是默认使用哪个环境
<environment>
:环境的具体内容 id
是环境的标识(我是这样理解的)
<transactionManager>
:事务管理,上面使用的是jdbc的事务管理
<dataSource>
:数据源,这个和数据库连接是一个意思,后面的跟的四个参数也是一样的
根据上述模板来编写我的核心配置文件
<?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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shea_school?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
3.5编写MyBatis工具类
这一步所在的目录
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
上面这段话是官网的入门《从 XML 中构建 SqlSessionFactory》的第一段话,来仔细缕一缕这句话:
1.要使用MyBatis需要一个SqlSessionFactory实例
2.这个实例可以通过SqlSessionFactoryBuilder获得
3.SqlSessionFactoryBuilder可以从XML配置文件中构建一个SqlSessionFactory
那我们反过来一下:首先我们写好了一个XML文件,这是没有问题的。然后SqlSessionFactoryBuilder可以通过我们编写的XML配置文件,来构建SqlSessionFactory
那我们使用编程语句来翻译这句话就是
//这是我们预先编写好的XML配置文件,并把它转换成输入流
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//这里是SqlSessionFactoryBuilder使用XML来构建(build)sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
去掉注解就是官网给我们的三句话,这三句话是固定的,我们可以将这个写成一个工具类
工具类的编写代码
package com.shea.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
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(){
return sqlSessionFactory.openSession();
}
}
注意: 不要抄这段代码!自己去写,问问自己为什么这样写?如果不知道那你就要补习一下java基础咯,static的特性还记得吗?
3.6 编写POJO实体类
本步骤所在目录
实体类,这个也是java的一个基础概念,打个比方,这个实体类是一个学生,那这个类里面要包含学生的属性,里面提供getter和setter方法。这里我们编写实体类,类中的属性就要和上述创建的数据表属性一一对应,编写的代码如下
package com.shea.pojo;
import lombok.*;
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
private int score;
private int age;
private int gender;
}
如果你没有安装Lombok那,去掉注解,加上getter、setter、构造、tostring这些方法,belike.(这里其实有点废话了)
package com.shea.pojo;
public class Student {
private int id;
private String name;
private int score;
private int age;
private int gender;
public Student(){}
public Student(int id, String name, int score, int age, int gender) {
this.id = id;
this.name = name;
this.score = score;
this.age = age;
this.gender = gender;
}
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 int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", score=" + score +
", age=" + age +
", gender=" + gender +
'}';
}
}
3.7 编写Mapper接口
所在的操作目录
初次尝试,我们就将学生的全部信息打印出来就可以了,编写如下
package com.shea.mapper;
import com.shea.pojo.Student;
import java.util.List;
public interface StudentMapper {
List<Student> getStudent();
}
3.8 SQL语句映射
这里暂时只写使用mapper.xml
我们在官网中可以看到一个mapper.xml
的模板
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
先解释一下标签内容
mapper
就是映射咯,变量namespace
就是你要相应绑定的接口,或者类,这里我们绑定我们的Mapper接口,这个是很重要的!
select
这个标签就是选择标签,这个标签可以选择的有insert
delete
等,可以自己去编译器里查看id
对应我们前面写的方法名,resultType
就是返回类型,sql语句执行的返回值。这里我们返回Student,但是xml文件不能直接找到这个类型,就把这个实体类写上去。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shea.mapper.StudentMapper">
<select id="getStudent" resultType="com.shea.pojo.Student">
select * from student
</select>
</mapper>
写完以后记得在核心配置文件mybatis-config.xml
中添加
src是和路径相关的,不同的地方路径不一样,放相对路径
我的目录结构:
<mappers>
<mapper resource="student-mapper.xml"/>
</mappers>
进行注册,不然会报错:org.apache.ibatis.binding.BindingException: Type interface com.shea.mapper.StudentMapper is not known to the MapperRegistry.
<?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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shea_school?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="student-mapper.xml"/>
</mappers>
</configuration>
3.9 测试
在这里编写测试文件
package com.shea.mapper;
import com.shea.pojo.Student;
import com.shea.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class StudentMapperTest {
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.getStudent();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
}
然后点击运行就通过了
3.10 可能出现的其他错误
初始化异常错误
在pom.xml中加入
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<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>
还有可能出现其他错误,大家这个时候就要先解决自己理解的异常,再使用搜索引擎搜索。
完成以后,初次体验也结束了,可能你会觉得很麻烦,但也就开头难一点,后面写代码就会非常轻松咯!
4.CRUD增删改查
4.1 有条件查询
这里我们做一个小例子就是:按id查询
- 接口添加方法
直接在StudentMapper接口里添加一个按id查找的方法返回值是student
添加的代码
Student findStudentByID(int id);
- mapper文件添加语句
然后在student-mapper.xml中添加查询语句
<select id="findStudentByID" parameterType="int" resultType="com.shea.pojo.Student">
SELECT * from student WHERE id = #{id}
</select>
id
和resultType
在上面的时候讲过了 。
parameterType
:这个例子中是按照id来查找,id的是int
类型的数组,我们需要把这个值传入,这个标签就是传入值的类型,也是传参的。
- 编写测试用例
@Test
public void testFindStudentByID(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.findStudentByID(1);
System.out.println(student);
sqlSession.close();
}
4.2插入数据
和上面一样
- 添加接口方法
void insertStudent(Student student);
- 编写mapper
<insert id="insertStudent" parameterType="com.shea.pojo.Student">
INSERT INTO student(id,name,score,age,gender) VALUES (#{id},#{name},#{score},#{age},#{gender})
</insert>
- 编测试文件
@Test
public void testInsertStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
studentMapper.insertStudent(new Student(3,"naoao",100,18,1));
//事务提交
sqlSession.commit();
sqlSession.close();
}
**注意:**这里和查询不一样,是需要提交事务的,可以运行,当然很显然,这里的student的id可以不写但是需要改变代码,大家自己思考自己动手写一下
4.3 修改
这个案例我在实体类中多写了一个构造方法,这样我就不用写那么多其他东西了
//实体类中多加的构造方法
public Student(int id, int score) {
this.id = id;
this.score = score;
}
- 接口添加方法
void updateStudent(Student student);
- 在mapper中编写sql
<update id="updateStudent" parameterType="com.shea.pojo.Student">
UPDATE student SET score = #{score} WHERE id = #{id}
</update>
- 编写测试文件
@Test
public void testUpdateStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
studentMapper.updateStudent(new Student(3,80));
sqlSession.commit();
sqlSession.close();
}
4.4 删除
如果你是看这个教程学习的同学,可以先留十分钟给自己写一下这个案例,使用id删除一个学生
- 添加一个接口方法
void deleteStudent(int id);
- 在mapper中添加sql
<delete id="deleteStudent" parameterType="int">
DELETE FROM student WHERE id = #{id};
</delete>
- 编写测试文件
@Test
public void testDeleteStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
studentMapper.deleteStudent(3);
sqlSession.commit();
sqlSession.close();
}
4.5 总结
当我们第一次使用mybatis的时候配置十分的繁琐,但是等你配置完再去修改代码,那你基本上需要认真写的就只有sql语句了,这个代码量很少,而且很快,比JDBC更便捷。
万事开头难结束了就是比较轻松的
5.XML配置configuration
这一部分我们将回到config-mybatis.xml
中重新认识这些属性,这个大家必须去看官方文档,这里只列举一些比较常用的几个配置
<?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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shea_school?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="student-mapper.xml"/>
</mappers>
</configuration>
5.1 propreties 属性配置
我们回看原来的配置文件
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shea_school?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
我们都是把内容直接写在<property>
标签中,但是有另外两种方法,另外两种其中有一种是比较常用的
- 第一种:引入外部配置文件
个人认为这种方法是最灵活的
新建一个config.properties
最好是和核心配置文件在同一个文件目录下,但是你也可以瞎选,但是后面出错也是你的事情。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/shea_school?useSSL=false&;useUnicode=true&;characterEncoding=UTF-8&;serverTimezone=GMT
username=root
password=123456
然后修改核心配置文件
<?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>
<properties resource="config.properties"/>
<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>
<mappers>
<mapper resource="student-mapper.xml"/>
</mappers>
</configuration>
上面我们修改的地方有:
加入了
<properties resource="config.properties"/>
修改了
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
在<property>
标签中的value是和外部中的名字一样,你是可以修改这个名字的,所以说非常的灵活,你可以在配置文件写很多。然后用你想用的。
2. 第二种:半引入
那就是你编写了properties
文件,但是可以在xml
文件中再写,模板如下
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
注意: 如果你同时写了配置文件和标签,优先使用配置文件的,如果配置文件错了,也是同样会报错的
5.2 typeAliases类型别名
我们在写拥有sql语句那个文件的时候,parameterType
总是要写全名,那有什么方法可以只写一个Student呢?
<insert id="insertStudent" parameterType="com.shea.pojo.Student">
INSERT INTO student(id,name,score,age,gender) VALUES (#{id},#{name},#{score},#{age},#{gender})
</insert>
前两个方法都是写入核心配置文件config-mybatis.xml
中
- 方法一:
我们给每一个类都取一个名字
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
alias
就是别名,而type
是你要取名的类,这个方法适合实体类比较少的时候,太多了一个一个取名也挺累的
2. 方法二:
这个就是适合实体类比较多,而且都放在一个包下
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
使用这个方法的时候,代替的名字就写实体类的类名,或者使用小写写就可以了。
使用这个方法还可以使用注解取别名,代码结构如下
@Alias("author")
public class Author {
...
}
在使用这个标签的时候要注意标签的位置,不然无法识别,如果出错的话就会报错,其他的标签也是一样的,截一小段报错
5.3 mapper映射器
现在我们使用的mapper映射器是这种形式的
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
这种方法是比较推荐也比较常用的
接下来这种不用,但是你知道就好
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
剩下两种我觉得灵活性不行
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
这两个种的mapper文件必须和Mapper接口在同一个包下,并且要名字相同。
6.作用域(Scope)和生命周期
这个主要是讲sqlSessionFactoryBuilder
、sqlSessionFactory
和sqlSession
三者的作用域和生命周期,先看这三者的关系(接下来的比喻可能都不恰当,但是是我的理解,有错误希望可以指出)
6.1 sqlSessionFactoryBuilder:
sqlSessionFactoryBuilder的作用就是通过xml文件来建造一个sqlSessionFactory。
我们可以想象成它是一个工厂的施工队(乙方)
另外一个是工厂的老板(甲方)
xml文件是甲方提供给乙方的建造图纸
回想一下平时的建筑工业:乙方建造好,拿到钱就可以走了。不需要在留在这个地方,它还可以接别的建造单。
所以再读官方文档给的话(如下)
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。
以保证所有的 XML 解析资源可以被释放给更重要的事情。 对于这句话的理解就是,xml文件种不仅仅只有工厂的建造图纸,还有产品的生产指南mapper.xml,存放sql的地方
6.2 sqlSessionFactory
生活种的工厂都是建造完就一直生产产品的,应该没有哪个老板那么大气,建造好一个工厂生产了一个产品以后就把它拆掉,然后再建立一个。
所以官方文档对这个的解释也是比较好理解的
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
6.3 sqlSession
我对这个的理解就是:它是工厂里的生产线,对照的生产图纸就是<mappers>
标签里的内容。
一个生产线可以生产一种产品,如果多条生产线混合生产,那就会造成混乱。
如果这个生产线结束了,那就应该把里面的机器等都关闭,不然电费和人力费可能会让老板亏损。
所以相对于工厂的稳定存在,生产线是不一定稳定存在的
官网原话如下:
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。
6.4 总结
作用域 | 生命周期 | |
---|---|---|
sqlSessionFactoryBuilder | 方法作用域(局部) | 生产完sqlSessionFactory就结束 |
sqlSessionFactory | 应用作用域 | 运用期间一直在运行 |
sqlSession | 请求或方法作用域 | 使用结束后需要关闭 |