Springboot整合Mybatis-plus框架
Springboot项目-mybatis-plus框架
[TOC]
mybatis-plus版本说明
Springboot+mybatis-puls整合参考链接:
https://www.jianshu.com/p/5e4218d47578
https://blog.csdn.net/qq_36067600/article/details/94646559
【1】springboot 2.2.6整合MyBatis-Plus2.2.0
a.整合配置
pom.xml配置
<?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>
<groupId>com.sz</groupId>
<artifactId>boxing</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 设置打包方式未war,未指定则为jar -->
<packaging>war</packaging>
<name>boxing</name>
<description>boxing</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>2.2.6.RELEASE</spring.boot.version>
<spring.boot.mybatis.plus.version>2.2.0</spring.boot.mybatis.plus.version>
<java.version>1.8</java.version>
<druid.version>1.1.22</druid.version>
<mysql.version>5.1.47</mysql.version>
<oracle.version>11.2.0.3</oracle.version>
<fastjson.version>1.2.70</fastjson.version>
<velocity.engine.core.version>2.1</velocity.engine.core.version>
<lombok.version>1.18.12</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
-->
<!--devtools热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring.boot.version}</version>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
<!-- springboot整合springMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- springboot整合aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- springboot整合mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${spring.boot.mybatis.plus.version}</version>
</dependency>
<!-- mybatis-plus 生成器需要依赖freemarker -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.engine.core.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- 传统引入数据库连接相关jar -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- mysql相关jar -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- Oracle(ojdbc)相关jar -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<!-- 引入JSON格式处理相关jar -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 代码生成 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<!--<scope>provided</scope>-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--解决vue部署在linux的tomcat下页面数据无法加载的问题-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>woff</nonFilteredFileExtension>
<nonFilteredFileExtension>woff2</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
</project>
yml整合配置
# mybatis config
mybatis-plus:
# mapper-locations: classpath*:mapper/**/*Mapper.xml
mapper-locations: classpath*:mapper/**/*Mapper.xml
type-aliases-package: com.sz.**.model
global-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: 3
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 2
#驼峰下划线转换 column-underline
db-column-underline: true
#刷新mapper 调试神器
refresh-mapper: true
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
#key-generator: com.baomidou.springboot.xxx
#逻辑删除配置(下面3个配置)
sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
logic-not-delete-value: 0
logic-delete-value: 1
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
# 打印sql执行语句
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
b.代码生成器
参考1:SimpleMpGenerator
public class SimpleMpGenerator {
public static void main(String[] args) {
//1. 全局配置
GlobalConfig config = new GlobalConfig();
//是否支持AR模式
config.setActiveRecord(true)
.setAuthor("") //作者
.setOutputDir("D://workspace/spring-boot-mybatis/src/main/java") //生成路径
.setFileOverride(true)//是否文件覆盖,如果多次
.setServiceName("%sService") //设置生成的service接口名首字母是否为I
.setIdType(IdType.AUTO) //主键策略
.setServiceName("%sService")//设置生成的service接口的名字的首字母是否为I
.setBaseResultMap(true)
.setBaseColumnList(true);
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
dsConfig.setDbType(DbType.MYSQL)
.setUrl("jdbc:mysql://localhost:3306/eoas-local?useUnicode=true&characterEncoding=utf8")
.setDriverName("com.mysql.jdbc.Driver")
.setUsername("root")
.setPassword("root");
//3.策略配置
StrategyConfig stConfig = new StrategyConfig();
stConfig.setCapitalMode(true) // 全局大写命名
.setDbColumnUnderline(true) //表名 字段名 是否使用下滑线命名
.setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
.setInclude("user_info") //生成的表
.setTablePrefix("tbl_"); // 表前缀
//4.包名策略
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent("com.sz.mip.system")//父包名
.setController("controller")
.setEntity("beans")
.setService("service")
.setMapper("mapper")
.setXml("mapper");
//5.整合配置
AutoGenerator ag = new AutoGenerator().setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig);
ag.execute();
}
}
参考2:MySqlCodeGenerator
public class MySqlCodeGenerator {
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// 选择 freemarker 引擎,默认 Veloctiy
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setAuthor("");
gc.setOutputDir("D://workspace/mp-mysql-code/src/main/java");
// 是否覆盖同名文件,默认是false
gc.setFileOverride(true);
// 不需要ActiveRecord特性的请改为false
gc.setActiveRecord(true);
// XML 二级缓存
gc.setEnableCache(false);
// XML ResultMap
gc.setBaseResultMap(true);
// XML columList
gc.setBaseColumnList(true);
/* 自定义文件命名,注意 %s 会自动填充表实体属性! */
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert() {
// 自定义数据库表字段类型转换【可选】
@Override
public DbColumnType processTypeConvert(String fieldType) {
System.out.println("转换类型:" + fieldType);
// processTypeConvert存在默认类型转换,可结合实际开发需求自定义实现返回
return super.processTypeConvert(fieldType);
}
});
// mysql数据库
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setUrl("jdbc:mysql://localhost:3306/mip-local?useUnicode=true&characterEncoding=utf8");
mpg.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
// 此处可以修改为您的表前缀
strategy.setTablePrefix(new String[]{"mip_", "eoas_"});
//表名 字段名 是否使用下滑线命名
strategy.setDbColumnUnderline(false);
// 表名生成策略(数据库表映射到实体的命名策略)(nochange 无改变)
strategy.setNaming(NamingStrategy.underline_to_camel);
// 需要生成的表
// strategy.setInclude(new String[]{"mip_user","mip_role"});
strategy.setInclude(new String[]{"mip_user"});
// 排除生成的表
// strategy.setExclude(new String[]{"test"});
// 自定义实体父类
// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
// 自定义实体,公共字段
// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
// 自定义 mapper 父类
// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
// 自定义 service 父类
// strategy.setSuperServiceClass("com.baomidou.demo.TestService");
// 自定义 service 实现类父类
// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
// 自定义 controller 父类
// strategy.setSuperControllerClass("com.baomidou.demo.TestController");
// 【实体】是否生成字段常量(默认 false)
// public static final String ID = "test_id";
// strategy.setEntityColumnConstant(true);
// 【实体】是否为构建者模型(默认 false)
// public User setName(String name) {this.name = name; return this;}
// strategy.setEntityBuilderModel(true);
mpg.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.sz.mip.framework.rest");
// pc.setModuleName("test");
pc.setController("controller");
pc.setEntity("model");
pc.setService("service");
pc.setMapper("mapper");
pc.setXml("mapper.xml");
mpg.setPackageInfo(pc);
// 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
// InjectionConfig cfg = new InjectionConfig() {
// @Override
// public void initMap() {
// Map<String, Object> map = new HashMap<String, Object>();
// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
// this.setMap(map);
// }
// };
//
// // 自定义 xxList.jsp 生成
// List<FileOutConfig> focList = new ArrayList<>();
// focList.add(new FileOutConfig("/template/list.jsp.vm") {
// @Override
// public String outputFile(TableInfo tableInfo) {
// // 自定义输入文件名称
// return "D://my_" + tableInfo.getEntityName() + ".jsp";
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 调整 xml 生成目录演示
// focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
// @Override
// public String outputFile(TableInfo tableInfo) {
// return "/develop/code/xml/" + tableInfo.getEntityName() + ".xml";
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 关闭默认 xml 生成,调整生成 至 根目录
// TemplateConfig tc = new TemplateConfig();
// tc.setXml(null);
// mpg.setTemplate(tc);
// 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,
// 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称
// TemplateConfig tc = new TemplateConfig();
// tc.setController("...");
// tc.setEntity("...");
// tc.setMapper("...");
// tc.setXml("...");
// tc.setService("...");
// tc.setServiceImpl("...");
// 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
// mpg.setTemplate(tc);
// 执行生成
mpg.execute();
// 打印注入设置【可无】
// System.err.println(mpg.getCfg().getMap().get("abc"));
}
}
参考3:OracleCodeGenerator
public class OracleCodeGenerator {
/**
* <p>
* MySQL 生成演示
* </p>
*/
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// 选择 freemarker 引擎,默认 Veloctiy
// mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setAuthor("");
gc.setOutputDir("E:/dev-haha/workspace/mp-oracle-code/src/main/java");
// 是否覆盖同名文件,默认是false
gc.setFileOverride(true);
// 不需要ActiveRecord特性的请改为false
gc.setActiveRecord(true);
// XML 二级缓存
gc.setEnableCache(false);
// XML ResultMap
gc.setBaseResultMap(true);
// XML columList
gc.setBaseColumnList(true);
/* 自定义文件命名,注意 %s 会自动填充表实体属性! */
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");
mpg.setGlobalConfig(gc);
// oracle数据库-数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.ORACLE);
dsc.setTypeConvert(new OracleTypeConvert() {
// 自定义数据库表字段类型转换
@Override
public DbColumnType processTypeConvert(String fieldType) {
return super.processTypeConvert(fieldType);
}
});
dsc.setDriverName("oracle.jdbc.driver.OracleDriver");
dsc.setUsername("CCB-WORK");
dsc.setPassword("123456");
dsc.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:orcl");
mpg.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
// 此处可以修改为您的表前缀
strategy.setTablePrefix(new String[]{"CFA","BOXING_PARAM"});
//表名 字段名 是否使用下滑线命名
strategy.setDbColumnUnderline(false);
// 表名生成策略(数据库表映射到实体的命名策略)(nochange 无改变)
strategy.setNaming(NamingStrategy.underline_to_camel);
// 需要生成的表
// strategy.setInclude(new String[]{"CFA_ADMIN","CFA_AUTHORITY});
strategy.setInclude(new String[]{"BOXING_PARAM_BRANCH"});
// 排除生成的表
// strategy.setExclude(new String[]{"test"});
mpg.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
// pc.setParent("com.sz.mip.framework.rest");
pc.setParent("com.sz.boxing");
// pc.setModuleName("test");
pc.setController("controller");
pc.setEntity("model");
pc.setService("service");
pc.setMapper("mapper");
pc.setXml("mapper.xml");
mpg.setPackageInfo(pc);
// 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
// InjectionConfig cfg = new InjectionConfig() {
// @Override
// public void initMap() {
// Map<String, Object> map = new HashMap<String, Object>();
// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
// this.setMap(map);
// }
// };
// mpg.setCfg(cfg);
// 执行生成
mpg.execute();
// 打印注入设置【可无】
// System.err.println(mpg.getCfg().getMap().get("abc"));
}
}
c.使用说明
注意实体:
【2】springboot 2.2.6整合MyBatis-Plus3.3.2
MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:
a.整合配置
pom.xml配置
<?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>
<groupId>com.sz</groupId>
<artifactId>szwh</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>szwh</name>
<description>数字外呼一体化平台开发</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>2.2.6.RELEASE</spring.boot.version>
<!-- 原2.2.0版本不需要依赖mybatis.plus.generator -->
<spring.boot.mybatis.plus.version>3.3.2</spring.boot.mybatis.plus.version>
<mybatis.plus.generator.version>3.3.2</mybatis.plus.generator.version>
<java.version>1.8</java.version>
<junit.version>3.8.1</junit.version>
<druid.version>1.1.22</druid.version>
<mysql.version>5.1.47</mysql.version>
<oracle.version>11.2.0.3</oracle.version>
<fastjson.version>1.2.70</fastjson.version>
<!--<jackson.version>2.11.0</jackson.version>-->
<velocity.engine.core.version>2.1</velocity.engine.core.version>
<junit.version>4.13</junit.version>
<lombok.version>1.18.12</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
-->
<!--devtools热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring.boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- springboot整合springMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- springboot整合aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- springboot整合mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${spring.boot.mybatis.plus.version}</version>
</dependency>
<!-- mybatisPlus 代码生成器 3.0.3之后的MP版本依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis.plus.generator.version}</version>
</dependency>
<!-- mybatis-plus 生成器需要依赖freemarker -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.engine.core.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- 传统引入数据库连接相关jar -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- mysql相关jar -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- Oracle(ojdbc)相关jar -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<!-- 引入JSON格式处理相关jar -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
-->
<!-- 单元测试相关 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<!--<scope>test</scope>-->
</dependency>
<!-- 日志打印相关(flowable) -->
<!--
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
-->
<!-- 代码生成 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<!--<scope>provided</scope>-->
</dependency>
</dependencies>
<build>
<finalName>szwh</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--解决vue部署在linux的tomcat下页面数据无法加载的问题-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>woff</nonFilteredFileExtension>
<nonFilteredFileExtension>woff2</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
</project>
yml整合配置
# mybatis config
mybatis-plus:
# MP-Mapper所对应的XML文件位置
mapper-locations: classpath*:mapper/**/*Mapper.xml
# MP-别名包扫描路径,通过该属性可以给包中的类注册别名 实体扫描,多个package用逗号或者分号分隔
type-aliases-package: com.sz.mip.**.model
# MP-配置扫描通用枚举 # 支持统配符 * 或者 ; 分割
# type-enums-package: com.abbottliu.sys.enums,com.abbottliu.enums
# 启动时是否检查XML文件的存在,默认不检查
check-config-location: false
# ExecutorType.SIMPLE:该执行器类型不做特殊的事情,为每个语句的执行创建一个新的预处理语句(PreparedStatement)
# ExecutorType.REUSE:该执行器类型会复用预处理语句(PreparedStatement)
# ExecutorType.BATCH:该执行器类型会批量执行所有的更新语句
executor-type: simple
configuration:
# 是否开启自动驼峰命名规则(camel case)映射
map-underscore-to-camel-case: true
# 配置JdbcTypeForNull, oracle数据库必须配置
jdbc-type-for-null: null
# 如果查询结果中包含空值的列,则MP在映射的时候不会映射这个字段
call-setters-on-nulls: true
# 打印sql执行语句(配置控制台打印完整带参数SQL语句) - 由子配置文件决定打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
#主键类型 auto:"数据库ID自增" 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: UUID
#字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断"
# field-strategy: NOT_EMPTY
# 数据库类型,默认值为未知的数据库类型
# db-type: MYSQL
# 逻辑删除配置
logic-delete-value: 1
logic-not-delete-value: 0
# 驼峰下划线转换
table-underline: true
banner: false
b.代码生成器
参考代码:CodeGenerator
public class CodeGenerator {
/**
* 读取控制台内容
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new BaseException("CodeGenerator","请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = "E:/dev-haha/workspace/fhyd";
// String projectPath = System.getProperty("user.dir"); 项目路径
gc.setOutputDir(projectPath + "/src/main/java")
.setFileOverride(true)// 是否覆盖文件
.setActiveRecord(true)// 开启 activeRecord 模式
.setEnableCache(false)// XML 二级缓存
.setBaseResultMap(true)// XML ResultMap
.setBaseColumnList(true)// XML columList
.setAuthor("");
/* 自定义文件命名,注意 %s 会自动填充表实体属性! */
gc.setMapperName("%sMapper")
.setXmlName("%sMapper")
.setServiceName("%sService")
.setServiceImplName("%sServiceImpl")
.setControllerName("%sController");
gc.setOpen(true);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置(Oracel)
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:orcl");
// dsc.setSchemaName("public");
dsc.setDriverName("oracle.jdbc.driver.OracleDriver");
dsc.setUsername("CCB-WORK");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.sz");
pc.setModuleName("fhyd");
pc.setEntity("model");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setMapper("mapper");
pc.setXml("mapper.xml");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义MAPPER.XML输出文件名,若Entity设置了前后缀、此处xml 的名称会跟着发生变化
// return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
return projectPath + "/src/main/resources/mapper/xml/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
/*
cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判断自定义文件夹是否需要创建
// checkDir("调用默认方法创建的目录,自定义目录用");
if (fileType == FileType.MAPPER) {
// 已经生成 mapper 文件判断存在,不想重新生成返回 false
return !new File(filePath).exists();
}
// 允许生成模板文件
return true;
}
});
*/
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// 表明、字段名生成策略配置:驼峰-下划线转化(数据库表映射到实体类的命名策略:no_change无改变)
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperEntityClass("父类实体,没有就不用设置!");
// 生成Lombok格式代码
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
// strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
// 写于父类中的公共字段
// strategy.setSuperEntityColumns("id");
// 需要生成代码的表
strategy.setInclude(new String[]{"FHYD_ENTERPRISE"});
// strategy.setControllerMappingHyphenStyle(true);
// 表名前缀配置(如果配置了表名前缀)
strategy.setTablePrefix(new String[]{"FHYD"});
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
c.使用说明
【3】mp版本升级注意问题
MP版本升级注意事项:
【1】引用JAR路径
实体类注解:@TableName、@TableId、@TableField
Model<T>:
save-->insert
【2】Page分页
【3】代码生成器控制
【4】方法调用:
Service层方法变更:
selectOne-->getOne
selectById-->getById
insert-->save
deleteById-->removeById
实体类.方法名(实现增删改查操作)
【5】筛选条件封装
// MP-2.2.0
Wrapper<T> queryWrapper = new EntityWrapper<>();
// MP-
QueryWrapper<T> idWrapper = new QueryWrapper<>();
springboot+mp:配置
https://baomidou.gitee.io/mybatis-plus-doc/#/spring-boot
Mappery引入飘红:
通过@Autowired加载Mapper飘红,在Mapper接口定义前加入@Repository即可消除
@Repository
public interface AdminMapper extends BaseMapper<Admin> {
mybatis-plus基础应用
【1】基础
枚举
逻辑删除
SpringBoot整合MP实现逻辑删除:
https://www.jianshu.com/p/65b2adf0408f
配置文件:MP配置(application.properties、application.yml)
实体类:指定逻辑删除字段
执行逻辑删除测试:(重启测试)
MP原生方法则会自动加入逻辑删除标识,如果是自定义mapper方法则需要自定义指定
查找日期相关
-- 价格参数校验
生效日期:为指定日期
<select id="getPriceMapByCond" parameterType="com.alibaba.fastjson.JSONObject"
resultType="java.util.Map">
<include refid="selectPriceVo"/>
where 1=1
<if test="queryCond != null">
<if test="queryCond.businessType != null and queryCond.businessType != ''">
and p.business_type = #{queryCond.businessType}
</if>
<if test="queryCond.priceType != null and queryCond.priceType != ''">
and p.price_type = #{queryCond.priceType}
</if>
<!--
<if test="queryCond.effectTime != null">
and to_char(p.effect_time,'yyyy-MM-dd') = #{queryCond.effectTime}
</if>
-->
<if test="queryCond.valueDate != null">
and to_char(p.effect_time,'yyyy-MM-dd') = #{queryCond.valueDate}
</if>
</if>
</select>
生效日期:为校验距离指定日期最近的数据
<select id="getPriceMapByCond" parameterType="com.alibaba.fastjson.JSONObject"
resultType="java.util.Map">
<include refid="selectPriceVo"/>
<if test="queryCond != null">
where p.business_type = #{queryCond.businessType}
and p.price_type = #{queryCond.priceType}
and to_char(p.effect_time,'yyyy-MM-dd') = (
-- 根据筛选条件获取指定筛选范围内最近的日期数据
select max(to_char(pc.effect_time,'yyyy-MM-dd'))
from boxing_param_price pc
where pc.business_type = #{queryCond.businessType}
and pc.price_type = #{queryCond.priceType}
and #{queryCond.valueDate} >= to_char(pc.effect_time,'yyyy-MM-dd')
)
</if>
</select>
【2】mapper-plus分页说明
a.mapper-plus-2.x分页说明
(1)mybatis-plus分页参考
定义分页插件配置
package com.sz.framework.config;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
分页工具类定义
public class PageUtil<T> {
/**
* @return com.baomidou.mybatisplus.plugins.Page<T>
* @MethodName getPage
* @Description 自定义获取分页组件
* @Param [jsonObject]
**/
public Page<T> getPage(JSONObject jsonObject) {
String pageNumberStr = jsonObject.getString("pageNumber");
String pageSizeStr = jsonObject.getString("pageSize");
// 当前页数pageNumber默认1、pageSize默认10
Integer pageNumber = (StringUtils.isEmpty(pageNumberStr)) ? 1 : Integer.valueOf(pageNumberStr);
Integer pageSize = (StringUtils.isEmpty(pageSizeStr)) ? 10 : Integer.valueOf(pageSizeStr);
Page<T> page = new Page<>(pageNumber, pageSize);
return page;
}
/** 自定义分页组件:根据指定的recordSize和分页对象封装分页组件数据(用于flowable数据查找相关分页) **/
public Page<T> getPage(JSONObject jsonObject, long total) {
String pageNumberStr = "1";
String pageSizeStr = "10";
if(jsonObject!=null){
pageNumberStr = jsonObject.getString("pageNumber");
pageSizeStr = jsonObject.getString("pageSize");
}
// 当前页数pageNumber默认1、pageSize默认10
Integer pageNumber = (StringUtils.isEmpty(pageNumberStr)) ? 1 : Integer.valueOf(pageNumberStr);
Integer pageSize = (StringUtils.isEmpty(pageSizeStr)) ? 10 : Integer.valueOf(pageSizeStr);
Page<T> page = new Page<>(pageNumber, pageSize);
// 如果指定recordList为空集合,则分页数为0(pages会自动封装)
page.setTotal(total);
return page;
}
}
mapper接口及对应xml文件配置
@Repository
@Mapper
public interface UserMapper extends BaseMapper<User> {
/**
* mapper方法定义
**/
public List<UserVO> getUserByPage(Page page, @Param(value = "queryCond") JSONObject jsonObject);
}
<select id="getUserByPage" parameterType="com.alibaba.fastjson.JSONObject"
resultType="com.sz.common.vo.UserVO">
<include refid="selectUserVo"/>
where 1=1 and u.logic_del = '0'
<if test="queryCond!= null">
<if test="queryCond.primaryClass != null and queryCond.primaryClass != ''">
and u.primary_class = #{queryCond.primaryClass}
</if>
........... 其他筛选条件配置 .............
</if>
order by u.primary_class,u.secondary_class,u.user_num
</select>
Mapper层要用List<UserVo>
接收 如果用Page接收报错如下:
service接口及实现类配置
可根据实际需求选择返回的数据:返回整个分页组件、或者是只返回分页后的数据
/** 获取当前所有可用的角色列表(封装为下拉框数据) **/
public interface UserService extends IService<User> {
// public List<UserVO> getUserByPage(JSONObject jsonObject);
public Page<UserVO> getUserByPage(JSONObject jsonObject);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public Page<UserVO> getUserByPage(JSONObject jsonObject) {
Page<UserVO> page = new PageUtil<UserVO>().getPage(jsonObject);
page.setRecords(userMapper.getUserByPage(page, jsonObject));
return page;
}
}
controller层实现
@RestController("system-user")
@RequestMapping("/system/user")
public class UserController {
/**
* 根据条件分页查找用户列表
**/
@RequiresRoles(value = {PRODUCT_MANAGER})
@PostMapping("/getUserByPage")
public AjaxResult getUserByPage(@RequestBody JSONObject jsonObject) {
Page<UserVO> pageData = userService.getUserByPage(jsonObject);
return AjaxResultUtil.success("pageData", pageData);
}
}
(2)物理分页和逻辑分页区分
在没有定义分页拦截器配置器的时候,其执行操作时先筛选出所有的记录随后再借助Page进行分页
定义了分页拦截器配置器之后,进行逻辑分页!在sql语句中直接进行分页
(3)借助mybatis分页插件分页(Flowable相关分页实现)
参考链接:https://blog.csdn.net/justry_deng/article/details/82933941
pom.xml配置
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
Service层
- 借助mybatis的分页插件PageInfo进行分页
public PageInfo<DeployEntity> getDeployByPage(JSONObject jsonObject);
@Override
public PageInfo<DeployEntity> getDeployByPage(JSONObject jsonObject) {
PageHelper.startPage(1,2);
List<Deployment> allList = repositoryService.createDeploymentQuery()
.deploymentTenantId(jsonObject.getString("tenantId")).list();
PageInfo<DeployEntity> pageInfo = new PageInfo<DeployEntity>
(EntityTransferUtil.transferDeployment(allList)) ;
return pageInfo;
}
- 使用mybatis-plus进行分页(调整flowable的方法特性调整分页方法)
/** 自定义分页组件:根据指定的recordSize和分页对象封装分页组件数据(用于flowable数据查找相关分页) **/
public Page<T> getPage(JSONObject jsonObject, long total) {
String pageNumberStr = "1";
String pageSizeStr = "10";
if(jsonObject!=null){
pageNumberStr = jsonObject.getString("pageNumber");
pageSizeStr = jsonObject.getString("pageSize");
}
// 当前页数pageNumber默认1、pageSize默认10
Integer pageNumber = (StringUtils.isEmpty(pageNumberStr)) ? 1 : Integer.valueOf(pageNumberStr);
Integer pageSize = (StringUtils.isEmpty(pageSizeStr)) ? 10 : Integer.valueOf(pageSizeStr);
Page<T> page = new Page<>(pageNumber, pageSize);
// 如果指定recordList为空集合,则分页数为0(pages会自动封装)
page.setTotal(total);
return page;
}
Controller层:
/** 查看部署列表 **/
@PostMapping("/getDeployByPage")
public AjaxResult getDeployByPage(@RequestBody JSONObject jsonObject) {
// Page<DeployEntity> pageData = deployService.getDeployByPage(jsonObject);
PageInfo<DeployEntity> pageData = deployService.getDeployByPage(jsonObject);
return AjaxResultUtil.success("pageData",pageData);
}
由于分页插件是通过拦截器,在原有SQL上进行追加约束条件,所以使用分页插件时,应注意:保证原有SQL不会受后面追加的条件的影响。给出一个反例:原有SQL中使用变量计算排名时,如果在后面追加了LIMIT的话,那么排名就会受到影响,因为SELECT的优先级在LIMIT之后。
Flowable的分页:如果使用mybatis分页插件实现分页,可以看到拦截后第一条执行的sql语句并非目标语句,因此导致分页失效
因此此处还是考虑使用flowable原生的分页方法,转化为自定义的分页逻辑。先查找好所有的记录作为分页的实体列表,随后调用listPage方法指定分页的数据(了解flowable分页的实现机制),或者是掌握flowable数据表规则,使用自定义sql用以控制分页
mybatis-plus扩展应用
Mybatis引用另一个mapper.xml文件中的sql:http://cn.voidcc.com/question/p-cunraeke-beu.html
实现思路1:使用不同的配置文件,配置不同的mapper文件(当sql变动时此种实现方式难以统一维护)
实现思路2:将方法放在同一个配置文件中,通过配置参数进行切换(配置参数可以在mapper接口定义的时候以参数的形式进行指定,或者是通过springboot整合mybatis的DatabaseIdProvider概念进行配置切换):需注意的是DatabaseIdProvider针对的更多的是不同数据源的配置切换而非同一数据源的不同用户的切换
mybatis的核心配置之databaseIdProvider:https://www.pianshen.com/article/228224019/
用户体系关联表填充相应的数据,此处将sql定义为一个返回参数模板的概念可供其他Mapper进行引用,避免每个sql重复定义造成sql维护成本过高
如果要实现动态配置,数据源针对的都是Oracle,只是定义不同的别名参数值,随后系统运行根据这个参数去获取对应的mapper片段
@Value("${projectVersion}")
private String projectVersion;
@Bean
public DatabaseIdProvider getDatabaseIdProvider(){
DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties properties = new Properties();
// 方式1:不同数据库配置切换
properties.setProperty("Oracle","oracle");
properties.setProperty("MySQL","mysql");
// 方式2::统一数据库配置实现不同sql配置切换(针对不同的oracle数据库用户),间接实现动态配置
properties.setProperty("Oracle",projectVersion);
databaseIdProvider.setProperties(properties);
return databaseIdProvider;
}
统一sql片段指定databaseId配置,可无需在相应的方法中指定例如<select databaseId="xxxx">
实现思路3:
可通过创建统一视图建立子系统用户表与关联UAS的关系,不同的项目环境相应切换对应的视图配置,在项目中则可无需额外对配置进行处理,只需统一视图名称和视图字段配置即可
mybatis动态sql中的两个内置参数(_parameter和_databaseId)
springboot整合mybatis使用一套程序切换不同的数据库:https://blog.csdn.net/weixin_39895109/article/details/83863838
[mybatis plus实体类中字段映射mysql中的json格式]
https://www.cnblogs.com/changchangchang/p/13121407.html
方式1:在xml中定义resultMap限定返回参数类型映射;
如果无效则检查返回的实体是否有相应字段匹配:检查下述内容
在实体类加上@TableName(autoResultMap = true)、在JSON字段映射的属性加上@TableField(typeHandler = FastjsonTypeHandler.class)
配置typeHandlersPackage路径:mybatis.typeHandlersPackage={BarTypeHandler所在包路径}
;
在oracle中配置上述内容无法解决:
方式2:通过配置注解(注意扫描包typeHandlersPackage):https://blog.csdn.net/qq_40688338/article/details/83380953
mybatis-plus开发应用技巧
Mybatis中实体类属性和数据列之间映射:
https://blog.csdn.net/lmy86263/article/details/53150091
mybatis简单实现多表关联查询:
https://www.jianshu.com/p/b68a142509e7
mybatis自动映射等级说明:
http://www.manongjc.com/article/95388.html
特殊字段属性(扩展性强的)映射不写死在代码里面,通过关联数据字典表查找
如果后续无扩展的可在代码中定义
Mybatis-plus代替数据字典:(针对不常变动的数据字段)
MyBatis-Plus 使用枚举自动关联注入:
https://www.imooc.com/article/details/id/29760
生成的代码除了Mapper.xml映射字段大小写、Model字段带小写映射不同,其余基本一致(继承基类Mapper、基类Service)
mapper常见问题排查
使用mp基类的方法能够正常访问数据
但是使用自定义的方法的时候:出现了sql语句正常执行但是mapper调用后没有正常封装数据到对象。???检查数据映射和对象之间的属性对应
查找的集合如果用单个对象去接收会报错:
实际业务处理:如果是业务确保唯一性则用单个对象接收不会出错,但是如果是具备不确定性则用List集合去接收随后根据业务需求选择某一个
Wrapper常用操作封装成一个Wrapper工具类,随后通过泛型指定
Wrapper<Role> deleteWrapper = new EntityWrapper<>();
deleteWrapper.eq("roleId",roleId);
等价于使用:new WrapperUtil<Role>().getIdWrapper("role_id",roleId)
开发技巧说明:
重复操作验证、查找对象空指针验证
前后端交互数据(限定交互类型避免随意访问接口导致出错)
公共操作类封装参考
Mp自定义方法使用wrapper:https://blog.csdn.net/u012925131/article/details/103428453/
Mp-@Param注解说明:https://blog.csdn.net/nqmysbd/article/details/86615016
Mp-dao-result返回值说明(返回数据结果封装):
https://blog.csdn.net/codejas/article/details/79520246
mp-dao层:mapper参数处理:https://www.cnblogs.com/super-chao/p/7722411.html
mp-dao:sq:片段应用:
Mp-自定义查询分页参考:https://blog.csdn.net/weixin_38111957/article/details/91554108
Mp-自定义分页查询:https://blog.csdn.net/FansUnion/article/details/89192879
不同mp版本处理方式不同
Mp-2.0参考:https://baomidou.gitee.io/mybatis-plus-doc/#/install
https://blog.csdn.net/FansUnion/article/details/89192879
如何在mapper中处理JSONObject对象?
Mp-自定义参数查询(如果不想指定DTO对象,考虑用Map接收参数)
或者是用JSONObject 接收参数,随后在dao层(mapper)用foreach循环迭代参数
然后进行sql拼接:
使用JSONObject接收参数:mapper处理
接口访问出错,检查接口参数、路径、注解相关配置、检查传入数据是否为指定的格式、接口访问方式等
前端传入对象数据后台接收全为null,检查@RequestBody注解配置
后台数据处理:
接收参数、
基本属性非空、长度等验证
数据重复性验证
操作验证
问题分析:如果在项目启动期间修改了数据库字段,需要重新启动项目,否则某些新增的字段系统无法拿到,无关代码(考虑和mp内部缓存机制相关)
VO对象封装,需要提供相应的getter、setter、toString,json自定解析将对象转化为字符串数据
Idea:mapper.xml警告:https://blog.csdn.net/VictorStephen/article/details/80280270
MyBatis-plus:ResultMap使用
如果查找结果没有正常封装导致报错,检查参数映射是否正常
最常见的是resultMap映射失败导致出错(找到的记录有n条,导致selectOne异常)
检查映射的resultMap引用是否正确!
mp问题
mp-字段映射
@MapKey("userId")
public Map<String,JSONObject> getUserMap();
<select id="getUserMap" resultType="com.alibaba.fastjson.JSONObject">
select u.user_id "userId",
u.user_num "userNum",
u.primary_class "primaryClass",
u.secondary_class "secondaryClass",
r.role_name "roleName"
from boxing_user u
left join cfa_role r on r.role_id = u.role_id
</select>
日期类注解校验
异常原因:项目中使用的校验注解所支持的数据类型与实体中字段的类型不符合。
例:在Integer类型的字段上使用@NotEmpty,@NotEmpty支持的是字符串类型字段,这样子使用肯定是会报错的
使用hibernate validator出现上面的错误, 需要 注意
@NotNull 和 @NotEmpty 和@NotBlank 区别
@NotEmpty 用在集合类上面、@NotBlank 用在String上面、@NotNull 用在基本类型上
mp-处理日期类字段
Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
此处原因为:在myBatis的xml文件中 写的 if 为空判断类型出错,把日期类型与空串作比较,代码片段如下:
<if test="createTime != null and createTime != ''">
AND DATE_FORMAT(lrc.create_time,'%Y-%m-%d') = DATE_FORMAT(#{createTime},'%Y-%m-%d')
</if>
其中 createTime 为日期类型,所以上面代码片段出错位置是 【createTime != ''】即去掉 【and createTime != ''】
总结:在myBatis的xml配置文件中写非空判断,其实只需要写 【!=null】就够用了;如果是String类型,判断中可以加【!=''】,注意日期类的处理