Mybatis Plus
quick get start
- maven configuration
<?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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.erf</groupId> <artifactId>springboot-data</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-data</name> <description>Demo project for Spring Boot Redis and MySql Plus</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
-
create table
drop table if exists `user`; create table `user`( `id` bigint not null auto_increment, `name` varchar(255) default null, `age` int default null , `email` varchar(255) default null, key `id`(`id`) )engine=InnoDB default charset =utf8; insert into `user`(`name`,`age`,`email`) values ('John1',24,'125jawdi@awd.com'), ('John2',42,'125jawdi@awd.com'), ('John3',42,'125jawdi@awd.com'), ('John4',44,'125jawdi@awd.com');
-
Database connection
spring.datasource.username=root spring.datasource.password=980980 spring.datasource.url=jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2d8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-
User.java
package com.erf.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class User { private int id; private String name; private int age ; private String email; }
-
UserMapper.java
package com.erf.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.erf.pojo.User; import org.springframework.stereotype.Repository; @Repository public interface UserMapper extends BaseMapper<User> { }
-
Application
package com.erf; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @MapperScan("com.erf.mapper") @SpringBootApplication public class SpringbootDataApplication { public static void main(String[] args) { SpringApplication.run(SpringbootDataApplication.class, args); } }
-
test CRUD interface
package com.erf; import com.erf.mapper.UserMapper; import com.erf.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; @SpringBootTest class SpringbootDataApplicationTests { @Autowired private UserMapper userMapper; @Test void contextLoads() { List<User> users = userMapper.selectList(null); users.forEach(System.out::println); } }
-
The results show that
User(id=1, name=John1, age=24, email=125jawdi@awd.com)
User(id=2, name=John2, age=42, email=125jawdi@awd.com)
User(id=3, name=John3, age=42, email=125jawdi@awd.com)
User(id=4, name=John4, age=44, email=125jawdi@awd.com)
Log output
spring.datasource.username=root spring.datasource.password=980980 spring.datasource.url=jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2d8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #Console log output mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
Primary key strategy and snowflake algorithm
-
snowflake is Twitter's open source distributed ID generation algorithm, and the result is a long ID. Its core idea is to use 41bit as the number of milliseconds, 10bit as the machine ID (five bits are the data center and five bit machine ID), 12bit as the serial number within milliseconds (meaning that each node can generate 4096 IDS per millisecond), and finally there is a symbol bit, which is always 0.
The snowflake algorithm can be modified according to the needs of its own project. For example, estimate the number of data centers in the future, the number of machines in each data center and the number of concurrency that can be unified in milliseconds to adjust the number of bit s required in the algorithm.advantage:
It does not depend on the database, is flexible and convenient, and its performance is better than the database.The ID is incremented on a single machine according to time.
Disadvantages:
It is incremental on a single machine, but due to the distributed environment, the clocks on each machine cannot be fully synchronized. Sometimes, it may not be globally incremental.
-
Primary key policy
@TableId(type = IdType.ASSIGN_ID) / / note that auto with self incrementing database primary key is used_ Increment will make type ineffective
IdType
value describe AUTO Self increment of database ID NONE Stateless. This type has no primary key set (in the annotation, it is equal to follow the global, and the global value is equal to INPUT) INPUT set the primary key value before insert ing ASSIGN_ID Assign ID (the primary key type is Number(Long and Integer) or String)(since 3.3.0), and use the method NextID of the interface IdentifierGenerator (the default implementation class is DefaultIdentifierGenerator) ASSIGN_UUID Allocate UUID. The primary key type is String(since 3.3.0). Use the method nextuuid (default method) of the interface IdentifierGenerator ID_WORKER Distributed globally unique ID long integer type (please use ASSIGN_ID) UUID 32-bit UUID string (please use ASSIGN_UUID) ID_WORKER_STR Distributed globally unique ID string type (please use ASSIGN_ID)
Initial population strategy
-
annotation
@TableField(fill = FieldFill.INSERT)String createTime;
-
Implementation mode
package com.erf.controller;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;import lombok.extern.slf4j.Slf4j;import org.apache.ibatis.reflection.MetaObject;import org.springframework.stereotype.Component;import java.time.LocalDateTime;@Slf4j@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill ...."); this.strictUpdateFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); } @Override public void updateFill(MetaObject metaObject) { }}
Optimistic lock
When you want to update a record, you want it not to be updated by others
Optimistic lock implementation method:
- When the record is fetched, the current version is obtained
- When updating, bring this version
- When updating, set version = newVersion where version = oldVersion
- If the version fails, the update will fail
-
Add @ Version annotation to the field of entity class
@Versionprivate String name;
-
Implement MybatisPlusInterceptor injection
package com.erf.conf;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration@MapperScan("com.erf.pojo")public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return mybatisPlusInterceptor; }}
Paging query
-
MybatisPlusInterceptor
@Configuration@MapperScan("scan.your.mapper.package")public class MybatisPlusConfig { /** * The new paging plug-in follows the rules of mybatis, and MybatisConfiguration#useDeprecatedExecutor = false needs to be set to avoid cache problems (this attribute will be removed after the old plug-in is removed) */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); return interceptor; } @Bean public ConfigurationCustomizer configurationCustomizer() { return configuration -> configuration.setUseDeprecatedExecutor(false); }}
-
Use of paging
@Test void contextLoads4(){ Page<User> userPage = new Page<>(3,3); userMapper.selectPage(userPage,null); userPage.getRecords().forEach(System.out::println); }
Automatic code generation
Don't forget the Application scan package @ MapperScan. Pay attention to the failure of Mapper automatic injection of the same name automatically generated
package com.erf.autocode; 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.NamingStrategy; public class MysqlGenerator { public static void main(String[] args) { AutoGenerator mpg = new AutoGenerator(); //1. Global configuration GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); //Generation path (generally generated under src/main/java of this project) gc.setAuthor("EatRiceFully"); //Set author gc.setOpen(false); gc.setFileOverride(true); //The second generation will overwrite the first generation gc.setServiceName("%sService"); //Whether the initial letter of the generated service interface name is I is not set gc.setBaseResultMap(true); //Generate resultMap mpg.setGlobalConfig(gc); //2. Data source configuration DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("980980"); mpg.setDataSource(dsc); // 3. Package configuration PackageConfig pc = new PackageConfig(); pc.setModuleName("autotest"); pc.setParent("com.erf"); mpg.setPackageInfo(pc); // 4. Policy configuration StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setSuperControllerClass("com.lcy.demo.sys.controller.BaseController"); strategy.setSuperEntityClass("com.lcy.demo.sys.entity.BaseEntity"); // strategy.setTablePrefix("t_"); // table prefix strategy.setEntityLombokModel(true); //Using lombok String[] tables = {"books","user"}; strategy.setInclude(tables); // If you want to generate multiple tables for reverse engineering, you can pass in String [] here mpg.setStrategy(strategy); //5. Execute mpg.execute(); } }