MyBatis 核心组件分 4 部分
-
SqlSessionFactoryBuilder (构造器):可以根据配置或者代码来生成 SqlSessionFactory
作用在于创建 SqlSessionFactory,创建成功后就失去作用,所以不允许长期存在
-
SqlSessionFactory(工厂接口):生成 SqlSession。
作用是创建 SqlSession 接口对象,长期存在于 MyBatis 应用中,需要长期保存,直至不再使用 MyBatis 应用,其生命周期等同于 MyBatis 应用周期
-
SqlSession(会话):既可以发送 SQL 执行返回结果,也可以获取 Mapper 的接口。现在一般使用 MyBatis 提供的 SQL Mapper 接口编程技术,具有更高的可读性和可维护性。
相当于一个数据库连接,作用是处理业务请求,应该存活于一个业务请求中,一旦请求结束,就应该关闭该连接,否则可能会引起数据库资源耗尽
- SQL Mapper(映射器):由 Java 接口和 XML 文档组成,给出对应的 SQL 和映射规则,负责发送 SQL 去执行并返回结果
由 SqlSession 创建,生命周期小于等于 SqlSession
SqlSessionFactory 是 MyBatis 最基本的接口,它唯一的作用就是生产 MyBatis 的核心接口对象 —— SqlSession。也正因为它的作用的唯一,我们通常会使用单例模式生产它。
如何生产 SqlSessionFactory ?
SqlSessionFactory 是通过配置文件或者代码(强烈推荐使用配置文件)通过 SqlSessionFactoryBuilder 来生成,SqlSessionFactoryBuilder 提供了一个 org.apache.ibatis.session.Configuration
引导类,其内部采用建造者模式(Builder 模式)
MyBatis 中,配置文件通常分两种:基本配置文件和映射配置文件。
基本配置文件用来配置整个运行环境、上下文参数等。
映射配置文件用来配置SQL映射关系。
注意一点,之后的内容需要提前下载两个 jar 包:mybatis 和 mysql-connector-java,版本根据自己情况而定。
本文使用 mybatis-3.5.5. jar 、 mysql-connector-java-8.0.21.jar 、MySQL 版本为 8.0
-
创建
User.java
package com.ambrose.bean; public class User { private int id; private String name; private int age; private String address; private String gender; /* getter & setter & toString */ }
-
基本配置文件
mybatis-config.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> <!-- 别名 --> <typeAliases> <!-- 为指定类定义别名,之后在 MyBatis 上下文中可以使用别名代替全限定名 --> <typeAlias alias="user" type="com.ambrose.bean.User"/> </typeAliases> <!-- 数据库环境 --> <!-- default 指定默认环境 id --> <environments default="dev"> <!-- 可以配置多个环境 --> <environment id="dev"> <!-- 配置事务管理器(使用 MyBatis 内部 JDBC 管理器方式) --> <transactionManager type="JDBC"/> <!-- 配置数据库(POOLED 代表使用 MyBatis 内部提供的连接方式) --> <dataSource type="POOLED"> <!-- 这种驱动被新版本弃用 --> <!-- <property name="driver" value="com.mysql.jdbc.Driver"/> --> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <!-- testdata 是我的数据库名称 --> <property name="url" value="jdbc:mysql://localhost:3306/testdata?serverTimezone=GMT"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 引入映射器配置文件 --> <mappers> <mapper resource="com/ambrose/mapper/UserMapper.xml"/> </mappers> </configuration>
-
映射器配置
UserMapper.xml
和UserMapper.java
:映射器配置是 mybatis 中最重要的组件,它是由一个接口和一个 xml(推荐) 或者注解组成。
如果同时存在 xml 和 注解,xml 的优先级更高-
映射器接口
package com.ambrose.mapper; import com.ambrose.bean.User; public interface UserMapper { User getUser(int id); }
-
映射器 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.xml 的定义 --> <!-- 1、namespace 对应的是接口的全限定名 --> <!-- 2、xml 的文件名需要与接口类型一致 --> <!-- 3、映射节点的 id 需要与接口的方法名一致 --> <!-- 4、自动映射是通过 SQL 语句返回的列名与 POJO 对应的,如果不一样,可以通过对 SQL 列名进行别名转换 --> <mapper namespace="com.ambrose.mapper.UserMapper"> <select id="getUser" parameterType="int" resultType="user" > select id, name, gender, age, address from user where id = #{id} </select> </mapper>
-
注解方式实现映射器(相当于映射器接口 + 映射器 xml)
简单方便,但扩展性差,尤其 SQL 语句较复杂时,不建议使用
package com.ambrose.mapper; import com.ambrose.bean.User; @Select("select id, name, gender, age, address from user where id = #{id}") public interface UserMapper { User getUser(int id); }
-
-
构建 SqlSessionFactory
-
构建 SqlSession
-
SqlSession 发送 SQL
-
Mapper 发送接口
package com.ambrose.test; import com.ambrose.bean.User; import com.ambrose.mapper.UserMapper; 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 MyBatisTest { /** * 创建 SqlSessionFactory */ public SqlSessionFactory buildSqlSessionFactory() { SqlSessionFactory factory = null; String resource = "mybatis-config.xml"; InputStream is; try { // 获取配置文件 is = Resources.getResourceAsStream(resource); // 通过 SqlSessionFactoryBuilder 对象加载配置文件,创建 SqlSessionFactory 对象 factory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { e.printStackTrace(); } return factory; } /** * 创建 SqlSession */ public SqlSession buildSqlSession() { SqlSession sqlSession = null; // 获取 SqlSessionFactory 对象 SqlSessionFactory factory = buildSqlSessionFactory(); // 打开 SqlSession 会话 sqlSession = factory.openSession(); return sqlSession; } /** * SqlSession 事务控制 */ public boolean sqlSessionTransaction() { SqlSession sqlSession = buildSqlSession(); try { // TODO SQL 处理语句 // 提交事务 sqlSession.commit(); return true; } catch (Exception e) { // 回退事务 sqlSession.rollback(); return false; } finally { // 关闭资源 if (sqlSession != null) sqlSession.close(); } } /** * SqlSession 发送 SQL */ @Test public void sqlSessionExecute() { // 获取 SqlSession 对象 SqlSession sqlSession = buildSqlSession(); // 执行 SQL // selectOne 方法表示查询并返回一个对象 // 第一个参数是 命名空间 + SQL id,意为 UserMapper.xml 下 id 为 getUser 的 SQL 语句 // 第二个参数是 主键,即 id User user = (User)sqlSession.selectOne("com.ambrose.mapper.UserMapper.getUser", 1); System.out.println(user); } /** * Mapper 发送接口 * 优势: * 1. 提高可读性,体现业务逻辑 * 2. 编译时校验,如果使用 sqlSession.selectOne 时出现类型等异常,无法在编译时发现 */ @Test public void sqlMapperExecute(){ // 获取 SqlSession 对象 SqlSession sqlSession = buildSqlSession(); // 获取 Mapper 对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 执行 SQL User user = mapper.getUser(1); System.out.println(user); } }
-
运行结果