Mybatis-Plus的配置
mybatis-plus可以在不配置xml和mapper的情况下进行数据存取(优于mybatis)
(只需要建一个空的mapper接口)
- Maven插件
velocity-engine-core是mybatis-plus自动生成代码所依赖的模板(不用自动生成代码功能可不用)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
- application.properties配置
和普通mysql配置相同,没有额外配置
#mysql 连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
- Mapper相关注解
@MapperScan中直接mapper文件所在的package
@SpringBootApplication
@EnableTransactionManagement
@EnableEurekaClient
@MapperScan("com.example.demo.dao")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 创建数据库表
略
- 创建JavaBean(推荐使用Lombok插件方式) - Model层
@Data
@TableName("area")
@ToString(callSuper=true, includeFieldNames=true)
@AllArgsConstructor
@NoArgsConstructor
public class Area implements Serializable{
private static final long serialVersionUID = 1L;
private String id;
private String name;
private int sort;
}
- 创建Mapper - DAO层
只有自定义SQL时,mapper中才有内容, 使用mybatis-plus自带CRUD语句或者构造器拼接语句时, mapper通常为空
public interface AreaMapper extends BaseMapper<Area> {
//通过mybatis-plus提供的注解,直接自定义SQL
@Select("select name from area where sort > ${sort}")
List<String> getBySort2(@Param("sort")int sort);
}
- 创建逻辑接口 - Service层
public interface IAreaService {
public Area getById(String id);
public List<Area> selectAll();
public int updateByPrimaryKeySelective(Area record);
public int deleteByPrimaryKey(String id);
public int insertSelective(Area record);
public List<Area> getBySort();
public List<String> getBySort2(int sort);
}
- 创建逻辑类 - Service层
Mybatis-Plus使用SQL的3种常见方法:
a. 使用mybatis-plus自带CRUD方法: 直接用mapper的自带方法
b. 使用mybatis-plus提供的条件构造器,拼接where条件
c. 使用@Select,@Update等注解, 自己写SQL+参数
@Service
public class AreaServiceImpl implements IAreaService {
@Autowired
public AreaMapper areaMapper;
//使用mybatis-plus自带CRUD方法
@Override
public Area getById(String id) {
return areaMapper.selectById(id);
}
@Override
public List<Area> selectAll() {
return areaMapper.selectList(null);
}
@Override
@Transactional
public int updateByPrimaryKeySelective(Area record) {
return areaMapper.updateById(record);
}
@Override
public int deleteByPrimaryKey(String id) {
return areaMapper.deleteById(id);
}
@Override
public int insertSelective(Area record) {
return areaMapper.insert(record);
}
//使用mybatis-plus提供的条件构造器,拼接条件
@Override
public List<Area> getBySort(){
QueryWrapper<Area> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().gt(Area::getSort, 40)
.lt(Area::getSort, 80);
return areaMapper.selectList(queryWrapper);
}
//通过mybatis-plus提供的注解,直接自定义SQL(定义在mapper中)
@Override
public List<String> getBySort2(int sort){
return areaMapper.getBySort2(sort);
}
}
- 创建接口 - Controller层
@RestController
@RequestMapping("/area")
public class AreaController {
@Autowired
private IAreaService areaService;
@Autowired
private DbpropertiesService dbproService;
@Autowired
private Area area;
@Resource
protected HttpServletRequest request;
@RequestMapping(value = "/getAreaInfo",method=RequestMethod.GET)
public Area getAreaInfo(@RequestParam(value="id") String id) {
area = areaService.getById(id);
return area;
}
@RequestMapping(value = "/getAreaAllInfo",method=RequestMethod.GET)
public List<Area> getAreaInfo() {
List<Area> arlist = areaService.selectAll();
return arlist;
}
@RequestMapping(value ="/updateAreaName",method=RequestMethod.PUT)
public int updateAreaInfo(@RequestParam(value="id") String id,@RequestParam(value="name",required=false) String name,@RequestParam(value="sort",required=false) Integer sort) {
area.setId(id);
area.setName(name);
area.setSort(sort);
int ar = areaService.updateByPrimaryKeySelective(area);
return ar;
}
@RequestMapping(value ="/deleteAreaName",method=RequestMethod.DELETE)
public int deleteAreaInfo(@RequestParam(value="id") String id) {
int ar = areaService.deleteByPrimaryKey(id);
return ar;
}
// @RequestMapping(value ="/insertAreaName",method=RequestMethod.POST)
// public int insertAreaInfo(@RequestParam(value="id") String id,@RequestParam(value="name",required=false) String name,@RequestParam(value="sort",required=false) Integer sort) {
// area.setId(id);
// area.setName(name);
// area.setSort(sort);
// int ar = areaService.insertSelective(area);
// return ar;
// }
@RequestMapping(value ="/insertAreaName",method=RequestMethod.POST)
public int insertAreaInfo(@RequestBody Area area) {
int ar = areaService.insertSelective(area);
return ar;
}
@RequestMapping(value ="/selectBySort",method=RequestMethod.GET)
public List<Area> selectAreaSort() {
List<Area> arList = areaService.getBySort();
return arList;
}
@RequestMapping(value ="/selectBySort2",method=RequestMethod.GET)
public List<String> selectAreaSort2(@RequestParam(value="sort") int sort) {
List<String> arList = areaService.getBySort2(sort);
return arList;
}
}
参考文档:
https://mp.baomidou.com/
多数据源插件
1. 默认用法
导入maven包
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-datasource.version}</version>
</dependency>
理论上应用需要一个主数据源, 多个副数据源, 全部写在properties文件中即可
automation就是默认连接的数据库,
其他3个就是副数据源.
#mysql 连接配置
spring.datasource.dynamic.primary=automation
spring.datasource.dynamic.datasource.automation.url=jdbc:mysql://172.25.4.235:3306/test_team?useSSL=false&serverTimezone=UTC
spring.datasource.dynamic.datasource.automation.username=j_test_team
spring.datasource.dynamic.datasource.automation.password=ys4TEDlrLARv
spring.datasource.dynamic.datasource.DRW.url=jdbc:mysql://172.25.4.205:3306/kf_darwin_auto_test?useSSL=false&serverTimezone=UTC
spring.datasource.dynamic.datasource.DRW.username=j_kf_darwin_wejb
spring.datasource.dynamic.datasource.DRW.password=YpM0ye7ruvoq
spring.datasource.dynamic.datasource.AUTHORITY.url=jdbc:mysql://172.25.4.205:3306/kf_authority?useSSL=false&serverTimezone=UTC
spring.datasource.dynamic.datasource.AUTHORITY.username=j_kf_authority
spring.datasource.dynamic.datasource.AUTHORITY.password=UgHzdODLu3To
spring.datasource.dynamic.datasource.IKBS.url=jdbc:mysql://172.25.4.214:3306/ikbs?useSSL=false&serverTimezone=UTC
spring.datasource.dynamic.datasource.IKBS.username=j_ikbs
spring.datasource.dynamic.datasource.IKBS.password=9PSAqLG4v7oh
使用: 在mapper文件中
// @DS是mybatis plus的多数据源注解, 使得不同方法可以访问不同的数据库
//使用默认数据库
@Select("${sql}")
List<JSONObject> executeSql_master(@Param("sql")String sql);
//使用指定数据库
@Select("${sql}")
@DS("IKBS")
List<JSONObject> executeSql_slave(@Param("sql")String sql);
2. 不使用properties
如果将所有数据库连接信息写在properties中, 如果在应用运行时,需要对数据库连接信息进行增删改查, 就需要重启应用, 为了增加灵活性, 我们可以将所有副数据库信息加入数据库中管理.
package com.project.automationplatform.configuration;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.project.automationplatform.dao.TestCaseAppManageMapper;
import com.project.automationplatform.model.TestCaseAppManage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.List;
/*
mybatis-plus多数据源的副数据库地址开始配置在application.properties中, 但为了在增加,修改,删除数据库连接信息时,
不需要修改代码,重启应用, 故将所有数据库连接信息储存于application表中, 在本连接类中启动应用时实时加入数据源列表
*/
@Configuration
public class DatasourceConfig implements BeanPostProcessor {
Logger logger = LoggerFactory.getLogger(getClass());
@Resource
private TestCaseAppManageMapper testCaseAppManageMapper;
//动态数据源
@Autowired
private DataSource dataSource;
@Resource
private DataSourceCreator dataSourceCreator;
@Bean
public void createNewDataSource(){
DynamicRoutingDataSource drds = (DynamicRoutingDataSource) dataSource;
QueryWrapper<TestCaseAppManage> wrapper = Wrappers.query();
wrapper.lambda().eq(TestCaseAppManage::getStatus, 1);
//获取application表中储存的数据库地址,用户名和密码列表
List<TestCaseAppManage> allApp = testCaseAppManageMapper.selectList(wrapper);
for(TestCaseAppManage app:allApp){
if (null != app.getAppDbUrl()){
DataSourceProperty dsp = new DataSourceProperty();
dsp.setPollName(app.getAppCode());//链接池名称
dsp.setUrl(app.getAppDbUrl());//数据库连接
dsp.setUsername(app.getAppDbUserName());//用户名
dsp.setPassword(app.getAppDbPassWord());//密码
//dsp.setDriverClassName(driverClassName);//驱动
//创建数据源并添加到系统中管理
DataSource dataSource = dataSourceCreator.createDataSource(dsp);
drds.addDataSource(app.getAppCode(), dataSource);
}
}
logger.info("已加入列表的多数据源drds: " + drds.getCurrentDataSources());
//return drds;
}
}
使用:
//执行'数据库查询SQL'中的SQL
@Override
public List<JSONObject> executeSql(String sql,String app){
//为了避免一个线程在跑A应用的数据库SQL时,另一个线程B想要跑B应用的数据库SQL, 产生并发问题,
//故加上排它锁
Lock thisLock = new ReentrantLock();
List<JSONObject> result = new ArrayList<JSONObject>();
thisLock.lock();
try{
DynamicDataSourceContextHolder.push(app);//数据源名称
result = testCaseTemplateMapper.executeSql_slave(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
DynamicDataSourceContextHolder.poll();
thisLock.unlock();
}
return result;
}
数据源datasource
数据源是数据库连接的规范接口
Springboot默认支持4种数据源类型,定义在 org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 中,分别是:
org.apache.tomcat.jdbc.pool.DataSource
com.zaxxer.hikari.HikariDataSource
org.apache.commons.dbcp.BasicDataSource
org.apache.commons.dbcp2.BasicDataSource
在不指定数据源类型时, SpringBoot默认使用tomcat.jdbc
如果需要使用第三方数据源, 比如Druid, 步骤如下:
Druid的配置
- Maven配置
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.3</version>
</dependency>
- application.properties配置
spring.datasource.type需要指定为Druid
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
其他的Druid自有属性,可以写在properties中也可以写在Druid的配置类中
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidConfiguration {
private String url;
private String username;
private String password;
private String driverClassName;
private int initialSize = 5;
private int minIdle = 5;
private int maxActive = 10;
private int maxWait = 2;
private int timeBetweenEvictionRunsMillis = 1000 * 60;
private int minEvictableIdleTimeMillis = 1000 * 60 * 30;
private String validationQuery;
private boolean testWhileIdle = false;
private boolean testOnBorrow = true;
private boolean testOnReturn = false;
private boolean poolPreparedStatements = false;
private int maxPoolPreparedStatementPerConnectionSize = -1;
private String filters;
private boolean useGlobalDataSourceStat = false;
private String connectionProperties;
- 定义数据源
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSource2Config {
private String url;
private String username;
private String password;
@Bean
public DataSource getDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);// 用户名
dataSource.setPassword(password);// 密码
return dataSource;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- 配置Druid的监控器和为事务管理器指定Druid数据源, 最终Configuration文件如下:
Druid监控配置:
ServletRegistrationBean
FilterRegistrationBean
事务管理器配置:
PlatformTransactionManager
package com.example.demo.dao.druid;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
@Configuration
public class DruidConfiguration {
@Bean
public ServletRegistrationBean druidServlet() {
//logger.info("init Druid Servlet Configuration ");
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(new StatViewServlet());
servletRegistrationBean.addUrlMappings("/druid/*");
Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("loginUsername", "admin");
initParameters.put("loginPassword", "admin");
initParameters.put("resetEnable", "false");
initParameters.put("allow", "");
initParameters.put("deny", "");
servletRegistrationBean.setInitParameters(initParameters);
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
@Bean
@Primary
public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
//Druid配置Bean
@Component
@ConfigurationProperties(prefix = "spring.datasource")
class DruidDataSourceProperties {
private String url;
private String username;
private String password;
private String driverClassName;
private int initialSize = 5;
private int minIdle = 5;
private int maxActive = 10;
private int maxWait = 2;
private int timeBetweenEvictionRunsMillis = 1000 * 60;
private int minEvictableIdleTimeMillis = 1000 * 60 * 30;
private String validationQuery;
private boolean testWhileIdle = false;
private boolean testOnBorrow = true;
private boolean testOnReturn = false;
private boolean poolPreparedStatements = false;
private int maxPoolPreparedStatementPerConnectionSize = -1;
private String filters = "stat";
private boolean useGlobalDataSourceStat = false;
private String connectionProperties;
@Bean //声明其为Bean实例,将数据源设置为druid
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
System.err.println("druid configuration initialization filter: " + e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public boolean isUseGlobalDataSourceStat() {
return useGlobalDataSourceStat;
}
public void setUseGlobalDataSourceStat(boolean useGlobalDataSourceStat) {
this.useGlobalDataSourceStat = useGlobalDataSourceStat;
}
public String getConnectionProperties() {
return connectionProperties;
}
public void setConnectionProperties(String connectionProperties) {
this.connectionProperties = connectionProperties;
}
}
- Druid性能监控台
http://localhost:8092/druid/index.html
本文介绍了如何在项目中配置MyBatis-Plus,包括无需XML配置的简单使用,Maven插件设置,以及如何在application.properties中配置数据源。此外,还详细讲解了多数据源插件的两种用法,一种是在properties文件中配置,另一种是动态管理数据库连接。最后,文章提到了Druid数据源的配置,包括Maven依赖、properties配置和监控器设置。
2191

被折叠的 条评论
为什么被折叠?



