MybatisPlus笔记
一、简介
1.MyBatisPlus介绍
MyBatis-Plus( 简称 MP),是一个 MyBatis 的增强工具包,只做增强不做改变. 为简化开发工作、提高生产率而生,我们的愿景是成为 Mybatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
2.代码及文档发布地址
官方地址:
http://mp.baomidou.com
代码发布地址:
Github: https://github.com/baomidou/mybatis-plus
Gitee: https://gitee.com/baomidou/mybatis-plus
文档发布地址:
https://mp.baomidou.com/guide/
代码地址:
https://github.com/ZKQevin/MybatisPlus
学习地址:
https://www.bilibili.com/video/BV1Ds411E76Y
二、集成MP
1.创建数据库表
-- 创建库
CREATE DATABASE mp;
-- 使用库
USE mp;
-- 创建表
CREATE TABLE tbl_employee(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(50),
email VARCHAR(50),
gender CHAR(1),
age int
);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@qq.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@qq.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@qq.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@qq.com',0,35);
2.创建JavaBean实体类
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;
private Integer age;
//省略get和set以及ToString方法。
}
3.添加依赖
<!--单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--mp依赖
MybatisPlus 会自动维护Mybatis以及Mybatis-spring相关的依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.1.2</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--c3p0-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.24.RELEASE</version>
</dependency>
4.引入数据源配置部分省略
三、通用CRUD
1)基于 Mybatis
需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法
提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句.
2)基于 MybatisPlus
只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口.这就是使用 M
(泛型指定的就是当前Mapper接口所操作的实体类)需要完成的所有操作,甚至不需要创建 SQL 映射文件。
1.插入操作
①.生成ID策略
②.开启驼峰命名转换以及对应数据库表
@TableName(value = "tbl_employee")//对应数据库名
public class Employee {
/**
* TableId:
* value:指定表中的主键列的列明,如果实体属性名与类名一直,可以省略不指定,
* type:指定主键策略
*/
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
private String lastName;
private String email;
private Integer gender;
private Integer age;
@TableField(exist = false)//忽略数据库没有的值salary
private Integer salary;
//省略get和set方法
}
③.获取插入的ID值
在mybatis的Mapper映射文件中
<insert id="insert" useGeneratedKeys="true" keyProperty="id"></insert>
在MybatisPlus中,直接在Java后台获取到不需要写Mapper
Integer key=employee.getId();
④.插入对象出现空值
@Test
public void testCommonInsert() {
//初始化Employee对象
Employee employee = new Employee();
employee.setLastName("MP");
employee.setEmail("kevin@qq.com");
Integer result = employeeMapper.insert(employee);
System.out.println("Result:" + result);
}
此时插入结果为:MP,kevin@qq.com,null,null。
结论:insert方法在插入时,会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中
2.更新操作
通过ID进行更新操作,传入一个对相同会进行自动判断
@Test
public void testCommonUpdate(){
Employee employee = new Employee();
employee.setId(6);
employee.setLastName("MybatisPlus");
employee.setEmail("MybatisPlus@qq.com");
employee.setGender(0);
//可以写一个构造方法,new Employee(6,"Name","email",0,20)
//如果出现非空会MybatisPlus会进行自动判断,不会出现在SQL语句中
employee.setAge(20);
Integer result = employeeMapper.updateById(employee);
System.out.println("result:"+result);
}
3.查询操作
①.通过ID查询
@Test
public void testCommonSelect(){
Employee employee = employeeMapper.selectById(3);
System.out.println("Employee="+employee);
}
②.通过实体查询单条数据
Employee employee = new Employee();
employee.setId(4);
employee.setLastName("DSM");
Employee result = employeeMapper.selectOne(employee);
System.out.println(result);
③.传入多个ID查询多条记录
List<Integer> idList=new ArrayList<>();
idList.add(4);
idList.add(5);
idList.add(6);
List<Employee> employees = employeeMapper.selectBatchIds(idList);
System.out.println(employees);
④.使用HashMap封装对象查询
Map<String, Object> columnMap=new HashMap<>();
columnMap.put("last_name","Tom");
columnMap.put("gender",1);
List<Employee> result = employeeMapper.selectByMap(columnMap);
System.out.println(result);
⑤.分页查询
查询第三页,每一页显示两条数据,MybatisPlus会进行自动分页处理,底层使用的Mybatis的RowBounds方法进行处理,内存进行处理,所以SQL是看不到的。后续会使用MybatisPlus的插件进行物理分页
IPage<Employee> result = employeeMapper.selectPage(new Page<>(3, 2), null);
System.out.println(result);
3.删除操作
①.通过id进行删除
@Test
public void testCommonDelete() {
Integer result = employeeMapper.deleteById(8);
System.out.println("Result:"+result);
}
②.根据条件删除
Map<String, Object> columnMap=new HashMap<>();
columnMap.put("last_name","MP");
columnMap.put("email","kevin@qq.com");
Integer result = employeeMapper.deleteByMap(columnMap);
System.out.println("result"+result);
③.批量删除数据
List<Integer> idList = new ArrayList<>();
idList.add(12);
idList.add(13);
Integer result = employeeMapper.deleteBatchIds(idList);
System.out.println("result"+result);
4.MybatisPlus启动注入SQL原理分析
问题: xxxMapper 继承了 BaseMapper, BaseMapper 中提供了通用的 CRUD 方法, 方法来源于 BaseMapper, 有方法就必须有 SQL, 因为 MyBatis 最终还是需要通过 SQL 语句操作数据。
四、条件构造器
1.QueryWrapper(条件查询构造器)
public Employee testQueryWrapperSelect(){
//1.我们需要分页查询tbl_employee表中,年龄在16-50之间性别为男性姓名为MP的所有用户
IPage<Employee> employeeIPage = employeeMapper.selectPage(new Page<Employee>(1, 2),
new QueryWrapper<Employee>()
.between("age", 18, 50)
.eq("gender", 1)
.eq("last_name", "Tom"));
List<Employee> employees1=employeeIPage.getRecords();
employees1.forEach((value)-> System.out.println(value));
//2.查询tbl_employee表中,性别为女并且名字中带有“Tom”或者邮箱中带有“a“
List<Employee> employees2 = employeeMapper.selectList(new QueryWrapper<Employee>()
.eq("gender", 0)
.like("last_name", "Tom")
.or() //SQL:(gender = ? AND last_name LIKE ? OR email LIKE ? )
//.orNew() //SQL:(gender = ? AND last_name LIKE ?) OR (email LIKE ? );貌似新版本已经取消orNew()了
.like("email", "a")
);
employees2.forEach(value -> System.out.println(value));
//3.使用last。查询为女的,根据age进行排序(asc/desc),进行分页
List<Employee> employees3 = employeeMapper.selectList(new QueryWrapper<Employee>()
.eq("gender", 0)
.orderByDesc("age")
.last("limit 1,3"));
employees3.forEach(value -> System.out.println(value));
//4.使用Condition分页查询tbl_employee表中,年龄在16-50之间性别为男性姓名为MP的所有用户(了解Condition即可)
//employeeMapper.selectPage(new Page<Employee>(1,2),Connection.create().eq("gender",1));
//5.另一种分页,获取每行存在list集合中,并且每行的字段都放在map集合中。key:value=columnName:value
Page<Map<String,Object>> page=employeeMapper.selectMapsPage(new Page<Map<String,Object>>(1,3),
new QueryWrapper<Employee>().lambda()
.between(Employee::getAge,15,50)
.eq(Employee::getGender,1)
.eq(Employee::getLastName,"MP"));
List<Map<String,Object>> emps=page.getRecords();
for(Map<String,Object> map:emps){
for(String key:map.keySet()){
System.out.print(key+"--->"+map.get(key)+"; ");
}
System.out.println();
}
2.UpdateWrapper(修改构造器)
@Test
public void testUpdateWrapperSelect(){
Employee employee = new Employee();
employee.setLastName("Jack");
employee.setEmail("Jack@sina.com");
employee.setGender(0);
Integer update = employeeMapper.update(employee, new UpdateWrapper<Employee>()
.eq("last_name","Tom")
.eq("age",44));
System.out.println(update);
}
3.UpdateWrapper(删除构造器)
@Test
public void testDeleteWrapper(){
Integer delete = employeeMapper.delete(new UpdateWrapper<Employee>()
.eq("last_name", "Tom")
.eq("age", 20));
System.out.println(delete);
}
4.小结
本次教学只是常用的罗列出来,还有很多构造器方法在文档之中,需要自己学
MP:多个Wrapper Condition 条件构造器
Mybatis MBG:xxxExample→Criteria:QBC(Query By Criteria) Hibernate、通用Mapper
五、ActiveReccord(活动记录)
1)概述
Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索。
1.使用AR:继承Model<实体类>
public class Employee extends Model<Employee> {
//省略getset方法以及实体类属性
}
2.AR插入操作
@Test
public void testARInsert(){
Employee employee = new Employee();
employee.setLastName("Jack");
employee.setEmail("Jack@qq.com");
employee.setGender(1);
employee.setAge(20);
boolean insert = employee.insert();
System.out.println("Result="+insert);
}
3.AR修改操作
@Test
public void testARUpdate(){
Employee employee = new Employee(16,"JKL","JKL@qq.com",0,15);
System.out.println(employee.updateById());
}
4.AR删除操作
@Test
public void testARDelete(){
Employee employee = new Employee();
//通过id删除数据
System.out.println("通过ID删除结果="+employee.deleteById(4));
}
//根据条件删除数据(在逻辑上删除不存在的数据也是返回True)
System.out.println("通过条件删除结果="+employee.delete(new QueryWrapper<Employee>().eq("last_name","jack")));
5.AR查询操作
@Test
public void testARSelect(){
Employee employee = new Employee();
//通过id查询
System.out.println(employee.selectById(16));
//查询所有操作
System.out.println(employee.selectAll());
//使用Wrapper以及AR进行模糊查询
employee.selectList(new QueryWrapper<Employee>().like("last_name","J")).forEach(value -> {
System.out.println(value);
});
}
6.AR分页复杂操作
@Test
public void testARPage(){
Employee employee = new Employee();
//selectpage方法将返回对象封装到一个Page对象中,如果要得到需要使用getRecord()方法。
IPage<Employee> employeeIPage = employee.selectPage(new Page<>(1, 1), new QueryWrapper<Employee>().like("last_name", "T"));
employeeIPage.getRecords().forEach(value -> {
System.out.println(value);
});
}
7.小结
AR 模式提供了一种更加便捷的方式实现 CRUD 操作,其本质还是调用的 Mybatis 对应的方法,类似于语法糖。指计算机语言中添加的某种语法,这种语法对原本语言的功能并没有影响。可以更方便开发者使用,可以避免出错的机会,让程序可读性更好。
六、代码生成器
1)简介
MP 提供了大量的自定义设置,生成的代码完全能够满足各类型的需求。AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。-*-
2)MP 的代码生成器 和 Mybatis MBG代码生成器的对比
MP 的代码生成器都是基于 java 代码来生成。MBG 基于 xml 文件代码生成
MyBatis 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件
MP的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、Controller层。IDEA的EasyCode也是可以进行生成。
3)表及字段命名策略选择
在MybatisPlus中,我们建议数据库表名 和 表字段名采用驼峰命名方式, 如果采用下划线命名方式,请开启全局下划线开关(版本2.3默认开启),如果表名字段名命名方式不一致请注解指定,我们建议最好保持一致(约定大于配置)
这么做的原因是为了避免在对应实体类时产生的性能损耗,这样字段不用做映射就能直接和实体类对应。当然如果项目里不用考虑这点性能损耗,那么你采用下滑线也是没问题的,只需要在生成代码时配置dbColumnUnderline(map-underscore-to-camel-case)属性就可以。
1.使用添加依赖
添加 模板引擎 依赖和日志依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足要求,可以采用自定义模板引擎。
<!--Apach Velocity模版依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!--sfl4j日志依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
2.生成器代码
@Test
public void testGenerator() {
//1.全局策略配置
GlobalConfig config = new GlobalConfig();
config.setActiveRecord(true)//是否支持AR模式
.setAuthor("kevin")//作者
.setOutputDir("D:\\Spring\\Spring-couse\\MyBatisPlus03\\src\\main\\java")//输出路径
.setFileOverride(true)//文件覆盖
.setIdType(IdType.AUTO)//主键策略
.setServiceName("%sService")//设置生成service接口名字的首字母是否为I(默认会生成I开头的IStudentService)
.setBaseResultMap(true)//自动SQL映射文件,生成基本的ResultMap
.setBaseColumnList(true);//生成基本的SQL片段
//2.数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL)//设置数据库类型
.setDriverName("com.mysql.jdbc.Driver")//数据库驱动名
.setUrl("jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=UTF-8")//数据库地址
.setUsername("root")//数据库名字
.setPassword("123");//数据库密码
//3.策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setCapitalMode(true)//全局大写命名
.setDbColumnUnderline(true)//指定表明 字段名是否使用下划线
.setNaming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略
.setTablePrefix("tbl_")//前置命名
.setInclude("tbl_employee");//生成的表
//4.包名策略
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("org.example")//所放置的包
.setMapper("mapper")//Mapper包
.setService("service")//服务层包
.setController("controller")//控制层
.setEntity("beans")//实体类
.setXml("mapper");//映射文件
//5.整合配置
AutoGenerator autoGenerator = new AutoGenerator();
autoGenerator.setGlobalConfig(config)
.setDataSource(dataSourceConfig)
.setStrategy(strategy)
.setPackageInfo(packageConfig);
//6.执行
autoGenerator.execute();
}
3.关于服务层自动注入
Service层的接口自动继承了了IService接口,里面有一些常用操作的接口
Service层的实现类不仅实现了Service层的接口,并且还继承了ServiceImpl类,该类也实现了IService接口。所以我们的serviceimpl不需要写一些简单具体操作的实现。并且也不需要自动注入mapper,在ServiceImpl中已经帮我们注入了。
//服务层接口
public interface EmployeeService extends IService<Employee> {
}
//服务层实现类
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
//不用再进行Mapper的注入
/**
* EmployeeServiceImpl 集成了ServiceImpl
* 1.在ServiceImpl中已经完成Mapper对象的注入,直接在EmployeeServiceImpl中进行使用
* 2.在ServiceImpl中野帮我们提供了常用的CRUD方法,基本的一些CRUD方法在Service中不需要我们自己定义
*/
}
//被继承的接口
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
@Autowired
protected M baseMapper;//已自动注入Mapper
//各种方法省略
}
七、插件拓展
1.Mybatis插件机制简介
1)插件机制
Mybatis通过插件(Interkeptor)可以做到拦截四太对象相关方法的执行,根据需求,完成相关数据的动态改变。
Executor
StatementHandler
ParameterHandler
ResultSetHandler
2)插件原理
四太对象的每个对象在创建时,都会执行interceptorChain.pluginAll(),会经过每个插件对象的plugin()方法,目的是为当前的四太对象创建代理。代理对象就可以拦截到四太对象相关方法的执行,因为要执行四太对象的方法需要经过代理。
3)注册插件:在Spring配置文件下sqlSessionFactory的bean标签下
<!--注册插件-->
<property name="plugins">
<list>
<!--注册分页插件-->
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
<!--注册执行分析插件-->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<!--停止全表操作-->
<property name="stopProceed" value="true"/>
</bean>
<!--注册性能分析插件-->
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="format" value="true"/> <!--是否进行格式化-->
<property name="maxTime" value="5"/> <!--最长执行时间,毫秒级-->
</bean>
<!--注册乐观锁插件-->
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"></bean>
</list>
</property>
还可以在Mybatis配置文件下configuration标签下
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor" />
…………
</plugins>
2.分页插件
测试分页插件
@Test
public void testPage(){
Page<Employee> page = new Page<>(1, 3);
List<Employee> employees = employeeMapper.selectPage(page, null);
employees.forEach(value -> System.out.println(value));
System.out.println("总条数:"+page.getTotal());
System.out.println("当前页码:"+page.getCurrent());
//将查询的结果封装page对象中
page.setRecords(employees);
}
这样就会看到在SQL中出现Limit限制语句是真正的进行了分页操作。我们还可以对查询到的数据进行封装为一个Page对象
3.执行分析插件
注册插件之后如果使用的对全表的操作,程序会自动摧毁此次请求。在测试阶段使用,不建议在生产阶段使用
@Test
public void testSQLExplain(){
employeeMapper.delete(null);//全表删除操作
}
4.性能分析插件
注册插件之后如果所执行的SQL超过执行时间之后那么此条SQL抛出异常。在测试阶段使用,不建议在生产阶段使用
@Test
public void testPerformance(){
Employee employee = new Employee("marry","marry@qq.com","0",22);
employeeMapper.insert(employee);
}
5.乐观锁插件
1)实现原理:取出记录的时候获取当前Version版本号更新的时候带上Version,执行更新时,set version=youVersion+1 where versior=yourVersion。如果Version不对,就更新失败。必须使用@Version注解
2)使用方法:在Spring配置文件ApplicationContext.xml配置文件中注册插件。在实体类和数据库添加字段Version。
在实体类上添加@Version注解
@Version
private Integer version;
//省略Get和Set方法
测试方法,如果此时Version不与数据库中一致并不会报错只是不会更新。
@Test
public void testOptimisticLocker(){
Employee employee = new Employee();//更新操作
employee.setId(21);
employee.setLastName("Tom");
employee.setVersion(2);
employeeMapper.updateById(employee);
}
八、自定义全局操作
简介
根据 MybatisPlus的 AutoSgllniector,可以自定义各种你想要的sal ,注入到全局中,相当于自定义Mxbatisplus自动注入的方法。
之前需要在xml中进行配置的SQL语句,现在通过扩展AutoSallnjector在加载mybatis,环境时就注入。
1.AutoSqlInjector注入自定义SQL
1).Mapper中定义业务方法
public interface EmployeeMapper extends BaseMapper<Employee>{
Integer deleteByName();
}
2).定义MySqlInjector(新建一个injector包,MySqlInjector类)
public class MySqlInjector extends AutoSqlInjector {
/**
* 扩展Inject方法,完成自定义全局操作
*/
@Override
public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
//将EmployeeMapper中定义的方法,处理成对应的MappedStatement对象,加入到configuration对象中。
//注入的SQL语句
String sql = "delete from " + table.getTableName() + " where name=JKL";
//注入的方法名 一定要与EmployeeMapper接口中的方法名一致
String method = "deleteByName";
//构造SqlSource对象
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
//构造一个删除的MappedStatement
this.addDeleteMappedStatement(mapperClass, method, sqlSource);
}
}
3).自定义的MySqlInjector配置到ApplicationContext.xml全局策略中
<!--定义MybatisPlus的全局策略配置,在版本2.3以后就不用管了默认把数据库下划线变成驼峰就可以插入和主键策略问题-->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 在2.3版本以后,dbColumnUnderline 默认值就是true -->
<property name="dbColumnUnderline" value="true"></property>
<!--注入自定义全局操作-->
<property name="sqlInjector" ref="mySqlInjector"></property>
</bean>
<!--定义自定义注入器-->
<bean id="mySqlInjector" class="org.example.injector.MySqlInjector"></bean>
4).定义测试类
@Test
public void testMySqlInjector(){
Integer i = employeeMapper.deleteByName();
System.out.println("Result="+i);
}
2.自定义注入器引用之逻辑删除
假删除、逻辑删除:并不会真正的从数据库中讲数据删除掉,而是将当前被删除的这条数据中的一个逻辑删除字段置为删除操作。举例:tbl_user logic_flag=1(可用),logic_flag=-1(不可用)。
1)新增数据表
CREATE TABLE tbl_user(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
logic_flag INT(11)
);
实体类
public class User {
private Integer id;
private String name;
@TableLogic(/*value = "1",delval = "-1"*/) //逻辑删除字段属性,可以使用注解属性
private Integer logicFlag;
//省略get和set方法
}
2)在Spring配置文件ApplicationContext.xml进行配置
<!--定义MybatisPlus的全局策略配置,在版本2.3以后就不用管了默认把数据库下划线变成驼峰就可以插入和主键策略问题-->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--注入逻辑删除-->
<property name="sqlInjector" ref="logicSqlInjector"></property>
<!--注入逻辑删除全局value配置,也可以在实体类上面进行配置-->
<property name="logicDeleteValue" value="-1"/>
<property name="logicNotDeleteValue" value="1"/>
</bean>
<!--逻辑删除-->
<bean id="logicSqlInjector" class="com.baomidou.mybatisplus.mapper.LogicSqlInjector"/>
3)测试类
@Test
public void testLogicDelete() {
System.out.println(userMapper.deleteById(1));
System.out.println(userMapper.selectById(1));
}
所执行的SQL:UPDATE tbl_user SET logic_flag=-1 WHERE id=?
九、公共字段自动填充
1.元数据处理器接口
com.baomidou.mybatisplus.mapper.MetaObjectHandler
inserFill(MetaObject metaObject)
updateFill(MetaObject metaObject)
metaobject:元对象,是Mybatis.提供的一个用于更加方便,更加优雅的访问对象的属性,给对象的属性设置值的一个对象.还会用于包装对象.支持对object 、Map、Collection等对象进行包装。本质上metaObjet获取对象的属性值或者是给对象的属性设置值,最终是要通过Reflector获取到属性的对应方法的Invoker,最终invoke。
2.开发步骤
1)创建包MyMetaObjectHandler并创建类MyMetaObjectHandler继承MetaObjectHandler。
public class MyMetaObjectHandler extends MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
//获取到需要被填充的字段的值
Object fieldValue = getFieldValByName("name", metaObject);
if (fieldValue == null) {
System.out.println("******************满足填充条件******************");
setFieldValByName("name", "Kevin", metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
//获取到需要被填充的字段的值
Object fieldValue = getFieldValByName("name", metaObject);
if (fieldValue == null) {
System.out.println("******************满足填充条件******************");
setFieldValByName("name", "Jack", metaObject);
}
}
}
2)在Spring配置文件ApplicationContext.xml中进行配置
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--注入公共字段填充处理器-->
<property name="metaObjectHandler" ref="myMetaObjectHandler"/>
</bean>
<!--公共字段填充处理器-->
<bean id="myMetaObjectHandler" class="org.example.MyMetaObjectHandler.MyMetaObjectHandler"/>
3)编写测试类
@Test
public void testMetaObjectHandler() {
User user=new User();
//user.setName("lucy");//不定义名字,自动进行填充
user.setLogicFlag(1);
user.setId(5);
userMapper.updateById(user);
}
注意一个问题:如果更新操作您本不想更新那个字段这儿也会给您默认进行填充,所以使用的时候需要进行注意这个问题。
十、Oracle主键Sequence
MySQL:支持主键自增。IdType.Auto
Oracle:序列(Sequence)
1)实体类配置主键Sequence @KeySequence(value=“序列名”,class=xxx.class逐渐属性类型)
2)全局MP主键生成策略为idType.INPUT
3)全局mp中配置Oracle主键Sequence
com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
4)可以将@keySequence定义在父类中,可实现多个子类对应的多个表公用一个Sequence
十一、IDEA插件EasyCode使用
1.安装
1.点击File>Settinds>Plugins然后在Plugins里搜索easycode点击Install安装插件
2.搭建一个Maven的Web项目。生成之后需要手动创建在main下创Java目录并且创建包。这里创建包com.kevin(后面使用到)
3.导入数据库
4.配置数据库连接以及设置时区。
点击Set time zone之后跳转到Advanced之后再点击回General
5.右键点击需要生成的数据库表
6.选择所放置的包(com.java),确定路径正确之后一路点击yes就可以了
7.完成之后结构图