MyBatis教程
官方教程 https://mybatis.org/mybatis-3/zh/getting-started.html
1. 简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集(RestSet)。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
1.1 持久层
-
完成持久化工作的代码
-
数据持久化:将数据在持久状态与瞬时状态转化的过程。
使用MyBatis原因:简化JDBC代码,解除sql与程序代码的耦合提高可维护性,支持动态sql
2. 使用
2.1 配置文件
<!--核心配置文件-->
<configuration>
<environments default="development">
<!--可以创建多个数据库环境 用environment进行包裹 进行默认选择 此处默认选择development环境-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--mysql驱动-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--url连接数据库 通过右侧的database选项进行数据库连接-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
2.2 从XML中构建SqlSessionFactory获取 SqlSession
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
从建造者模式的builder创建出factory
获取sqlsessionfactory对象
try {
//获取配置文件
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//加载流构建工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
- 获取到SqlSessionFactory对象后,我们就可以从中获取 SqlSession 的实例。SqlSession完全包含了面向数据库执行SQL命令所需的所有方法,通过该实例就可以直接执行已映射的SQL语句。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
-
从数据库中获取想要的数据有两种方式:
-
**(推荐使用)**使用正确描述每个语句的参数和返回值的接口(比如 UserDao.class),不仅可以执行清晰和类型安全的代码,而且还不用进行强制类型转换。
UserDao mapper = sqlSession.getMapper(UserDao.class); List<User> userList = mapper.getUserList();
-
//需要进行强制类型转换 不推荐 List<User> userList = sqlSession.selectList("com.xyzhang.dao.UserDao.getUserList");
-
2.3 执行流程解析
MyBatis 提供的全部特性都可以利用基于 XML 的映射语言来实现,下文的例子可满足以上对SqlSession的调用
<?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.xyzhang.dao.UserDao">
<!--select查询语句-->
<select id="getUserList" resultType="com.xyzhang.pojo.User">
select * from mybatis.user
</select>
</mapper>
-
在命名空间“com.xyzhang.dao.UserDao”中定义了一个名为“getUserList”的映射语句,这种命名允许使用指定的完全限定名“com.xyzhang.dao.UserDao.getUserList”来调用映射语句。
List<User> userList = sqlSession.selectList("com.xyzhang.dao.UserDao.getUserList");
-
该命名也可以直接映射到在命名空间中同名的 Mapper 类,并将已映射的 select 语句中的名字、参数和返回类型匹配成方法。
UserDao mapper = sqlSession.getMapper(UserDao.class); List<User> userList = mapper.getUserList();
- 第二种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点; 其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择已映射的 SQL 语句。
- 第二种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点; 其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择已映射的 SQL 语句。
2.4 作用域和生命周期
SqlSessionFactoryBuilder:
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。
SqlSessionFactory:数据库连接池
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,不应丢弃它或重新创建。 因此 SqlSessionFactory 的最佳作用域是应用作用域(全局变量)。 最简单的实现方式是使用单例模式或者静态单例模式。
SqlSession:数据库连接池的一个请求
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。
每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。
并且应该把关闭操作放到 finally 块中以确保每次都能执行关闭。
映射器实例:(mapper)
映射器接口的实例是从 SqlSession 中获得的。因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。尽管如此,映射器实例的最佳作用域是方法作用域。 也就是说,映射器实例应该在调用它们的方法中被请求,用过之后即可丢弃。
最好把映射器放在方法作用域内:
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
// 你的应用逻辑代码
}
2.5 日后使用方式
只修改接口(UserMapper.java)和配置文件(resource文件下的UserMapper.xml)即可
3. XML映射文件及注解
3.0 注解:
-
简化开发,直接在接口上实现添加注解;
//查询全部用户 @Select("select id,name,pwd password from user") public List<User> getAllUser();
-
在核心配置文件上使用class绑定接口(不是配置文件),但可以与配置文件同时使用。
<!--使用class绑定接口--> <mappers> <mapper class="com.kuang.mapper.UserMapper"/> </mappers>
实现机制:反射
底层:动态代理
关于@Param() 注解:
- 在方法只接受一个参数的情况下,可以不使用@Param。
- 在方法接受多个参数的情况下,建议一定要使用@Param注解给参数命名。
- 如果参数是 对象类型, 则不能使用@Param。
- 不使用@Param注解时,参数只能有一个,并且是Javabean。
3.1 namespace
3.2 select:选择,查询语句
- id:对应namespace中的方法名;
- resultType:Sql语句执行的返回值;
- parameterType:参数类型
📌增删改需要提交事务sqlSession。commit();也可在getSqlsession()时设置为自动提交事务(设置参数为true即可 看源码!!!)
@Test
public void addUser() {
//通过实体类获取sqlSession实例
SqlSession sqlSession = MybatisUtils.getSqlSession();
//获取映射实例
UserMapper mapper