MyBatis + XML
使用 mybatis-spring-boot-starter
自动化配置 MyBatis 主要配置。同时,在 XML 中编写相应的 SQL 操作。
1、引入依赖
在 pom.xml
文件中,引入相关依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 实现对 MyBatis 的自动化配置 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、配置注解扫描 mapper
@SpringBootApplication
@MapperScan(basePackages = "com.springboot.mapper") #注解扫描mapper
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
3、配置 application.yaml
spring:
# datasource 数据源配置内容
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
# mybatis 配置内容
mybatis:
config-location: classpath:mybatis-config.xml # 配置 MyBatis 配置文件路径
mapper-locations: classpath:mapper/*.xml # 配置 Mapper XML 地址
type-aliases-package: com.springboot.entity # 配置数据库实体包路径
4、mybatis 配置文件
在 resources
目录下,创建 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>
<settings>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<typeAlias alias="Integer" type="java.lang.Integer"/>
<typeAlias alias="Long" type="java.lang.Long"/>
<typeAlias alias="HashMap" type="java.util.HashMap"/>
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
<typeAlias alias="ArrayList" type="java.util.ArrayList"/>
<typeAlias alias="LinkedList" type="java.util.LinkedList"/>
</typeAliases>
</configuration>
因为在数据库中的表的字段,我们是使用下划线风格,而数据库实体的字段使用驼峰风格,所以通过
mapUnderscoreToCamelCase = true
来自动转换。
在 resources/mapper
路径下,创建 UserMapper.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.springboot.mapper.UserMapper">
<sql id="FIELDS">
id, username, password, create_time
</sql>
<insert id="insert" parameterType="UserDo" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (
username, password, create_time
) VALUES (
#{username}, #{password}, #{createTime}
)
</insert>
<update id="updateById" parameterType="UserDo">
UPDATE users
<set>
<if test="username != null">
, username = #{username}
</if>
<if test="password != null">
, password = #{password}
</if>
</set>
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="Integer">
DELETE FROM users
WHERE id = #{id}
</delete>
<select id="selectById" parameterType="Integer" resultType="UserDo">
SELECT
<include refid="FIELDS" />
FROM users
WHERE id = #{id}
</select>
<select id="selectByUsername" parameterType="String" resultType="UserDo">
SELECT
<include refid="FIELDS" />
FROM users
WHERE username = #{username}
LIMIT 1
</select>
<select id="selectByIds" resultType="UserDo">
SELECT
<include refid="FIELDS" />
FROM users
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
</select>
</mapper>
5、代码实现
在 com.springboot.entity
下创建实体包 UserDo.java
/**
* 用户id
*/
private Integer id;
/**
* 账号
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 创建时间
*/
private Date createTime;
//省略get/set方法
对应的SQL语句,数据库名为 mybatis-test
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
`username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
`password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
在 com.springboot.mapper
下创建 UserMapper.java
接口
@Repository
public interface UserMapper {
int insert(UserDo user);
int updateById(UserDo user);
int deleteById(@Param("id") Integer id);
UserDo selectById(@Param("id") Integer id);
UserDo selectByUsername(@Param("username") String username);
List<UserDo> selectByIds(@Param("ids") Collection<Integer> ids);
}
@Repository
注解,用于标记是数据访问 Bean 对象。
@Param
注解,声明变量名。
6、测试
在测试类 SpringbootApplicationTests.java
中进行测试
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert() {
UserDo userDo = new UserDo();
userDo.setUsername(UUID.randomUUID().toString());
userDo.setPassword("niubi");
userDo.setCreateTime(new Date());
userMapper.insert(userDo);
}
@Test
public void testUpdateById() {
UserDo userDo = new UserDo();
userDo.setId(1);
userDo.setPassword("niubi666");
userMapper.updateById(userDo);
}
@Test
public void testDeleteById() {
userMapper.deleteById(5);
}
@Test
public void testSelectById() {
System.out.println(userMapper.selectById(1));
}
@Test
public void testSelectByUsername() {
userMapper.selectByUsername("penguin");
}
@Test
public void testSelectByIds() {
List<UserDo> users = userMapper.selectByIds(Arrays.asList(1, 3));
System.out.println("users:" + users.size());
}
}
MyBatis + 注解
注解方式与 xml 方式相差不多,如果使用注解,在 application.yaml
配置文件中,我们可以删除 mapper-locations
配置项。当然,如果想 XML 和注解一起使用,可以保留该配置项。
可以删除 UserMapper.xml
配置文件,在 UserMapper
接口上声明 SQL,注解的使用方式是在接口上通过注解声明 SQL 操作。
其他配置与 xml 相同。
在 UserMapper.java
接口上声明SQL:
@Repository
public interface UserMapper {
@Insert("INSERT INTO users(username, password, create_time) VALUES(#{username}, #{password}, #{createTime})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
int insert(UserDO user);
@Update(value = {
"<script>",
"UPDATE users",
"<set>",
"<if test='username != null'>, username = #{username}</if>",
"<if test='password != null'>, password = #{password}</if>",
"</set>",
"</script>"
})
int updateById(UserDO user);
@Insert("DELETE FROM users WHERE id = #{id}")
int deleteById(@Param("id") Integer id);
@Select("SELECT username, password, create_time FROM users WHERE id = #{id}")
UserDO selectById(@Param("id") Integer id);
@Select("SELECT username, password, create_time FROM users WHERE username = #{username}")
UserDO selectByUsername(@Param("username") String username);
@Select(value = {
"<script>",
"SELECT username, password, create_time FROM users",
"WHERE id IN",
"<foreach item='id' collection='ids' separator=',' open='(' close=')' index=''>",
"#{id}",
"</foreach>",
"</script>"
})
List<UserDO> selectByIds(@Param("ids") Collection<Integer> ids);
}
测试方法还是上面的测试类方法。
MyBatis-Plus
我们使用 mybatis-plus-boot-starter
自动化配置 MyBatis-Plus 的配置。
1、引入依赖
在 pom.xml
文件中,引入相关依赖。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!-- 实现对 MyBatis Plus 的自动化配置 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
2、配置 application.yaml
spring:
# datasource 数据源配置内容
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
# mybatis-plus 配置内容
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
global-config:
db-config:
id-type: auto # ID 主键自增
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath:mapper/*.xml # 配置 Mapper XML 地址
type-aliases-package: com.springboot.entity # 配置数据库实体包路径
logging:
level:
com:
springboot:
mapper: debug
相比 mybatis
配置项来说,mybatis-plus
增加了更多配置项,也因此我们无需在配置 mybatis-config.xml
配置文件。
配置 logging
,方便我们看到 MyBatis-Plus 自动生成的 SQL 。
3、代码实现
在 com.springboot.entity
下创建实体包 UserDo.java
@TableName(value = "users")
public class UserDo {
private Integer id;
private String username;
private String password;
private Date createTime;
/**
* 是否删除
*/
@TableLogic
private Integer deleted;
//省略get/set方法
}
-
@TableName
注解,设置了 UserDo 对应的表名是users
。 -
增加了
deleted
字段,并添加了@TableLogic
注解,设置该字段为逻辑删除的标记。 -
在
application.yaml
配置文件中,我们配置了删除(logic-delete-value = 1
)和未删除(logic-not-delete-value = 0
)。当然,也可以通过注解的value
和delval
来定义未删除和删除。
对应的创建表的 SQL 如下:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
`username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
`password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`deleted` bit(1) DEFAULT NULL COMMENT '是否删除。0-未删除;1-删除',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
在 com.springboot.mapper
下创建 UserMapper.java
接口
@Repository
public interface UserMapper extends BaseMapper<UserDo> {
default UserDo selectByUsername(@Param("username") String username) {
return selectOne(new QueryWrapper<UserDo>().eq("username", username));
}
List<UserDo> selectByIds(@Param("ids") Collection<Integer> ids);
default IPage<UserDo> selectPageByCreateTime(IPage<UserDo> page, @Param("createTime") Date createTime) {
return selectPage(page, new QueryWrapper<UserDo>().gt("create_time", createTime));
}
}
- 继承了
com.baomidou.mybatisplus.core.mapper.BaseMapper<T>
接口,这样常规的 CRUD 操作,MyBatis-Plus 就可以替我们自动生成。更多 BaseMapper 已经提供好的接口方法,可以看看《MyBatis-Plus 文档 —— CRUD 接口》 。 - 对于
#selectByUsername()
方法,我们使用了 MyBatis-Plus 提供的QueryWrapper<T>
构造相对灵活的条件,这样一些动态 SQL 我们就无需在 XML 中编写。更多 QueryWrapper 已经提供好的拼接方法,可以看看 《MyBatis-Plus 文档 —— 条件构造器》 - 对于
#selectByIds()
方法,实际也可以使用 MyBatis-Plus 的 QueryWrapper 很方便的实现,这里仅仅是为了演示在 MyBatis-Plus 混合使用 XML 。 - 对于
#selectPageByCreateTime(IPage<UserDO> page, @Param("createTime") Date createTime)
方法,是用于演示 MyBatis-Plus 提供的分页插件。更多 IPage 的内容,可以看看 《MyBatis-Plus 文档 —— 分页插件》
在 resources/mapper
路径下,创建 UserMapper.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.springboot.mapper.UserMapper">
<sql id="FIELDS">
id, username, password, create_time
</sql>
<select id="selectByIds" resultType="UserDo">
SELECT
<include refid="FIELDS" />
FROM users
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
</select>
</mapper>
4、测试
测试方法跟上面 XML 一样,多一个分页的单元测试方法,如下:
@Test
public void testSelectPageByCreateTime() {
IPage<UserDo> page = new Page<>(1, 10);
Date createTime = new Date(2021 - 1990, Calendar.FEBRUARY, 24);
page = userMapper.selectPageByCreateTime(page, createTime);
System.out.println("users:" + page.getRecords().size());
}
MyBatis-Plus 简化了 SQL 代码的编写工作,为编码提供了很多的方便。