整合 MybatisPlus 操作数据库
# 530.整合 MybatisPlus 操作数据库
本节课我们来学习整合 Mybatis-Plus,完成基本的查询功能
# 什么是 Mybatis-Plus
Mybatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
官网:MyBatis-Plus (opens new window),GitHub 地址:github.com/baomidou/mybatis-plus (opens new window)
# MybatisX 插件
官网文档:MybatisX 快速开发插件 | MyBatis-Plus (opens new window)
MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入
mybatisx
搜索并安装。
其功能丰富,例如可以通过 Mapper 接口,跳转到 XML:
还有生成代码、重置模板、智能提示等功能,更多内容请看文档。
# 需求
接下来我们使用 Mybatis-Plus,来完成动态表格中数据的显示(从数据库中读取并显示):
为此,我们先学习下如何使用 Mybatis-Plus,下节课再开始做修改
ps:我们在学习异常处理的时候,手动给
/dynamic_table
请求抛出了一个异常
public class TableController { @GetMapping("/dynamic_table") public String dynamic_table(Model model){ List<User> users = Arrays.asList(new User("zhangsan", "123456"), new User("lisi", "123444"), new User("haha", "aaaaa"), new User("hehe", "aaddd")); model.addAttribute("users", users); if (users.size() > 3){ throw new UserTooManyException(); } return "table/dynamic_table"; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16这里我们删除抛出异常相关代码:
# 数据库准备
根据 MyBatis-Plus 快速入门文档 (opens new window),我们准备下数据库
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) AUTO_INCREMENT NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 修改表单
先删除掉无用的表格,例如下面的“DATATABLES HIDDEN ROW DETAILS EXAMPLE”
对应的代码在 dynamic_table.html,我们直接删除其外层的 div(class = row 的 div):
# 引入依赖
根据 Mybatis 文档,引入:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
2
3
4
5
可以分析下其依赖:
可以看到引入了不少和数据源开发相关的,因此我们可以注释掉我们之前配置的这依赖:
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.1.4</version>-->
<!-- </dependency>-->
2
3
4
5
6
7
8
9
10
# 自动配置
我们看看 Mybatis-Plus 自动配置了什么,首先打开 spring.factories
:
其内容:
# Auto Configure
org.springframework.boot.env.EnvironmentPostProcessor=\
com.baomidou.mybatisplus.autoconfigure.SafetyEncryptProcessor
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
2
3
4
5
6
我们打开 MybatisPlusAutoConfiguration
:
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisPlusProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean{
//......
}
2
3
4
5
6
7
8
首先,其配置是绑定了 MybatisPlusProperties
,配置项开头是 mybatis-plus
:
@Data
@Accessors(chain = true)
@ConfigurationProperties(prefix = Constants.MYBATIS_PLUS)
public class MybatisPlusProperties {
private String configLocation;
private String[] mapperLocations = new String[]{"classpath*:/mapper/**/*.xml"};
//..............
2
3
4
5
6
7
8
9
10
11
可以看到 mapperLocations 是有默认值的
还自动配置了 SqlSessionFactory
,用的是容器中的数据源,并且会读取全局配置文件(如有)并加载:
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
//...........
2
3
4
5
6
7
8
9
10
还自动配置了 SqlSessionTemplate
:
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
ExecutorType executorType = this.properties.getExecutorType();
if (executorType != null) {
return new SqlSessionTemplate(sqlSessionFactory, executorType);
} else {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
2
3
4
5
6
7
8
9
10
还配置了扫描 @Mapper
注解的类:
@Configuration
@Import(AutoConfiguredMapperScannerRegistrar.class)
@ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
@Override
public void afterPropertiesSet() {
logger.debug(
"Not found configuration for registering mapper bean using @MapperScan, MapperFactoryBean and MapperScannerConfigurer.");
}
}
2
3
4
5
6
7
8
9
10
11
# 修改 User 类
由于我们已经有 User 类了,但是没有 id、name 属性,我们可以修改 User,增加属性:
package com.peterjxl.learnspringbootwebadmin.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {
private String userName;
private String password;
// 以下是数据库的字段
private Long id;
private String name;
private Integer age;
private String email;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
但是 Mybatis-Plus 中,默认是认为所有类的成员变量,都是在数据库存在的,如果不存在则需要额外指出:
@TableField(exist = false)
private String userName;
@TableField(exist = false)
private String password;
2
3
4
5
此外,默认会通过类名去找数据库中同名的表,但如果数据库表名和类名不同,要如何绑定呢?使用注解 @TableName
@TableName("新表名")
public class User implements Serializable {
//............
2
3
# 准备 Mapper
之前我们是自己写 SQL(不管是配置文件还是使用注解),而 Mybatis-Plus 不用了,我们只需继承一个类:BaseMapper
package com.peterjxl.learnspringbootwebadmin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.peterjxl.learnspringbootwebadmin.bean.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> { }
2
3
4
5
6
7
8
该类已经帮我们写好了一大堆方法:
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
int updateById(@Param(Constants.ENTITY) T entity);
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
//...............
2
3
4
5
6
7
8
9
10
11
12
13
14
接下来,我们测试下,在测试类新增如下代码:
class LearnSpringBootWebAdminApplicationTests {
@Autowired
UserMapper userMapper;
@Test
void testUserMapper() {
log.info("用户信息:{}", userMapper.selectById(1L));
}
}
2
3
4
5
6
7
8
9
运行结果:
用户信息:User(userName=null, password=null, id=1, name=Jone, age=18, email=test1@baomidou.com)
# 源码
已将本文源码上传到 Gitee (opens new window) 或 GitHub (opens new window) 的分支 demo14,读者可以通过切换分支来查看本文的示例代码