一、数据准备
二、开发步骤
1、引入依赖
<dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.15</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.2.0</version></dependency>
</dependencies>
2、编写核心配置文件:mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--允许设置多个环境,但是每个 SqlSessionFactory 实例只能选择一种环境设置默认的环境:development--><environments default="development"><!-- 环境配置,名称为:development --><environment id="development"><!-- 配置事物管理器为 JDBC --><transactionManager type="JDBC"/><!-- 配置数据源 --><dataSource type="POOLED"><!-- 配置数据库连接信息 --><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatisdb"/><property name="username" value="root"/><property name="password" value="mysql"/></dataSource></environment></environments><mappers><!-- 指定 XxxMapper.xml 文件 --><mapper resource="CarMapper.xml"/></mappers>
</configuration>
3、编写 XxxMapper.xml 文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="qiuXuan"><!--id就代表了下面的这条sql语句--><insert id="insertCar">insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)values(null,'1003','五菱宏光',30.0,'2020-09-18','燃油车');</insert>
</mapper>
4、在 mybatis-config.xml 文件中指定 XxxMapper.xml 文件的路径
5、编写 MyBatis 程序
-
在 MyBatis 当中 SqlSession 负责 SQL 语句的执行,是 Java 程序与数据库之间的会话
-
要获取 SqlSession 对象,需要先获取 SqlSessionFactory 对象,通过 SqlSessionFactory 工厂来生产 SqlSession 对象
如何获取 SqlSessionFactory 对象?
通过 SqlSessionFactoryBuilder 对象的 build 方法获取一个 SqlSessionFactory 对象
SqlSessionFactoryBuilder ---> SqlSessionFactory ---> SqlSession
java">package com.qiuxuan;public class MyBatisIntroductionTest {public static void main(String[] args) throws IOException {// 获取 SqlSessionFactoryBuilderSqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();/*** 获取 SqlSessionFactory** build 方法的参数为一个 InputStream* 指向 mybatis-config.xml 核心配置文件** 可以通过 MyBatis 的 Resources 工具类获取* 其 getResourceAsStream 方法返回的就是一个 InputStream* 参数为核心配置文件路径(默认从类根路径[resources]查找资源)*/InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = builder.build(is);// 获取 SqlSessionSqlSession sqlSession = factory.openSession();// 执行 SQL 语句(参数为 SQL 语句的 id)int count = sqlSession.insert("insertCar");System.out.println(count);// mybatis 默认是不会自动提交的,需要手动提交sqlSession.commit();}
}
三、MyBatis 中有两个主要的配置文件
-
mybatis-config.xml(一个)
-
核心配置文件,主要配置连接数据库的信息等
-
-
XxxMapper.xml(一个表一个)
-
用于编写 SQL 语句的配置文件
-
四、Tips
mybatis 中 sql 语句的结尾 “;” 可以省略
使用 Resources.getResourceAsStream
获取资源文件的方式符合 OCP 原则,有利于程序的移植性、健壮性
若使用 FileInputStream 方式获取资源文件,当程序需要在其他系统运行时,原来的路径将会失效,需要修改 Java 代码中的资源路径,违背了 OCP 原则
也可使用类加载器获取资源:
java">ClassLoader.getSystemClassLoader().getResourceAsStream("资源路径");
与 Resources.getResourceAsStream
一致,都是从根路径获取资源,即 resources 目录下
ClassLoader.getSystemClassLoader()
获取的是系统类加载器,而 Resources.getResourceAsStream
底层使用的就是 ClassLoader.getSystemClassLoader()
五、MyBatis 的事务管理机制
在 mybatis-config.xml 文件中,可以通过以下的配置进行 mybatis 的事务管理
<transactionManager type="JDBC"/>
type 属性包括两个值:JDBC、 MANAGED,对应两种事务管理机制
-
JDBC 事务管理器
-
MyBatis 框架自己采用管理事务,自己采用原生的 JDBC 代码去管理事务
-
使用 JDBC 事务管理器底层创建事务管理对象的是 JdbcTransation 对象
-
conn.setAutoCommit(false);
开启事务若使用 JDBC 事务管理器,在
factory.openSession()
底层会执行此语句若使用
factory.openSession()
时传入参数 true,则底层不会执行conn.AutoCommit(false)
,也就不会开启事务,此时执行任意 DML 语句都会自动提交业务处理...
conn.commit();
提交事务
-
MANAGED 事务管理器
-
mybatis 不再负责事务的管理了,事务管理交给其他容器负责,例如:Spring
-
六、较完整的 MyBatis 程序
java">package com.qiuxuan;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class MyBatisCompleteCodeTest {public static void main(String[] args) {SqlSession sqlSession = null;try {// 1.创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();// 2.创建SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));// 3.创建SqlSession对象sqlSession = sqlSessionFactory.openSession();// 4.执行SQLint count = sqlSession.insert("insertCar");System.out.println("更新了几条记录:" + count);// 5.提交sqlSession.commit();} catch (Exception e) {// 回滚if (sqlSession != null) {sqlSession.rollback();}e.printStackTrace();} finally {// 6.关闭if (sqlSession != null) {sqlSession.close();}}}
}
七、Junit 单元测试
JUnit 是专门做单元测试的组件。
-
在实际开发中,单元测试一般是由我们 Java 程序员来完成的。
-
要对自己写的每一个业务方法负责任,要保证每个业务方法在进行测试的时候都能通过。
-
-
测试的过程中涉及到两个概念:
-
期望值
-
实际值
-
-
期望值和实际值相同表示测试通过,期望值和实际值不同则单元测试执行时会报错。
1、引入依赖
<!-- junit依赖 -->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>
2、编写单元测试类【测试用例】
测试用例中每一个测试方法上使用 @Test 注解进行标注。
测试用例的名字以及每个测试方法的定义都是有规范的:
-
测试用例的名字:
XxxTest
-
测试方法声明格式:
public void test业务方法名(){}
java">// 测试用例
public class CarMapperTest{// 测试方法@Testpublic void testInsert(){}@Testpublic void testUpdate(){}}
可以在类上执行,也可以在方法上执行
-
在类上执行时,该类中所有的测试方法都会执行。
-
在方法上执行时,只执行当前的测试方法。
-
编写一个测试用例,来测试 insertCar 业务
java">public class CarMapperTest {@Testpublic void testInsertCar(){SqlSession sqlSession = null;try {// 1.创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();// 2.创建SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));// 3.创建SqlSession对象sqlSession = sqlSessionFactory.openSession();// 4.执行SQLint count = sqlSession.insert("insertCar");System.out.println("更新了几条记录:" + count);// 5.提交sqlSession.commit();} catch (Exception e) {// 回滚if (sqlSession != null) {sqlSession.rollback();}e.printStackTrace();} finally {// 6.关闭if (sqlSession != null) {sqlSession.close();}}}
}
八、logback 日志框架
mybatis-config.xml
<settings><setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
注意:<configuration>
里配置的位置是有顺序要求的,否则会报错
Error creating document instance. Cause: org.xml.sax.SAXParseException;
<configuration><properties>...</properties><settings>...</settings><typeAliases>...</typeAliases><typeHandlers>...</typeHandlers><objectFactory>...</objectFactory><objectWrapperFactory>...</objectWrapperFactory><reflectorFactory>...</reflectorFactory><plugins>...</plugins><environments>...</environments><databaseIdProvider>...</databaseIdProvider><mappers>...</mappers>
</configuration>
标准日志也可以用,但是配置不够灵活,可以集成其他的日志组件,例如:log4j,logback等。
-
logback 是目前日志框架中性能较好的,较流行的,所以选它。
-
引入 logback 相关依赖
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.11</version><scope>test</scope>
</dependency>
-
引入 logback 相关配置文件(文件名叫做 logback.xml 或 logback-test.xml,放到类路径当中)
<?xml version="1.0" encoding="UTF-8"?><configuration debug="false"><!-- 控制台输出 --><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 工具类 SqlSessionUtil 的封装
每一次获取 SqlSession 对象代码太繁琐,封装一个工具类
java">/*** MyBatis工具类** @author 秋玄* @version 1.0.0* @since 1.0.0*/
public class SqlSessionUtil {private static final SqlSessionFactory sqlSessionFactory;/*** 类加载时初始化sqlSessionFactory对象*/static {try {SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));} catch (Exception e) {e.printStackTrace();}}/*** 每调用一次openSession()可获取一个新的会话,该会话支持自动提交。** @return 新的会话对象*/public static SqlSession openSession() {return sqlSessionFactory.openSession(true);}
}
一 叶 知 秋,奥 妙 玄 心