背景
MyBatis作为java用户的主流ORM框架,在集成了Spring之后,大大提高了我们开发的效率。但是有没有想过,假如没有集成Spring,如何使用MyBatis呢?
本文将通过MyBatis的原始使用(没有依赖Spring,甚至没有IOC注入),来加深对MyBatis的原理理解。
原始使用
1. 依赖
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!--Junit依赖,用来执行单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>2. 数据库表
-- auto-generated definition
create table user
(
id int unsigned auto_increment comment 'ID'
primary key,
name varchar(100) null comment '姓名',
age tinyint unsigned null comment '年龄',
gender tinyint unsigned null comment '性别, 1:男, 2:女',
phone varchar(11) null comment '手机号'
)
comment '用户表';3. 实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private int age;
private int gender;
private String phone;
}
4. Mapper接口类
public interface UserMapper {
int insert(User user);
}5. 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="com.qiang.dao.UserMapper">
<insert id="insert">
insert into User (id, name, age, gender, phone)
value (#{id}, #{name}, #{age}, #{gender}, #{phone})
</insert>
</mapper>
6. Service
public class UserServiceImpl {
public String addUser(User user){
if (user.getName().isEmpty()) {
throw new RuntimeException("用户名不能为空");
}
return DaoUtils.execute(sqlSession -> {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int count = mapper.insert(user);
return count>0 ? "添加成功" : "添加失败";
});
}
}
7. 配置
jdbc.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username=root
password=1234
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>
<!-- 加载resource资源包下的properties文件-->
<properties resource="jdbc.properties"/>
<settings>
<!--将表中字段的下划线自动转换为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<!-- 设置类型别名 将user / User 自动映射为com.qiang.entity.User 在mapper.xml中不用写全类名 -->
<typeAliases>
<package name="com.qiang.entity"/>
</typeAliases>
<!-- 配置连接数据库的环境-->
<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>
<package name="com.qiang.dao"/>
</mappers>
</configuration>8. DaoUtils
public class DaoUtils {
private static SqlSessionFactory factory;
static {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
System.err.println("read mybatis-config.xml fail");
e.printStackTrace();
System.exit(1);
}
// 加载完mybatis-config.xml配置文件之后,会根据其中的配置信息创建SqlSessionFactory对象
factory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
public static <R> R execute(Function<SqlSession, R> function) {
// 创建SqlSession
SqlSession session = factory.openSession();
try {
R apply = function.apply(session);
// 提交事务
session.commit();
return apply;
} catch (Throwable t) {
// 异常,回滚事务
session.rollback();
System.out.println("execute error");
throw t;
} finally {
// 关闭SqlSession
session.close();
}
}
}9. 测试
package com.qiang;
import com.qiang.entity.User;
import com.qiang.service.UserServiceImpl;
import org.junit.Test;
public class test {
private UserServiceImpl userService;
@Test
public void test1(){
userService = new UserServiceImpl();
String result = userService.addUser(new User(1, "小王", 18, 1, "123456789"));
System.out.println(result);
}
}
SpringBootStarter使用
Spring Boot Starter集成
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.5.4</version>
<scope>test</scope>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>
spring:
data:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
username: root
password: 1234@Service
public class UserServiceImpl {
@Autowired
private UserMapper userMapper;
public String addUser(User user){
int count = userMapper.insert(user);
return count>0 ? "添加成功" : "添加失败";
}
}@SpringBootTest
@ComponentScan(basePackages = "com.qiang")
public class test {
@Autowired
private UserServiceImpl userService;
@Test
public void test1(){
String result = userService.addUser(new User(3, "小王2", 18, 1, "123456789"));
System.out.println(result);
}
}结语
原始使用的方式:
配置
MyBatis-Config使用Utils读取配置,创建
sqlSession执行的时候,要通过
sqlSession获取对应的mapper使用获取的
mapper执行
Spring Boot + mybatis-spring-boot-starter的方式
自动创建
SqlSessionFactory(单例托管到 Spring 容器)自动创建
SqlSession并绑定到 当前线程(SqlSessionTemplate)事务直接交给 Spring 的声明式事务 (
@Transactional),底层帮你commit/rollback/close
---- 模板代码全没了,不需要 DaoUtils
我们要学的是MyBatis的框架原理,所以先从MyBatis的原始使用入手,学习一下基本的执行步骤,后续会慢慢深入到更加细节的内容中。