简介:注意事项图示
配置文件配置类查找插入更新(修改)自动填充赋值(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(){ HashMap分页查询(基于Page)hp=new HashMap<>(); hp.put("name","gclgg"); hp.put("pass",123456); List users=usersMapper.selectByMap(hp); System.out.println(users); }
配置类中配置分页插件
//配置分页查询插件 @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语句设置 QueryWrapperge—大于等于(>=) eq—等于 ne—不等于 between—区间查询 like—模糊查询 orderByDesc—降序排序 last—拼接SQL语句 select—指定要查询的列 注意:wrapper = new QueryWrapper<>(); //使用wrapper进行查询 List users = usersMapper.selectList(wrapper); System.out.println(users);
可以基于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() { Listmybatis-plus代码生成器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(){ HashMap hp=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); } }
基于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条)