1 简介
Mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将Java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成Java对象。Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。
Mybatis-Plus(简称MP)是一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发、提高效率而生。它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。Mybatis-Plus与Spring Boot的整合亦非常简单,只需把Mybatis的依赖换成Mybatis-Plus的依赖,再把sqlSessionFactory换成Mybatis-Plus的即可。
使用Spring Boot + Mybatis-Plus可以轻松实现后端服务对数据库操作的整合。本文将基于Spring Boot 2.2.5.RELEASE版本,讲述Spring Boot + Mybatis-Plus的整合方法,数据库使用MySQL。demo源码下载地址:https://github.com/wangzh0201/cloud
2 添加依赖
在pom.xml文件中添加如下依赖(本文使用国产数据库连接池插件com.alibaba.druid):
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<!-- 引入mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
3 修改配置文件
在application.properties配置文件中增加数据库相关配置,代码如下:
# 数据库设置
spring.jpa.open-in-view=false
spring.datasource.druid.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3307/data_server?useUnicode=true&characterEncoding=utf8&serverTimezone=CTT
spring.datasource.druid.username=root
spring.datasource.druid.password=root123
# 初始化大小,最小,最大
spring.datasource.druid.initialSize=10
spring.datasource.druid.minIdle=10
spring.datasource.druid.maxActive=100
# 配置获取连接等待超时的时间
spring.datasource.druid.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.minEvictableIdleTimeMillis=300000
# 校验SQL
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.druid.filters=stat,wall
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 监控配置
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=hbfec
# 防火墙配置
spring.datasource.druid.filter.wall.enabled=true
spring.datasource.druid.filter.wall.db-type=mysql
spring.datasource.druid.filter.wall.config.comment-allow=true
# 日志配置
spring.datasource.druid.filter.slf4j.enabled=true
spring.datasource.druid.filter.slf4j.statement-create-after-log-enabled=false
spring.datasource.druid.filter.slf4j.statement-close-after-log-enabled=false
spring.datasource.druid.filter.slf4j.result-set-open-after-log-enabled=false
spring.datasource.druid.filter.slf4j.result-set-close-after-log-enabled=false
4 创建数据源配置
创建config包,在config包下创建Java类文件DruidConfig,用于配置数据源,代码示例如下:
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource.druid")
@Bean
public DataSource druid() {
DataSource dataSource = DruidDataSourceBuilder.create().build();
return dataSource;
}
/**
* 配置Druid的监控
* 配置一个管理后台的Servlet
*
* @return
*/
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "123456");
initParams.put("allow", ""); //默认允许所有访问
bean.setInitParameters(initParams);
return bean;
}
/**
* 配置一个web监控的filter
*
* @return
*/
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
5 创建Mybatis-Plus配置
在config包下创建Java类文件MyBatisPlusConfig,用于设置Mybatis的配置项,本文示例为分页查询配置,代码示例如下:
@EnableTransactionManagement
@Configuration
@MapperScan({"com.baomidou.cloud.service.*.mapper*", "com.cm.cloud.mapper"})
public class MyBatisPlusConfig {
/**
* 分页查询配置
*
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
return paginationInterceptor;
}
}
使用@EnableTransactionManagement注解是为了开启数据库的事务支持,之后在访问数据库的Service方法上添加注解 @Transactional 便可使用事务进行数据库操作。
@MapperScan注解添加对mapper文件的扫描,com.baomidou.cloud.service..mapper为Mybatis-Plus自带的mapper文件,com.cm.cloud.mapper为后台服务mapper文件位置。
6 创建实体类
创建实体类与数据库的表进行关联,代码示例如下:
@TableName(value = "user")
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Serializable {
@TableId
private Long id;
private String account;
private String password;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(value = "create_time")
private Date createTime;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(value = "modify_time")
private Date modifyTime;
private Integer deleted;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getModifyTime() {
return modifyTime;
}
public void setModifyTime(Date modifyTime) {
this.modifyTime = modifyTime;
}
public Integer getDeleted() {
return deleted;
}
public void setDeleted(Integer deleted) {
this.deleted = deleted;
}
@Override
public String toString() {
return "id:" + id
+ ",account:" + account
+ ",password:" + password
+ ",createTime:" + createTime
+ ",modifyTime:" + modifyTime
+ ",deleted:" + deleted;
}
}
@TableName注解设置关联数据库中表的名字。
@JsonIgnoreProperties(ignoreUnknown = true)注解写在类上之后,就会忽略类中不存在的字段。这个注解还可以指定要忽略的字段,例如@JsonIgnoreProperties({ “password”, “deleted” })。
7 创建Mapper
在com.cm.cloud.mapper包下创建实体类对应的mapper文件,实现对数据库的增删改查操作,示例代码如下:
@Repository
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT * FROM user WHERE account=#{account} AND deleted=0 LIMIT 1")
@Results({
@Result(property = "createTime", column = "create_time"),
@Result(property = "modifyTime", column = "modify_time")
})
User getUserByAccount(@Param("account") String account);
}
继承Mybatis-Plus的BaseMapper类,则可以直接使用Mybatis-Plus中对数据库操作的一些函数,比如insert、selectPage、updateById等。
在mapper文件中,也可以使用注解编写sql语句,实现自定义的数据库操作函数,例如上述代码中的getUserByAccount。
8 实现数据库操作
实现mapper文件后,在Service层就可以通过调用mapper实现数据库的增删改查操作了,示例代码如下:
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
@Service
public class UserServiceImpl implements UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
@Autowired
UserMapper userMapper;
/**
* 分页查询
*
* @param currentPage
* @param pageSize
* @return
*/
@Override
public List<User> getUsersByPage(Integer currentPage, Integer pageSize) {
Page<User> page = new Page<>(currentPage, pageSize);
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.eq("deleted", 0);
userMapper.selectPage(page, wrapper);
return page.getRecords();
}
/**
* 根据account获取用户信息
*
* @param user
* @return
*/
@Override
public User getUserByAccount(User user) {
if (user != null) {
// 缓存不存在,从数据库获取
return userMapper.getUserByAccount(user.getAccount());
}
return null;
}
/**
* 添加用户
*
* @param user
* @return
*/
@Override
public User insertUser(User user) {
if (user != null) {
Date now = new Date();
user.setCreateTime(now);
user.setModifyTime(now);
user.setDeleted(0);
int result = userMapper.insert(user);
if (result > 0) {
return user;
}
}
return null;
}
/**
* 根据id更新用户信息
*
* @param user
* @return
*/
@Override
public User updateUser(User user) {
if (user != null) {
int result = userMapper.updateById(user);
if (result > 0) {
return user;
}
}
return null;
}
/**
* 根据id删除用户,逻辑删除
*
* @param user
* @return
*/
@Override
public int deleteUser(User user) {
if (user != null) {
user.setDeleted(1);
return userMapper.updateById(user);
}
return 0;
}
}