
简介:注意事项图示
配置文件配置类查找插入更新(修改)自动填充赋值(createTime和updateTime)乐观锁批量ID查找条件查询分页查询(基于Page)删除
物理删除逻辑删除(黑名单等) 性能分析插件(SQL分析)
application配置全局文件配置类(configuration)自动注入处理类(Handler)mapper文件实体类乐观锁SQL分析复杂条件查询(基于QueryWrapper)
ge---大于等于(>=)eq---等于ne---不等于between---区间查询like---模糊查询orderByDesc---降序排序last---拼接SQL语句select---指定要查询的列注意:代码 mybatis-plus代码生成器
简介:mybatis
将使用mybatis过程中那些常用且固定的简单CRUD套路进行进一步封装(baseMapper,page等等)
并且由于service也就是调用mapper进行服务的,所以自然mp也将service进行了封装,只需要传参(实体类)继承配置就可以使用。
注意事项mp提供的baseMapper接口包含了常用且固定的简单CRUD,还提供了对应接口方法的SQL语句。 只需要简单配置传参,继承就可以进行单表 *** 作。
记住一件事(无论mybatis或者mp还是hibernate):实体类名和数据库表名,实体类变量名和列名都要一致相同。
注意:createTime(驼峰式命名)----create_time(数据库列命名)
mapper文件用到方法名时也要和接口方法名一致,绝对不会出错。
反之则可能出错。
图示 配置文件mp错误示范:
cause:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table
‘student.users1’ doesn’t exist(实体类名与表名未对应)
Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown
column ‘id1’ in ‘field list’(实体类变量名与列名未对应)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/student spring.datasource.username=root spring.datasource.password= #mybatis日志,可以查看使用的SQL语句 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #逻辑删除 mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0配置类
package com.example.mp.conf;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
//声明为配置类,专门用于配置环境
@Configuration
//配置mapper扫描的映射文件
@MapperScan("com.example.mp.mapper")
public class MPConfig {
//配置乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
//配置分页查询插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
//配置逻辑删除插件
@Bean
public ISqlInjector iSqlInjector(){
return new LogicSqlInjector();
}
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(500);//ms,超过此处设置的ms则sql不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
}
查找
实体类(entity):
lombok用于简化实体类,提供get,set,有参/无参构造方法。
mp提供的baseMapper接口包含了常用且固定的简单CRUD,还提供了对应接口方法的SQL语句。
只需要简单配置继承传参就可以进行单表 *** 作。
MyBatis-Plus(自带)默认的主键策略是: ID_WORKER/ID_WORKER_STR 全局唯一 ID(64位二进制=19位十进制)
snowflake(雪花)算法 其核心思想是: 使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),
12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID), 最后还有一个符号位,永远是0。
具体实现的代码可以参看https://github.com/twitter/snowflake。
雪花算法支持的TPS可以达到419万左右(2^22*1000)。
一共41+10+12+1=64位二进制
雪花算法在工程实现上有单机版本和分布式版本。单机版本如下,分布式版本可以参看美团leaf算法:https://github.com/Meituan-Dianping/Leaf
AUTO使用方法
错误示范:
实体类
实现插入时间和更新时间的自动填充
注解实现自动填充
也可以使用set不使用注解
注解方式
@TableField注解需要放在对应注入变量上方(规范化)
乐观锁
乐观锁原理
乐观锁笔记
mp乐观锁实现方式:
取出记录时,获取当前version(查)更新时,带上这个version执行更新时, set version = newVersion where version = oldVersion如果version不对,就更新失败(改)
(先查后改)
乐观锁SQL语句
UPDATE user
SET money=#{money},version=#{version+1}
WHERe id=#{id} and version=#{version}
mp中乐观锁插件使用时:必须先查(得到oldVersion)才可以(比较version值)后改。
如以下SQL语句所示,需知oldVersion值
UPDATE
user
SET
name='gclgg',
pass='355985',
create_time='2022-01-25 09:44:35',
update_time='2022-01-25 19:57:49.908',
version=4
WHERe
id=1485790668226932737
AND version=3
批量ID查找
// 批量查询
@Test
public void findIds(){
List users=usersMapper.selectBatchIds(Arrays.asList(1485790477566349314L,1485790668226932737L));
System.out.println(users);
}
条件查询
注意条件查询中HashMap的设置键为String,值为对应实体类类型
// 条件查询
@Test
public void findByMap(){
HashMaphp=new HashMap<>();
hp.put("name","gclgg");
hp.put("pass",123456);
List users=usersMapper.selectByMap(hp);
System.out.println(users);
}
分页查询(基于Page)
配置类中配置分页插件
//配置分页查询插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
批量删除
条件删除
配置为deleted=1为删除,deleted=0为未删除
mp其他时也会考虑逻辑删除变量deleted。
因为在application.properties文件中的配置在全局都适应。
例如:可以看到mp插件中乐观锁SQL语句
application配置全局文件该全局配置文件是配置全局,所以针对全部 *** 作生效。
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/student spring.datasource.username=root spring.datasource.password= #mybatis日志,可以查看使用的SQL语句 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #逻辑删除 mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0 #环境设置:dev、test、prod spring.profiles.active=dev配置类(configuration)
package com.example.mp.conf;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
//声明为配置类,专门引入配置
@Configuration
//配置mapper扫描的映射文件
@MapperScan("com.example.mp.mapper")
public class MPConfig {
//配置乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
//配置分页查询插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
//配置逻辑删除插件
@Bean
public ISqlInjector iSqlInjector(){
return new LogicSqlInjector();
}
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(500);//ms,超过此处设置的ms则sql不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
}
自动注入处理类(Handler)
package com.example.mp.handler;
import com.baomidou.mybatisplus.core.handlers.metaObjectHandler;
import org.apache.ibatis.reflection.metaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class mymetaObjectHandler implements metaObjectHandler {
@Override
public void insertFill(metaObject metaObject) {
this.setFieldValByName("createTime",new Date(), metaObject);
this.setFieldValByName("updateTime",new Date(), metaObject);
this.setFieldValByName("version",1,metaObject);
}
@Override
public void updateFill(metaObject metaObject) {
this.setFieldValByName("updateTime",new Date(), metaObject);
}
}
mapper文件
package com.example.mp.mapper; import com.baomidou.mybatisplus.core.mapper.baseMapper; import com.example.mp.User; import org.springframework.stereotype.Repository; @Repository public interface UsersMapper extends baseMapper实体类{ }
package com.example.mp;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Long id;
private String name;
private String pass;
//实体类:驼峰式命名createTime-对应-列名:create_time
@TableField(fill = FieldFill.INSERT)//插入时赋值
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)//插入,更新时赋值
private Date updateTime;
@Version//乐观锁:更新时判断再更新
@TableField(fill = FieldFill.INSERT)//插入时赋值
private Integer version;
@TableLogic
private Integer deleted;
}
乐观锁SQL分析
复杂条件查询(基于QueryWrapper)
//创建QueryWrapper对象进行复杂条件查询的SQL语句设置
QueryWrapper wrapper = new QueryWrapper<>();
//使用wrapper进行查询
List users = usersMapper.selectList(wrapper);
System.out.println(users);
ge—大于等于(>=)
eq—等于
ne—不等于
between—区间查询
like—模糊查询
orderByDesc—降序排序
last—拼接SQL语句
select—指定要查询的列
注意:
可以基于SQL进行多重复杂条件查询。
package com.example.mp;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mp.mapper.UsersMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
//作用:用于标识声明一个springboot框架容器。
@SpringBootTest
class MpApplicationTests {
@Autowired
private UsersMapper usersMapper;
@Test
public void findAll() {
List users=usersMapper.selectList(null);
System.out.println(users);
}
@Test
public void insert(){
User users=new User();
users.setName("gclgg");
users.setPass("123456");
// users.setCreateTime(new Date());
// users.setUpdateTime(new Date());
int result=usersMapper.insert(users);
System.out.println(result);
}
@Test
public void update(){
User user=new User();
user.setId(1485790668226932737L);
user.setPass("355985");
// user.setUpdateTime(new Date());
// 更新除ID以外修改过默认值(0,null)的属性
int result=usersMapper.updateById(user);
System.out.println(result);
}
// 测试乐观锁,必须先查后改才生效
@Test
public void testOpt(){
User user;
user=usersMapper.selectById(1485790668226932737L);
user.setPass("355985");
// user.setUpdateTime(new Date());
// 更新除ID以外修改过默认值(0,null)的属性
int result=usersMapper.updateById(user);
System.out.println(result);
}
// 批量查询
@Test
public void findIds(){
List users=usersMapper.selectBatchIds(Arrays.asList(1485790477566349314L,1485790668226932737L));
System.out.println(users);
}
// 条件查询
@Test
public void findByMap(){
HashMaphp=new HashMap<>();
hp.put("name","gclgg");
hp.put("pass",123456);
List users=usersMapper.selectByMap(hp);
System.out.println(users);
}
// 分页查询
@Test
public void page(){
//1 创建page对象
//传入两个参数: 当前页 和 每页显示记录数
Page page = new Page<>(1,3);
//调用mp分页查询的方法
//调用mp分页查询过程中,底层封装
//把分页所有数据封装到page对象里面
usersMapper.selectPage(page,null);
//通过page对象获取分页数据
System.out.println("当前页"+page.getCurrent());//当前页
System.out.println("每页数据list集合"+page.getRecords());//每页数据list集合
System.out.println("每页显示记录数"+page.getSize());//每页显示记录数
System.out.println("总记录数"+page.getTotal()); //总记录数
System.out.println("总页数"+page.getPages()); //总页数
System.out.println("是否有下一页"+page.hasNext()); //下一页
System.out.println("是否有上一页"+page.hasPrevious()); //上一页
}
//删除 *** 作 物理删除
@Test
public void testDeleteById(){
int result = usersMapper.deleteById(1485918452676915201L);
System.out.println(result);
}
//批量删除
@Test
public void testDeleteBatchIds() {
int result = usersMapper.deleteBatchIds(Arrays.asList(1,2));
System.out.println(result);
}
//条件删除
@Test
public void testDeleteByMap() {
HashMap map = new HashMap<>();
map.put("name", "gclgg");
map.put("pass", 123456);
int result = usersMapper.deleteByMap(map);
System.out.println(result);
}
//mp实现复杂查询 *** 作
@Test
public void testSelectQuery() {
//创建QueryWrapper对象
QueryWrapper wrapper = new QueryWrapper<>();
//指定要查询的列
// 通过QueryWrapper设置条件
wrapper.select("id","name");
//ge、gt、le、lt
//查询age>=30记录
//第一个参数字段名称,第二个参数设置值
wrapper.ge("pass",12345);
//eq、ne
// wrapper.eq("name","lilei");
// wrapper.ne("name","lilei");
//between
//查询密码长度区间 10000-10000000
// wrapper.between("pass",10000,1000000);
//like
// wrapper.like("name","gc");
//orderByDesc
// wrapper.orderByDesc("id");
//last
wrapper.last("AND pass='123456'");
List users = usersMapper.selectList(wrapper);
System.out.println(users);
}
}
mybatis-plus代码生成器
基于mp的自动生成代码,直接配置传参,继承mp封装简单且固定的crud的mapper,service的代码。
最后我们只需要编写业务逻辑(controller)就行。
package com.createcode;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;
public class CodeGenerator {
@Test
public void run() {
// 1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
// 2、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
// projectPath="F:\javaweb项目\edu_parent\service\service_edu"
gc.setOutputDir("F:\javaweb项目\edu_parent\service\service_edu"+ "/src/main/java");
gc.setAuthor("testjava");
gc.setOpen(false); //生成后是否打开资源管理器(就是把右边父文件夹打开,文件夹全部摊开)
gc.setFileOverride(false); //重新生成时文件是否覆盖
// 否则变为IUserService
gc.setServiceName("%sService"); //去掉Service接口的首字母I
gc.setIdType(IdType.ID_WORKER_STR); //主键策略
gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
gc.setSwagger2(true);//开启Swagger2模式
mpg.setGlobalConfig(gc);
// 3、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/education");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 4、包配置:com.qlugcl.eduservice
PackageConfig pc = new PackageConfig();
pc.setParent("com.qlugcl");//包名
pc.setModuleName("eduservice"); //模块名
pc.setController("controller");
pc.setEntity("entity");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
// 5、策略配置
StrategyConfig strategy = new StrategyConfig();
// 数据库表
strategy.setInclude("edu_teacher");
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀
strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式 *** 作
strategy.setRestControllerStyle(true); //restful api风格控制器
strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
mpg.setStrategy(strategy);
// 6、执行
mpg.execute();
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)