preface
Mybatis- Plus simplifies Mybatis!
Creating a database
The database name is mybatis_plus
Create a table
Create a user table
DROP TABLE IF EXISTS user; CREATE TABLE user (id BIGINT(20) NOT NULL COMMENT 'id ', name VARCHAR(30) NULL DEFAULT NULL COMMENT' iD ', Age INT(11) NULL DEFAULT NULL COMMENT 'age ', email VARCHAR(50) NULL DEFAULT NULL COMMENT' mailbox ', PRIMARY KEY (ID)); INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, '[email protected]'), (2, 'Jack', 20, '[email protected]'), (3, 'Tom', 28, '[email protected]'), (4, 'Sandy', 21, '[email protected]'), (5, 'Billie', 24, '[email protected]');Copy the code
Note: — In real development, there are usually four fields: version (optimistic lock), deleted (logical deletion), gmT_CREATE (created time), gmt_Modified (modified time)
Initialize the project
Initialize with a Springbooter!Copy the code
Import dependence
<! -- database driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <! -- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <! -- mybatis-plus --> <! Mybatis - Plus is self-developed, not official! --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> The < version > 3.0.5 < / version > < / dependency >Copy the code
Note: Try not to import both Mybatis and Mybatis – Plus! Avoid unexpected problems caused by version differences.
Connecting to a Database
Create application. Yml
spring: profiles: active: dev datasource: Mysql 5 com.mysql.jdbc.driver # mysql 8 com.mysql.cj.jdbc.driver serverTimezone=GMT%2B8 url: jdbc:mysql://localhost:3306/mybatis_plus? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 driver-class-name: com.mysql.cj.jdbc.Driver username: root password: rootCopy the code
Business code
Entity classCopy the code
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
Copy the code
Mapper interfaces
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.kuang.pojo.User; import org.springframework.stereotype.Repository; Public interface UserMapper extends BaseMapper<User> {// This extends BaseMapper<User> All CRUD operations have been written}Copy the code
Note that we need to scan all interfaces in our mapper package @mapperscan (” com.kwhua.mapper “) on the main startup class.
test
@ SpringBootTest class MybatisPlusApplicationTests {/ / inherited BaseMapper, all the way to their parent / / we can also write your own extension methods! @Autowired private UserMapper userMapper; @test void contextLoads() {// This is a Wrapper, condition constructor. List<User> users = userMapper.selectList(null); users.forEach(System.out::println); }}Copy the code
All data output
To configure the log
All of our SQL is now invisible and we want to know how it is executed, so we need to configure the log output to application-yml file to add log configuration
# configuration log mybatis - plus: configuration: log - impl: org. Apache. The ibatis. Logging. Stdout. StdOutImplCopy the code
View the log information about SQL execution
3. Mybatis – plus the CRUD
1. Insert operations
@test public void testInsert(){User User = new User(); user.setName("kwhua_mybatis-plus_insertTest"); user.setAge(15); user.setEmail("[email protected]"); int result = userMapper.insert(user); Id system.out. println(result); // Number of affected rows system.out.println (user); // The id is automatically populated when it is seen. }Copy the code
If you see the ID, it will fill in automatically. The default value of the database insert ID is the global unique ID
Primary key generation policy
TableId(type = idtype.auto); TableId(type = idtype.auto);
3, test again (you can see that the value of id is 1 more than the last insert)
Id generation strategy source code explanation
Public enum IdType {AUTO(0), // database ID is NONE(1), // primary key INPUT(2) is not set, // enter ID_WORKER(3), // Default mode, global unique ID UUID(4), // Global unique ID uuid ID_WORKER_STR(5); //ID_WORKER string representation}Copy the code
This is no longer tested individually.
The update operation
@Test public void testUpdate(){ User user = new User(); SQL user.setid (1302223874217295874L); user.setName("kwhua_mybatis-plus_updateTest"); user.setAge(20); // Note that the updateById argument is an object! int i = userMapper.updateById(user); System.out.println(i); }Copy the code
Automatic filling
Create time, modify time! Both field operations are automated and we don’t want to update them manually! All database tables must be configured with GMT_CREATE, GMT_Modified! And it needs automation! Method 1: Database level (generally not used in work) 1. Create gmt_CREATE and gmT_modified columns in the table
2. Synchronize entity classes
private Date gmtCreate;
private Date gmtModified;
Copy the code
3. Check again
Mode 2: code level 1, delete database defaults, update operation!
2, the entity class field attributes need to add annotations
@tableField (fill = FieldFill.INSERT) private Date gmt_create; @TableField(fill = FieldFill.INSERT_UPDATE) private Date gmt_modified;Copy the code
3. Write a processor to handle this annotation!
@slf4j@component // Don't forget to add the handler to the IOC container! Public class MyMetaObjectHandler implements MetaObjectHandler {@override public void insertFill(MetaObject) metaObject) { log.info("start insert fill....." ); // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject this.setFieldValByName("gmt_create",new Date(),metaObject); this.setFieldValByName("gmt_modified",new Date(),metaObject); } @override public void updateFill(MetaObject MetaObject) {log.info("start update fill.....") ); this.setFieldValByName("gmt_modified",new Date(),metaObject); }}Copy the code
4. Test inserts and updates to check time changes.
Optimistic locking
Optimistic lock: name think meaning, very optimistic, it always think there will be no problem, no matter what do not lock! If there is a problem, update the value again to test pessimistic lock: hence the name, very pessimistic, it always thinks there is always a problem, no matter what will be locked! Operate again!
Optimistic lock implementation:
Set version = newVersion where version = oldVersion If the version is incorrect, the update fails
Optimistic locking: 1, first query, Version = 1 -- A update user set name = "kwhua", version = version + 1 where id = 2 and version = 1 If version = 2, A will fail to be modified! update user set name = "kwhua", version = version + 1 where id = 2 and version = 1Copy the code
Optimistic lock testAdd version to database!
2. Add the corresponding field to the entity class
@version // Optimistic lock Version annotation private Integer Version;Copy the code
3. Register components
/ / @ MapperScan scan our mapper folder (com. Kwhua. "mapper") @ EnableTransactionManagement @ Configuration / / Configuration class public class MyBatisPlusConfig {/ / registered optimistic locking plug-in @ Bean public OptimisticLockerInterceptor OptimisticLockerInterceptor () {return new OptimisticLockerInterceptor(); }}Copy the code
4, test,
// Test optimistic lock successfully! @test public void testOptimisticLocker(){// 1, query User information User = usermapper.selectById (1L); // 2, modify user information user.setName("kwhua"); user.setEmail("[email protected]"); Usermapper. updateById(user); }Copy the code
The version field has changed from 1 to 2
// Test optimistic lock failed! @test public void testOptimisticLocker2(){// Thread 1 User User = usermapper.selectById (1 l); user.setName("kwhua111"); user.setEmail("[email protected]"); User2 = usermapper.selectById (1L); user2.setName("kwhua222"); user2.setEmail("[email protected]"); userMapper.updateById(user2); // Spin lock to try to commit many times! userMapper.updateById(user); // If there is no optimistic lock, the value of queue-jumping thread will be overwritten! }Copy the code
You can see that thread 1 failed to perform the update
Query operation
@test public void testSelectById(){User User = usermapper.selectById (1L); System.out.println(user); } // test batch query! @Test public void testSelectByBatchId(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println); @test public void testSelectByBatchIds(){HashMap<String, Object> map = new HashMap<>(); Put ("name","kwhua"); map.put("age",15); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }Copy the code
6.1 Paging Query 1. Configure the interceptor component
@bean public PaginationInterceptor PaginationInterceptor() {return new PaginationInterceptor(); }Copy the code
2, use the Page object directly!
@test public void testPage(){@test public void testPage(){@test public void testPage(){@test public void testPage(); userMapper.selectPage(page,null); page.getRecords().forEach(System.out::println); System.out.println(page.getTotal()); }Copy the code
Physically deleted
@test public void testDeleteById(){usermapper.deletebyid (1L); } / / by id batch delete @ Test public void testDeleteBatchId () {userMapper. DeleteBatchIds (Arrays. The asList (2 l, 3 l)); } @test public void testDeleteMap(){HashMap<String, Object> map = new HashMap<>(); map.put("name","kwhua"); userMapper.deleteByMap(map); }Copy the code
Logic to delete
Logical delete: not removed from the database, but invalidated by a variable! Deleted = 0 => Deleted = 1 Administrators can view deleted records! Prevent data loss, similar to the recycle bin!
1. Add a deleted field to the table
2. Add attributes to the entity class
@TABLelogic // Logical deletion private Integer deleted;Copy the code
3, configuration,
// Logical delete component! @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }Copy the code
Configuration file Configuration
global-config:
db-config:
logic-delete-value: 1
logic-not-delete-value: 0
Copy the code
4. Test Delete test
The field value is also changed from 0 to 1
Test the query
Performance analysis plug-in
Function: Performance analysis interceptor, used to output each SQL statement and its execution time MP also provides performance analysis plug-in, if exceeded this time will stop running! 1. Import the plug-in
/ @bean@profile ({"dev","test"})/ PerformanceInterceptor PerformanceInterceptor () {PerformanceInterceptor PerformanceInterceptor = new PerformanceInterceptor(); performanceInterceptor.setMaxTime(100); / / ms set the maximum time of SQL execution, if more than, not executed performanceInterceptor setFormat (true); return performanceInterceptor; }Copy the code
Conditional constructor (Wrapper)
.isNotNull .gt
QueryWrapper<User> wrapper = new QueryWrapper<>(); Wrapper.isnotnull ("name") // not null. IsNotNull ("email").ge("age",18); userMapper.selectList(wrapper).forEach(System.out::println); // Compare this to the map we just learned}Copy the code
.eq
@test void test2(){// Query name kwhua QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("name","kwhua"); User user = userMapper.selectOne(wrapper); // Use selectOne to query a single data, use List or Map system.out.println (user) to query multiple results; }Copy the code
.between
@test void test3(){// Query a User aged between 20 and 30 QueryWrapper<User> wrapper = new QueryWrapper<>(); Wrapper. Between (" age ", 20, 30); // Interval Integer count = usermapper.selectCount (wrapper); System.out.println(count); }Copy the code
.like
@test void test4(){QueryWrapper<User> wrapper = new QueryWrapper<>(); // likelift %t, likeRight t% wrapper. NotLike ("name","e").likeright ("email","t"); List<Map<String, Object>> maps = userMapper.selectMaps(wrapper); maps.forEach(System.out::println); }Copy the code
.insql
@test void test5(){QueryWrapper<User> wrapper = new QueryWrapper<>(); InSql ("id","select ID from user where ID <3"); inSql("id","select id from user where ID <3"); List<Object> objects = userMapper.selectObjs(wrapper); objects.forEach(System.out::println); }Copy the code
.orderByAsc
@test void test6(){QueryWrapper<User> wrapper = new QueryWrapper<>(); // Sort by id wrapper.orderByASc ("id"); List<User> users = userMapper.selectList(wrapper); users.forEach(System.out::println); }Copy the code
Automatic code generator
You can create a Java class in the Test folder
Public class generateCode {public static void main(String[] args) {// Need to build a code generator object AutoGenerator MPG = new AutoGenerator(); GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath+"/src/main/java"); gc.setAuthor("kwhua"); // Author name gc.setopen (false); gc.setFileOverride(false); // Whether to override gc.setidType (idtype.id_worker); gc.setDateType(DateType.ONLY_DATE); gc.setSwagger2(true); Swagger2 annotation // Custom file name, note that %s will automatically fill the table entity attributes! gc.setServiceName("%sService"); gc.setControllerName("%sController"); gc.setServiceName("%sService"); gc.setServiceImplName("%sServiceImpl"); gc.setMapperName("%sMapper"); gc.setXmlName("%sMapper"); mpg.setGlobalConfig(gc); // set DataSourceConfig DSC = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/kwhua_test? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); // dsc.setDriverName("com.mysql.jdbc.Driver"); //mysql5.6 following the driver dsc.setusername ("root"); dsc.setPassword("root"); dsc.setDbType(DbType.MYSQL); mpg.setDataSource(dsc); PackageConfig PC = new PackageConfig(); pc.setParent("com.kwhua"); / / package name PC. SetModuleName (" model "); // module name pc.setentity ("entity"); pc.setMapper("mapper"); pc.setService("service"); pc.setController("controller"); mpg.setPackageInfo(pc); //4, StrategyConfig strategy = new StrategyConfig(); strategy.setInclude("user","course"); // Set the name of the table to be mapped strategy.setnaming (namingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); // Automatic lombok; strategy.setLogicDeleteFieldName("deleted"); TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT); TableFill gmtModified = new TableFill("gmt_modified",FieldFill.INSERT_UPDATE); ArrayList<TableFill> tableFills = new ArrayList<>(); tableFills.add(gmtCreate); tableFills.add(gmtModified); strategy.setTableFillList(tableFills); / / optimistic locking strategy. SetVersionFieldName (" version "); // Create the class name based on your table name. If your table name does not have an underscore, such as test, you can cancel this step strategy.settablePrefix ("t_"); strategy.setRestControllerStyle(true); / / rest request / / automatically underline, such as localhost: 8080 / hello_id_2 strategy. SetControllerMappingHyphenStyle (true); mpg.setStrategy(strategy); mpg.execute(); // execute}}Copy the code
Execute the main method to generate the corresponding code
The last
Thank you for reading here, the article has any shortcomings please correct, feel the article is helpful to you remember to give me a thumbs up, every day will share Java related technical articles or industry information, welcome to pay attention to and forward the article!