抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文学习了如何使用MyBatis进行数据库操作。

环境

Windows 10 企业版 LTSC 21H2
MySQL 5.7.40
Java 1.8
Maven 3.6.3
MyBatis 3.5.6

1 入门案例

目录结构:

code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
demo-mybatis/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/
│ │ │ ├── mapper/
│ │ │ │ ├── UserMapper.java
│ │ │ │ └── UserMapper.xml
│ │ │ ├── pojo/
│ │ │ │ └── User.java
│ │ │ └── DemoApplication.java
│ │ └── resources/
│ │ ├── jdbc.properties
│ │ └── mybatis-config.xml
└── pom.xml

创建pom.xml文件:

pom.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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>demo-mybatis</artifactId>
<version>1.0.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>

<build>
<!-- 配置资源文件 -->
<resources>
<!-- 保留默认的资源目录 -->
<resource>
<directory>src/main/resources</directory>
</resource>
<!-- 额外添加XML文件 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<!-- 禁止Maven替换XML中的占位符,交由MyBatis处理 -->
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>

创建MyBatis配置文件:

mybatis-config.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 configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部属性文件 -->
<properties resource="jdbc.properties"/>
<!-- 指定运行环境,可以配置多个环境,只能指定一个 -->
<environments default="dev">
<!-- 配置开发环境 -->
<environment id="dev">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 数据源 -->
<property name="driver" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射 -->
<mappers>
<!-- 指定Mapper映射文件位置 -->
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
</configuration>

创建MySQL配置文件:

jdbc.properties
1
2
3
4
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=GMT%2B8
username=root
password=123456

创建数据库表:

mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

USE test;

CREATE TABLE IF NOT EXISTS user (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
name VARCHAR(100) NOT NULL COMMENT '姓名',
age INT NOT NULL COMMENT '年龄',
email VARCHAR(100) DEFAULT NULL COMMENT '邮箱'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

INSERT INTO user (name, age, email) VALUES
('张三', 25, 'zhangsan@example.com'),
('李四', 30, 'lisi@example.com'),
('王五', 28, 'wangwu@example.com');

创建实体类:

java
1
2
3
4
5
6
7
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
// ...
}

创建Mapper接口:

java
1
2
3
public interface UserMapper {
User selectUserById(Integer id);
}

创建Mapper配置文件:

xml
1
2
3
4
5
6
7
8
9
<?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.example.mapper.UserMapper">
<!-- 配置SQL语句 -->
<select id="selectUserById" resultType="com.example.pojo.User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>

创建启动类:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DemoApplication {
public static void main(String[] args) {
// 读取配置文件
InputStream inputStream = DemoApplication.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(inputStream);
// 创建SqlSession对象,开启会话,设置自动提交事务,否则需要手动提交事务
SqlSession session = factory.openSession(true);
// 获取UserMapper接口
UserMapper mapper = session.getMapper(UserMapper.class);
// 执行查询
User user = mapper.selectUserById(1);
// 打印结果
System.out.println(user);
// 关闭SqlSession对象,关闭会话,自动提交事务
session.close();
}
}

执行启动类的main()方法。

2 配置方式

2.1 XML配置

使用标签进行增删改查:

  • 使用select标签查询数据
  • 使用insert标签插入数据
  • 使用update标签更新数据
  • 使用delete标签删除数据

标签通用属性:

  • id属性:SQL唯一标识符,在一个Mapper映射文件中必须唯一。
  • parameterType属性:SQL参数类型,用于指定SQL的参数类型,可以省略。
  • resultType属性:SQL返回类型,用于指定SQL的返回类型。

需要在MyBatis配置文件中指定Mapper映射文件的位置:

xml
1
2
3
4
5
<!-- 配置映射 -->
<mappers>
<!-- 指定Mapper映射文件位置 -->
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>

如果Mapper映射文件和Mapper接口在同一目录,还需要在pom.xml文件中添加额外的资源文件:

xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<build>
<!-- 配置资源文件 -->
<resources>
<!-- 保留默认的资源目录 -->
<resource>
<directory>src/main/resources</directory>
</resource>
<!-- 额外添加XML文件 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<!-- 禁止Maven替换XML中的占位符,交由MyBatis处理 -->
<filtering>false</filtering>
</resource>
</resources>
</build>

2.2 注解配置

使用注解进行增删改查:

  • 使用@Select注解查询数据
  • 使用@Insert注解插入数据
  • 使用@Update注解更新数据
  • 使用@Delete注解删除数据

需要在MyBatis配置文件中指定Mapper接口的位置:

xml
1
2
3
4
5
<!-- 配置映射 -->
<mappers>
<!-- 指定Mapper接口位置 -->
<package name="com.example.mapper"/>
</mappers>

不需要在pom.xml文件中添加额外的资源文件,但是需要在Mapper接口上使用注解配置SQL语句:

java
1
2
@Select("SELECT * FROM user WHERE id = #{id}")
User selectUserById(Integer id);

注解配置只能处理简单的SQL语句,如果SQL语句比较复杂,需要使用XML配置。

3 基本操作

3.1 DML操作

3.1.1 插入操作

修改Mapper接口:

java
1
Integer insertUser(User user);
3.1.1.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<insert id="insertUser">
INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})
</insert>

获取自增主键:

xml
1
2
3
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})
</insert>
3.1.1.2 注解配置

修改Mapper接口:

java
1
2
@Insert("INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})")
Integer insertUser(User user);

获取自增主键:

java
1
2
3
@Insert("INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})")
@Options(useGeneratedKeys=true, keyProperty="id")
Integer insertUser(User user);

3.1.2 删除操作

修改Mapper接口:

java
1
Integer deleteUserById(Integer id);
3.1.2.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<delete id="deleteUserById">
DELETE FROM user WHERE id = #{id}
</delete>
3.1.2.2 注解配置

修改Mapper接口:

java
1
2
@Delete("DELETE FROM user WHERE id = #{id}")
Integer deleteUserById(Integer id);

3.1.3 更新操作

修改Mapper接口:

java
1
Integer updateUserById(User user);
3.1.3.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<update id="updateUserById">
UPDATE user SET name = #{name}, age = #{age}, email = #{email} WHERE id = #{id}
</update>
3.1.3.2 注解配置

修改Mapper接口:

java
1
2
@Update("UPDATE user SET name = #{name}, age = #{age}, email = #{email} WHERE id = #{id}")
Integer updateUserById(User user);

3.2 DQL操作

3.2.1 通过单个参数查询单个对象

修改Mapper接口:

java
1
User selectUserById(Integer id);
3.2.1.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<select id="selectUserById" resultType="com.example.pojo.User">
SELECT * FROM user WHERE id = #{id}
</select>
3.2.1.2 注解配置

修改Mapper接口:

java
1
2
@Select("SELECT * FROM user WHERE id = #{id}")
User selectUserById(Integer id);

3.2.2 通过单个参数查询对象列表

修改Mapper接口:

java
1
List<User> selectUserListByName(String name);
3.2.2.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<select id="selectUserListByName" resultType="com.example.pojo.User">
SELECT * FROM user WHERE name = #{name}
</select>
3.2.2.2 注解配置

修改Mapper接口:

java
1
2
@Select("SELECT * FROM user WHERE name = #{name}")
List<User> selectUserListByName(String name);

3.2.3 通过对象参数查询对象列表

修改Mapper接口:

java
1
List<User> selectUserListByUser(User user);
3.2.3.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<select id="selectUserListByUser" resultType="com.example.pojo.User">
SELECT * FROM user WHERE name = #{name} AND age = #{age}
</select>
3.2.3.2 注解配置

修改Mapper接口:

java
1
2
@Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}")
List<User> selectUserListByUser(User user);

3.2.4 通过集合参数查询对象列表

修改Mapper接口:

java
1
List<User> selectUserListByMap(Map<String, Object> map);
3.2.4.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<select id="selectUserListByMap" resultType="com.example.pojo.User">
SELECT * FROM user WHERE name = #{name} AND age = #{age}
</select>
3.2.4.2 注解配置

修改Mapper接口:

java
1
2
@Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}")
List<User> selectUserListByMap(Map<String, Object> map);

3.2.5 通过多个参数查询对象列表

修改Mapper接口:

java
1
List<User> selectUserListByInfo(@Param("name") String name, @Param("age") Integer age);

多个参数需要使用@Param注解指定参数名,否则会报错,单个参数可以省略@Param注解。

3.2.5.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<select id="selectUserListByInfo" resultType="com.example.pojo.User">
SELECT * FROM user WHERE name = #{name} AND age = #{age}
</select>
3.2.5.2 注解配置

修改Mapper接口:

java
1
2
@Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}")
List<User> selectUserListByInfo(@Param("name") String name, @Param("age") Integer age);

3.2.6 通过单个参数查询集合列表

修改Mapper接口:

java
1
List<Map<String, Object>> selectMapListByName(String name);
3.2.6.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<select id="selectMapListByName" resultType="java.util.Map">
SELECT name, email FROM user WHERE name = #{name}
</select>
3.2.6.2 注解配置

修改Mapper接口:

java
1
2
@Select("SELECT name, email FROM user WHERE name = #{name}")
List<Map<String, Object>> selectMapListByName(String name);

3.2.7 通过单个参数查询结果映射

修改Mapper接口:

java
1
List<User> selectUserListByEmail(String email);
3.2.7.1 XML配置

修改Mapper配置文件,使用resultMap标签:

xml
1
2
3
4
5
6
7
8
9
10
11
<!-- 定义结果映射 -->
<resultMap type="com.example.pojo.User" id="userResultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="email" property="email"/>
</resultMap>
<!-- 使用结果映射 -->
<select id="selectUserListByEmail" resultMap="userResultMap">
SELECT * FROM user WHERE email = #{email}
</select>
3.2.7.2 注解配置

修改Mapper接口,使用@Results注解和@Result注解:

java
1
2
3
4
5
6
7
8
9
10
// 定义结果映射
@Results({
@Result(column="id", property="id", id=true),
@Result(column="name", property="name"),
@Result(column="age", property="age"),
@Result(column="email", property="email")
})
// 使用结果映射
@Select("SELECT * FROM user WHERE email = #{email}")
List<User> selectUserListByEmail(String email);

3.3 DDL操作

3.3.1 创建数据表

修改Mapper接口:

java
1
void createTable(String tableName);
3.3.1.1 XML配置

修改Mapper配置文件:

xml
1
2
3
4
5
6
7
8
<update id="createTable">
CREATE TABLE IF NOT EXISTS ${tableName} (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
name VARCHAR(100) NOT NULL COMMENT '姓名',
age INT NOT NULL COMMENT '年龄',
email VARCHAR(100) DEFAULT NULL COMMENT '邮箱'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'
</update>
3.3.1.2 注解配置

修改Mapper接口:

java
1
2
3
4
5
6
7
@Update("CREATE TABLE IF NOT EXISTS ${tableName} ( " + 
"id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键', " +
"name VARCHAR(100) NOT NULL COMMENT '姓名', " +
"age INT NOT NULL COMMENT '年龄', " +
"email VARCHAR(100) DEFAULT NULL COMMENT '邮箱' " +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'")
void createTable(String tableName);

3.3.2 清空数据表

修改Mapper接口:

java
1
void truncateTable(String tableName);
3.3.2.1 XML配置

修改Mapper配置文件:

xml
1
2
3
<update id="truncateTable">
TRUNCATE TABLE ${tableName}
</update>
3.3.2.2 注解配置

修改Mapper接口:

java
1
2
@Update("TRUNCATE TABLE ${tableName}")
void truncateTable(String tableName);

4 参数传递

在通过XML配置使用参数时,需要将参数传递到XML配置文件中。

4.1 使用单个简单类型参数

建议在Mapper接口中省略@Param注解。

可以在XML配置的占位符中使用任意参数名,建议和方法参数名一致。

4.2 使用单个对象类型参数

建议在Mapper接口中省略@Param注解。

可以在XML配置的占位符中使用对象属性名,需要属性有对应的Set方法。

4.3 使用Map类型参数

建议在Mapper接口中省略@Param注解。

可以在XML配置的占位符中使用Map的键名。

4.4 使用列表类型参数

建议在Mapper接口中使用@Param注解,并且指定参数名。

可以在XML配置的占位符中使用@Param注解指定的参数名。

如果省略@Param注解,可以使用默认参数名:

  • 如果是List类型的参数,默认使用list作为参数名
  • 如果是Array类型的参数,默认使用array作为参数名

4.5 使用多个参数

建议在Mapper接口中使用@Param注解,并且指定参数名。

可以在XML配置的占位符中使用@Param注解指定的参数名,简单类型可以直接使用参数名,对象类型需要通过参数名.属性名的方式使用属性名。

5 参数引用

在通过XML配置使用参数时,可以使用#{}${}两种引用方式,比较这两种方式的区别:

对比项 #{}(预编译占位符) ${}(替换字符串)
安全性 使用PreparedStatement设置参数值,能够防止SQL注入攻击 直接替换字符串生成SQL,无法防止SQL注入攻击
功能性 用于参数值传递 用于表名、字段名等动态对象传递,因为这些地方不支持预编译,使用时必须校验字符串

评论