MyBatis入门
开发步骤
使用 Maven 进行项目管理。
第一步:打包方式jar
第二步:引入依赖
<!--mybatis核⼼依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>第三步:编写 mybatis 核心配置文件——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>
<!-- mybatis-config.xml -->
<environments default="development">
<!-- 配置数据库环境,一个environment对应一个DB -->
<environment id="development">
<!--指定事务管理器-->
<transactionManager type="JDBC"/>
<!--指定数据源类型-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/powernode"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
...
</environments>
</configuration>注意:
- 文件名不是必须叫做mybatis-config.xml,只是大家都采用这个名字。
- 文件存放的位置也不是固定的,一般情况下,会放到类的根路径下。
见 04-配置文件详解.核心配置文件
第四步:编写 SQL映射文件——XxxMapper.xml。
SQL 映射文件
<?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">
<!-- CarMapper.xml -->
<mapper namespace="car">
<!--resultType:将查询结果集的记录进行封装的类型,体现ORM思想-->
<!--原理:根据查询结果集的字段名,在pojo中进行setter方法的匹配,从而进行封装-->
<select id=".." resultType="pojo全限定类名">
select id,car_num as carNum,brand,
guide_price as guidePrice,
produce_time as produceTime,
car_type as carType
from t_car;
</select>
</mapper>见 04-配置文件详解.SQL映射文件
第五步:将 SQL 映射文件 在 核心配置文件 中引入。
<!-- mybatis-config.xml -->
...
<mappers>
<mapper resource="XxxMapper.xml"/>
</mappers>见 04-配置文件详解.核心配置文件.引入SQL映射文件
第六步:编写MyBatis程序。
使用mybatis的类库,编写mybatis程序,连接数据库,做增删改查就行了。
// 1. 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2. 创建SqlSessionFactory对象
// 从类的根路径下查找mybatis核心配置文件
InputStream is =
Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 3. 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4. 执⾏sql
int count = sqlSession.insert("insertCar"); // 这个"insertCar"必须是sql的id
// 5. 提交(mybatis默认采⽤的事务管理器是JDBC,默认是不提交的,需要⼿动提交。)
sqlSession.commit();
// 6. 关闭资源(只关闭是不会提交的)
sqlSession.close();MyBatis 执行 SQL
mybatis的核心对象包括:
- SqlSessionFactoryBuilder
- SqlSessionFactory
- SqlSession
获取顺序:SqlSessionFactoryBuilder --> SqlSessionFactory --> SqlSession
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); // 使用无参构造获取 builder 建造者对象
SqlSessionFactory factory = builder.build(...); // 获取工厂对象
SqlSession session = factory.openSession(...); // 通过工厂对象生成 session 对象
// 一个 session 负责一次会话,底层使用一个 connection 对象进行 CRUDbuilder 的使用
使用 builder 解析核心配置文件中的 <environment> ,获得连接数据库的有关信息。
builder 解析一个 <environment> 建造出一个 factory,一个 <environment> 对应一个DB。
(BD -- <environment> --builder-- factory)
/*
<!-- mybatis-config.xml -->
<environments default="DEFAOUT_ID">
<environment id="...">
...
</environment>
...
</environments>
*/
// 1. 使用流读取 mybatis-config.xml
// 使用 org.apache.ibatis.io.Resources 工具类,从类路径下查找
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 底层实现:ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
// 使用文件流
// InputStream is = new FileInputStream("d:\\mybatis-config.xml");
// 2. 传入流给 builder 进行解析,建造出 factory 对象
factory = builder.build(is); // 使用默认 default 所指定的 environment(DEFAOUT_ID)
factory = builder.build(is,id); // 使用 id 所指定的 environment- builder 用来解析核心配置文件(位置不要紧,只要能用流读取到就行),建造 factoty。builder可以重复使用。
- 一个 factory 对应一个
<environment>,对应一个 DB。
factory 的使用
public interface SqlSessionFactory {
// JDBC事务管理器下,默认关闭自动提交
SqlSession openSession();
// 指定是否自动提交
SqlSession openSession(boolean autoCommit);
...
}
// 采用默认的提交配置,获取会话 sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();session 的使用
SqlSession是专门用来执行SQL语句的,是一个Java程序和数据库之间的一次会话。
使用 session 对象调用方法进行sql的执行,同时支持封装pojo返回,看具体的调用说明方法。
方法见名之意,一般都有如下方法参数:
String statement:引入 SQL 映射文件中 sql 的区分标志,包括:
id:sql 的 id,不同命名空间(SQL映射文件)中可能会相同,单个SQL映射文件的唯一。namespace.id:带命名空间前缀,严格的唯一。
Object parameter:sql 占位符传值对象
- 占位符
#{key} ${key}:parameter 是 map,调用 get 方法获取实际值 - 占位符
#{属性值} ${属性值}:parameter 是 pojo,匹配 getter 方法获取实际值 - 当sql中占位符只有一个时,
{}内可以随便写,且可以指定值传参。
// 使用 session 进行事务管理
sqlSession.commit();
sqlSession.rollback();
sqlSession.close(); // 关闭会话,释放资源
// 不建议自动提交,因为这样不支持事务了(没有开启事务)
SqlSession sqlSession = factory.openSession(true);作用域(Scope)和生命周期
SqlSessionFactoryBuilder:可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
- 最佳作用域是方法作用域(也就是局部方法变量)。
- 可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它。
SqlSessionFactory:一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
- 避免多次重建。最佳作用域是应用作用域,最简单的就是使用单例模式或者静态单例模式(工具类封装)。
SqlSession:每个线程都应该有它自己的 SqlSession 实例。
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。
关闭操作是很重要的,应确保每次都能执行关闭操作。
try (SqlSession session = sqlSessionFactory.openSession()) {
// 你的应用逻辑代码
}集成三方日志框架
引⼊⽇志框架的⽬的是为了看清楚mybatis执⾏的具体sql。
常见的日志组件
- SLF4J(沙拉风):沙拉风是一个日志标准,其中有一个框架叫做logback,它实现了沙拉风规范。
- LOG4J
- LOG4J2
- STDOUT_LOGGING:标准日志
- ....
- log4j log4j2 logback都是同一个作者开发的。
MyBatis 集成日志框架
mybatis 已经实现了 STDOUT_LOGGING 这种标准日志。可直接在核心配置文件中开启,无需引入依赖:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>标准日志在有些情况下的信息不够充分,可以选择其他的更为丰富的日志组件,如 logback:
<!--引入logback依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<!--在核心配置文件中开启-->
<settings>
<setting name="logImpl" value="SLF4J"/>
</settings>- 不在核心配置文件中配置日志组件也可以,MyBatis 会智能识别。
使用logback,还需要提供logback的配置文件,主要配置日志输出相关的级别以及日志具体的格式:
- 名字必须叫做:logback.xml 或者 logback-test.xml
- 必须放到类的根路径下
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义⽇志⽂件的存储地址-->
<!--配置文件属性,使用 ${name} 引用-->
<property name="LOG_HOME" value="/home"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:⽇志消息,%n是换⾏符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天⽣成⽇志⽂件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--⽇志⽂件输出的⽂件名-->
<FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--⽇志⽂件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:⽇志消息,%n是换⾏符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--⽇志⽂件最⼤的⼤⼩-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--mybatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- ⽇志输出级别,logback⽇志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>MyBatis 工具类的封装
执行sql是session对象,builder仅仅用于建造factory,建造好factory后即可回收资源。
一个factory对应一个数据库环境,也不需要频繁建造,因此可以将 builder、factory的相关代码封装成工具类,直接通过工具类获取session执行sql。
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* MyBatis⼯具类
*/
public class SqlSessionUtil {
// 工具类构造方法常私有化
private SqlSessionUtil(){}
private static SqlSessionFactory sqlSessionFactory;
/**
* 类加载时初始化sqlSessionFactory对象
*/
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 每调⽤⼀次openSession()可获取⼀个新的会话
* @return 新的会话对象
*/
public static SqlSession openSession() {
return sqlSessionFactory.openSession();
}
}