Mybatisplus
一、start
1.1 导入依赖
<!-- mysql驱动程序-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
1.2 配置文件
spring: datasource: username: root password: niuniu url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai driver-class: com.mysql.jdbc.Driver
1.3 开启Mapper注解扫描
启动类上加
@MapperScan("Mapper包路径")
1.4 创建pojo(实体类与表名相同)
@Data @AllArgsConstructor @NoArgsConstructor public class User { private Integer id; private String username; private String password; private String email; }
1.5 创建Mapper接口继承BaseMapper<实体类>
public interface UserMapper extends BaseMapper<User> {
}
1.6 配置日志
sql现在是不可见的,我们希望看见执行流程
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
二、CRUD扩展
主键生成策略
uuid、自增主键、雪花算法、redis、zookeeper
https://www.cnblogs.com/haoxinyue/p/5208136.html
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。雪花算法支持的TPS可以达到419万左右(2^22*1000)。
设置主键
@TableId
自动填充
创建时间、修改时间自动化完成
@TableField(fill = FieldFill.INSERT)
自定义实现类 MyMetaObjectHandler(根据mybatisplus版本不同在官网查看最新配置)
@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill ...."); this.strictInsertFill(metaObject, "属性名", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { log.info("start update fill ...."); this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());) } }
三、条件构造器
@Test public void test3() { QueryWrapper<User> wrapper = new QueryWrapper<>(); //username="a" and password=null wrapper.eq("username","a").isNull("password"); userMapper.selectList(wrapper); }
wrapper支持链式编程
更多方法查看官方文档不一一列举
四、乐观锁
乐观锁:在修改时校验,version一致修改,否则不修改
1、配置
@Bean public MybatisPlusInterceptor OptimisticLocker() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }
2、在数据库字段添加version字段默认值为0
3、在实体类添加version属性,并加注解@Version
这里可以利用自旋锁,当发生错误时,再次查询最新的记录再次提交
五、分页
配置文件
@Configuration @MapperScan("com.jydm.api.Mapper") public class MybatisPlusConfig { // 最新版 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
测试代码
@Test public void test2(){ //参数一:当前页 //参数二:每页记录数 Page<User> page = new Page<>(1,3); //参数一:page对象 //参数二:条件构造器 userMapper.selectPage(page, null); //获取记录总数 long total = page.getTotal(); System.out.println(total); //获取查询记录的list集合 List<User> records = page.getRecords(); records.forEach(System.out::println); }
六、逻辑删除
物理不删除,让用户看不到
1.配置
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
2.在数据库添加deleted字段默认为0
3.在实体类添加deleted属性 并添加注解@TableLogic
七、代码自动生成
1.添加依赖
<!-- mybatisplus代码生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <!--生成器模板引擎--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency>
2.编写自动生成程序
import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.po.TableFill; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.DateType; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class AutoCode { /** * <p> * 读取控制台内容 * </p> */ 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.isNotBlank(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("jydm"); gc.setOpen(false); gc.setFileOverride(false);//是否覆盖 gc.setServiceName("%sService");//去除Service I前缀 gc.setDateType(DateType.ONLY_DATE);//日期类型 gc.setSwagger2(true); //实体属性 Swagger2 注解 mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/shop?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("niuniu"); dsc.setDbType(DbType.MYSQL);//设置数据库类型 mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setModuleName("api");//模块名字 pc.setParent("com.jydm");//包路径 pc.setEntity("pojo");//实体类包名 pc.setMapper("mapper"); //mapper包名 pc.setService("service"); //service包名 pc.setController("controller");//controller包名 mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setInclude(scanner("表明")); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true);//自动lombok strategy.setRestControllerStyle(true);//controller restful风格 strategy.setLogicDeleteFieldName("deleted");//逻辑删除 strategy.setControllerMappingHyphenStyle(true); // localhost:8080/hello_id_2 strategy.setVersionFieldName("version");// 乐观锁 //自动填充配置 TableFill gmtCreate = new TableFill("create_time", FieldFill.INSERT);//创建时间填充 TableFill gmtModified = new TableFill("update_time", FieldFill.INSERT_UPDATE);//插入更细时间填充 ArrayList<TableFill> tableFills = new ArrayList<>(); tableFills.add(gmtCreate); tableFills.add(gmtModified); strategy.setTableFillList(tableFills); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); //启动 mpg.execute(); } }
注意:
乐观锁对应数据库字段为 version 默认为0
逻辑删除对应数据库字段为 deleted 默认为0
创建时间对应数据库字段为 create_time
更新时间对应数据库字段为 updata_time
八、性能分析插件
浙公网安备 33010602011771号