SpringBoot2.x整合MybatisPlus3.x,实现数据的简单CRUD操作+****代码生成
程序员文章站
2022-07-13 10:51:22
...
一、项目地址
GitHub地址:https://github.com/kobeyk/springboot-myabatis-plus-sample.git
二、项目结构
三、Pom整合
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.appleyk</groupId>
<artifactId>springboot-mybatisplus-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>springboot-mybatisplus-sample</name>
<description>SpringBoot集成MybatisPlus实现单表增删改查的例子</description>
<properties>
<java.version>1.8</java.version>
<jdk.version>1.8</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<jackson.version>2.9.8</jackson.version>
<postgresql.version>42.1.4</postgresql.version>
<mybatisplus.version>3.2.0</mybatisplus.version>
<velocity.version>1.7</velocity.version>
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--这玩意虽然省事,但是有利有弊吧,注意idea要安装对应的插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!-- postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
<!--一定要有这个玩意,模板,否则mybatisplus****生成代码找不到模板-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
四、application.properties配置
server.port=8080
logging.level.com.appleyk.dao.mapper = debug
#hikari
spring.datasource.hikari.driver-class-name=org.postgresql.Driver
spring.datasource.hikari.jdbc-url=jdbc:postgresql://localhost:5432/injection_db?stringtype=unspecified
spring.datasource.hikari.username=postgres
spring.datasource.hikari.password=postgres
spring.datasource.templateType=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
五、自定义数据源,注入相应bean
package com.appleyk.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
* <p>自定义数据源配置</p>
*
* @author Appleyk
* @version V.0.1.1
* @blob https://blog.****.net/Appleyk
* @date created on 14:01 2020/2/26
*/
@EnableTransactionManagement
@MapperScan(value = {"com.appleyk.dao.mapper"}, sqlSessionTemplateRef = "sqlSessionTemplate")
@Configuration
public class TDataSourceConfig {
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.datasource.hikari") //需要导入配置
public HikariDataSource dataSource(){
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource,@Qualifier("paginationInterceptor") PaginationInterceptor paginationInterceptor) throws Exception {
/**坑1:注意这里一定要是MybatisPlus的MybatisSqlxxBean,而不是正常的SqlXXBean,否者会出现statement绑定无效*/
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
/**坑2:注意,一定要设置 MyBatis-Plus的分页插件,否者分页结果无效*/
Interceptor[] plugins = {paginationInterceptor};
bean.setPlugins(plugins);
return bean.getObject();
}
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意坑1: 如果配置成了SqlSessionFactoryBean,会提示
{
"timestamp": 1582787261756,
"status": 500,
"error": "Internal Server Error",
"message": "Invalid bound statement (not found): com.appleyk.dao.mapper.TUserMapper.selectPage",
"path": "/user/query"
}
注意坑2: 如果没有为MybatisPlus设置分页插件,则基于分页查询的结果会有问题
六、MybatisPlus****生产代码
package com.appleyk.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
/**
* <p>
*
* 自动代码生成器(myabtisplus****),本项目中controller、service、dao均是自动生成的
* 注意: 由于代码已经生成,但是配置里面设置的重新生成会覆盖之前的文件,因此,博主已经把它改成false了
* .setFileOverride(true) ====》 .setFileOverride(false)
*
* </p>
*
* @author Appleyk
* @version V.0.1.1
* @blob https://blog.****.net/Appleyk
* @date created on 14:01 2020/2/26
*/
public class TCodeGenerator {
/**项目存储位置*/
public static String PROJECT_GENERATE_DISK = System.getProperty("user.dir")+"/src/main/java";
/**数据库地址*/
public static String DB_URL = "jdbc:postgresql://localhost:5432/injection_db?stringtype=unspecified";
/**数据库驱动名*/
public static String DRIVER_CLASS_NAME = "org.postgresql.Driver";
/**数据库类型*/
public static String DB_TYPE = DbType.POSTGRE_SQL.name();
/**数据库用户*/
public static String USER = "postgres";
/**数据库密码*/
public static String PASSWORD = "postgres";
/**参与****的表名**/
public static String[] INCLUDE_TABLE_NAMES = new String[]{"t_user","t_user_info"};
/**不参与****的表名**/
public static String[] EXCLUDE_TABLE_NAMES = new String[]{"spatial_ref_sys"};
/**创建人*/
public static String AUTHOR = "Appleyk";
/**表字段生成对应的实体类时,字段属性是否需要强制带上注解*/
public static boolean ENABLE_TABLE_FIELD_ANNOTATION = false;
/**表id,用哪一种生成策略,如下面用的是分布式全局唯一ID,是不是分布式暂时没考就哈*/
public static IdType TABLE_ID_TYPE = IdType.ID_WORKER;
/**是否去掉生成实体的属性名前缀,如表有t_table1,m_table2,则这个值可以为 = new String[]{"t","m"}*/
public static String[] FIELD_PREFIX = null;
/**
* 全局配置
* @return
*/
private static GlobalConfig GlobalGenerate(){
GlobalConfig config = new GlobalConfig();
/*不需要ActiveRecord特性的请改为false*/
config.setActiveRecord(false)
.setIdType(TABLE_ID_TYPE)
/*是否启用二级缓存*/
.setEnableCache(false)
/*设置作者*/
.setAuthor(AUTHOR)
/*生成完之后,不弹窗,告知我在生成在哪个目录了*/
.setOpen(false)
/*XML 设置映射结果 ResultMap*/
.setBaseResultMap(true)
/*XML 设置表列 ColumnList*/
.setBaseColumnList(true)
/*设置生产的文件(包)在哪,一般是相对于本项目而言*/
.setOutputDir(PROJECT_GENERATE_DISK)
/*每次生成,是否覆盖之前的文件(慎重考虑啊)*/
.setFileOverride(false)
/*自定义文件命名,注意 %s 会自动填充表实体属性!*/
.setControllerName("%sController")
.setServiceName("%sService")
.setServiceImplName("%sServiceImpl")
.setMapperName("%sMapper")
.setXmlName("%sMapper");
return config;
}
/**
* 数据源配置
* @return
*/
private static DataSourceConfig DaoSourceGenerate(){
DataSourceConfig dataSourceConfig = new DataSourceConfig();
DbType type=null;
if("oracle".equals(DB_TYPE)){
type=DbType.ORACLE;
}else if("sql_server".equals(DB_TYPE)){
type=DbType.SQL_SERVER;
}else if("mysql".equals(DB_TYPE)){
type=DbType.MYSQL;
}else if("postgre_sql".equals(DB_TYPE)){
type=DbType.POSTGRE_SQL;
}
/*设置数据库类型*/
dataSourceConfig.setDbType(type)
/*设置数据库驱动(反射,基于类名,找到对应的类)*/
.setDriverName(TCodeGenerator.DRIVER_CLASS_NAME)
/*设置数据库连接地址,地址包含库ip、端口、库名等*/
.setUrl(DB_URL)
/*设置数据库用户名*/
.setUsername(TCodeGenerator.USER)
/*设置数据库密码*/
.setPassword(TCodeGenerator.PASSWORD);
return dataSourceConfig;
}
/**
* 策略配置
* @return
*/
private static StrategyConfig StrategyGenerate() {
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig
.setVersionFieldName("version")
/*全局大写命名 ORACLE 注意*/
.setCapitalMode(true)
/*生成RestController*/
.setRestControllerStyle(true)
/*是否使用Lombok省略getter、setter*/
.setEntityLombokModel(false)
// .setDbColumnUnderline(true)
/*表名生成策略 -- 驼峰*/
.setNaming(NamingStrategy.underline_to_camel)
.setEntityTableFieldAnnotationEnable(ENABLE_TABLE_FIELD_ANNOTATION)
/* 生成指定的xxxController、、xxService等是否去掉数据库表名的前缀,如t_user -> user -> UserController*/
.setFieldPrefix(FIELD_PREFIX)
/*设置哪些表参与****,多个表名传数组*/
.setInclude(INCLUDE_TABLE_NAMES)
/*设置哪些表不参与****,多个表名传数组;注意,不能和Include一起使用*/
// .setExclude(EXCLUDE_TABLE_NAMES)
/*此处可以修改为您的表前缀*/
.setTablePrefix(null)
/*自定义实体,公共字段*/
.setSuperEntityColumns(null)
/*自定义 mapper 父类*/
.setSuperMapperClass(null)
/*自定义 service 父类*/
.setSuperServiceClass(null)
/*自定义 serviceImpl 父类*/
.setSuperServiceImplClass(null)
/*自定义 controller 父类*/
.setSuperControllerClass(null)
/*【实体】是否生成字段常量(默认 false)public static final String ID = "test_id";*/
.setEntityColumnConstant(false)//
/*【实体】是否为构建者模型(默认 false)public User setName(String name) {this.name = name; return this;}*/
.setEntityBuilderModel(false)
/*【实体】是否为lombok模型(默认 false)*/
.setEntityLombokModel(false)
/*Boolean类型字段是否移除is前缀处理*/
.setEntityBooleanColumnRemoveIsPrefix(true);
return strategyConfig;
}
/**
* 自定义模板配置
* @return
*/
private static TemplateConfig TemplateGenerate(){
TemplateConfig templateConfig = new TemplateConfig()
.setController("/templates/controller.java")
.setMapper("/templates/mapper.java")
.setXml("/templates/mapper.xml")
.setService("/templates/service.java")
.setServiceImpl("/templates/serviceImpl.java");
return templateConfig;
}
public static PackageConfig PackageGenerate(){
PackageConfig pc = new PackageConfig()
.setParent("com.appleyk")
.setController("controller")
.setService("service")
.setServiceImpl("service.impl")
.setEntity("dao.entity")
.setMapper("dao.mapper")
.setXml("dao.mapper");
return pc;
}
public void generateByTablesWithInjectConfig() {
//全局配置
GlobalConfig config =TCodeGenerator.GlobalGenerate();
//配置数据源
DataSourceConfig dataSourceConfig=TCodeGenerator.DaoSourceGenerate();
//配置策略
StrategyConfig strategyConfig = TCodeGenerator.StrategyGenerate();
//配置包
PackageConfig packageConfig=TCodeGenerator.PackageGenerate();
//生成代码
new AutoGenerator()
.setGlobalConfig(config)
.setDataSource(dataSourceConfig)
.setStrategy(strategyConfig)
.setPackageInfo(packageConfig)
.execute();
}
public static void main(String[] args) {
TCodeGenerator generatorServiceEntity=new TCodeGenerator();
generatorServiceEntity.generateByTablesWithInjectConfig();
}
}
七、分页查询演示
项目启动:
Service:
@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements TUserService {
@Autowired
private TUserMapper userMapper;
@Override
public IPage<TUser> find(){
Page<TUser> page = new Page<>(1,20);
return userMapper.selectPage(page,null);
}
}
Mapper:
public interface TUserMapper extends BaseMapper<TUser> {
}
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.appleyk.dao.mapper.TUserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.appleyk.dao.entity.TUser">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="password" property="password" />
<result column="create_time" property="createTime" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, name, password, create_time
</sql>
</mapper>
Controller:
@RestController
@RequestMapping("/user")
public class TUserController {
@Autowired
private TUserService userService;
/**
* 分页查询
* @return
*/
@GetMapping("/query")
public TResult query(){
return TResult.ok(userService.find());
}
}
PostMan测试:
{
"status": 200,
"message": "成功!",
"data": {
"records": [
{
"id": "111",
"name": "appelyk",
"password": "11111",
"createTime": 1582791338107
},
{
"id": "1232679405023793154",
"name": "appelyk",
"password": "123456a",
"createTime": 1582791338108
},
{
"id": "1232680020835762177",
"name": "appelyk",
"password": "123456a",
"createTime": 1582791338108
},
{
"id": "1232680432896749569",
"name": "appelyk",
"password": "123456a",
"createTime": 1582646400000
},
{
"id": "1232680817808056322",
"name": "appelyk",
"password": "123456a",
"createTime": 1582646400000
},
{
"id": "1232681928061243393",
"name": "appelyk",
"password": "123456a",
"createTime": 1582646400000
},
{
"id": "1232684931182948354",
"name": "kobe",
"password": "123456a",
"createTime": 1582646400000
},
{
"id": "1232687920962592770",
"name": "kobe",
"password": "123456a",
"createTime": 1582646400000
}
],
"total": "8",
"size": "20",
"current": "1",
"orders": [],
"searchCount": true,
"pages": "1"
},
"timeStamp": "2020-02-27 16:15:38"
}
八,****演示
(1)数据库增加一张表,t_test,字段如下
(2)代码中,include_tables中加上这个表的名称
(3)执行
(4)验证生成的文件是否存在
(5)我们看下,自动生成的mapper默认都具有哪些数据操作方法
(6)我们看下,自动生成的service默认都具有哪些数据操作方法
九,小结
至于MybatisPlus是否足够出色,还需要我们研发人员在用的过程中,不断的去体验,去感受!