Java · 框架 · MyBatis

简介

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

原理

MyBatis 的基本工作原理是:

  • 先封装 SQL
  • 接着调用 JDBC 操作数据库
  • 最后把数据库返回的表结果封装成 Java 类

使用

如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中:

1
2
3
4
5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>

实践

使用 MyBatis 实现数据库的增删改查:

  • user
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime DEFAULT NULL COMMENT '生日',
`sex` char(1) NOT NULL COMMENT '性别',
`address` varchar(255) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

mysql> select * from user;
+----+----------+---------------------+-----+--------------------+
| id | username | birthday | sex | address |
+----+----------+---------------------+-----+--------------------+
| 1 | rao | 1990-08-07 00:00:00 | 男 | 陕西省西安市 |
| 2 | yu | 1990-01-02 00:00:00 | 女 | 山东省菏泽市 |
| 3 | rao | 2019-11-24 04:54:31 | 女 | 山东省青岛市 |
+----+----------+---------------------+-----+--------------------+
  • 主配置文件 SqlMapperConfig.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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">

<!-- MyBatis主配置文件 -->
<configuration>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置mysql环境 -->
<environment id="mysql">
<!-- 配置事务类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源 -->
<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="root"/>
</dataSource>
</environment>
</environments>

<!-- 指定映射配置文件的位置 -->
<mappers>
<!-- XML方式 -->
<mapper resource="com/rao/dao/IUserMapper.xml"/>
<!-- 注解方式 -->
<!--mapper class="com.rao.dao.IUserDao"/-->
</mappers>
</configuration>
  • 实体类 User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.rao.domain;

import java.io.Serializable;
import java.util.Date;

/**
* user表实体类
*
* @author Rao Hui
* @date 2019-11-24 15:12
*/
public class User implements Serializable {

private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
  • Dao 接口 IUserDao.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.rao.dao;

import com.rao.domain.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
* 用户的持久层接口
*
* @author Rao Hui
* @date 2019-11-24 15:17
*/
public interface IUserDao {

/**
* 查询用户
* @return
*/
//@Select("select * from user") // 注解方式
List<User> findAll();

/**
* 保存用户
*/
void saveUser(User user);

/**
* 更新用户
*/
void updateUser(User user);

/**
* 删除用户
*/
void deleteUser(Integer userId);
}
  • 映射配置文件 IUserMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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.rao.dao.IUserDao">
<!-- 查询用户 -->
<select id="findAll" resultType="com.rao.domain.User">
select * from user;
</select>

<!-- 插入用户 -->
<insert id="saveUser" parameterType="com.rao.domain.User">
insert into user (username,sex,birthday,address) values (#{username},#{sex},#{birthday},#{address})
</insert>

<!-- 更新用户 -->
<update id="updateUser" parameterType="com.rao.domain.User">
update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}
</update>

<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{uid}
</delete>
</mapper>
  • 接口测试类 MybatisTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.rao.test;

import com.rao.dao.IUserDao;
import com.rao.domain.User;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
* mybatis入门测试
*
* @author Rao Hui
* @date 2019-11-24 15:49
*/
public class MybatisTest {

private InputStream in;
private SqlSession session;
private IUserDao userDao;

@Before
public void init() throws IOException
{
// 1. 读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");

// 2. 创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);

// 3. 使用工厂生产SqlSession对象
session = factory.openSession();

// 4. 使用SqlSession创建Dao接口的代理对象
userDao = session.getMapper(IUserDao.class);
}

@After
public void destroy() throws IOException
{
session.commit();

// 释放资源
session.close();
in.close();
}

@Test
public void testFindAll(){

// 5. 使用代理对象执行方法
List<User> users = userDao.findAll();
for (User user : users)
{
System.out.println(user);
}
}

@Test
public void testSaveUser()
{
User user = new User();
user.setUsername("hui");
user.setSex("男");
user.setAddress("山东省青岛市");
user.setBirthday(new Date());

userDao.saveUser(user);
}

@Test
public void testUpdateUser()
{
User user = new User();
user.setId(3);
user.setUsername("liu");
user.setSex("女");
user.setAddress("山东省青岛市");
user.setBirthday(new Date());

userDao.updateUser(user);
}

@Test
public void testDeleteUser()
{
userDao.deleteUser(4);
}
}

参考

来源