1. Mapper CRUD interface
- The universal CRUD encapsulates the BaseMapper (opens new window) interface, which automatically resolves the entity table relationship mapping when Mybatis plus starts, and transforms it into the Mybatis internal object injection container
- Generic T is any entity object
- Wrapper updateWrapper entity object encapsulates the operation class (can be null, and the entity in it is used to generate the where statement)
- The parameter Serializable is any type of primary key. Mybatis plus does not recommend using the compound primary key convention. Each table has its own unique id primary key
- The object Wrapper is a conditional constructor
1.1 Insert - add User - default ID_WORKER globally unique id
Syntax:
// Insert a record int insert(T entity);
The insert operation will automatically generate the id, return the number of affected rows, and the id will automatically backfill the value User object
The default value of the id inserted in the database is the global unique id
// Test insertion @Test public void testInsert(){ User user = new User(); user.setName("mybatis_plus"); user.setAge(3); user.setEmail("12345678@qq.com"); int result = userMapper.insert(user); // Help us automatically generate id System.out.println(result); // Number of rows affected System.out.println(user); // If found, id will be backfilled automatically }
Extension: primary key (id) generation policy - id is automatically generated during insertion
field | describe |
---|---|
AUTO | Database ID self increment |
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 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 of interface IdentifierGenerator - nextuuid (default method) |
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) |
1) ID_WORKER globally unique id – snowflake algorithm
Generation of unique id of distributed system: https://www.cnblogs.com/haoxinyue/p/5208136.html
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
In milliseconds, 10bit is used as the machine ID (5 bits are the data center and 5 bits are the machine ID), and 12bit is used as the serial number within milliseconds (meaning
It means that each node can generate 4096 ID S per millisecond), and finally there is a symbol bit, which is always 0. Can guarantee almost global only
One!
2) Set primary key generation policy
@ TableId(type = IdType.AUTO) on entity class field
public class User { @TableId(type = IdType.UUID) private Long id; private String name; private Integer age; private String email; }
1.2 Update – update User data with id 3
Syntax:
// Update the record according to the whereWrapper condition int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper); // Modify according to ID int updateById(@Param(Constants.ENTITY) T entity);
updateById, but the parameter is an object! Update automatically splices dynamic sql through conditions
// Test update @Test public void testUpdate(){ User user = new User(); // Automatic splicing of dynamic sql through conditions user.setId(3L);//long type user.setName("mybayis_plus"); user.setAge(18); // Note: updateById, but the parameter is an object! int i = userMapper.updateById(user); System.out.println(i); }
Extension: auto fill – automatically fill data when inserting and updating
Automatically fill in the creation time and modification time! These operations are completed automatically. We don't want to update them manually!
Alibaba Development Manual: all database tables: gmt_create,gmt_modified almost all tables should be configured! And need
Automation!
1) Annotation needs to be added on the field attribute of entity class
- DEFAULT is not processed by DEFAULT
- INSERT fill fields when inserting
- Fill in fields when UPDATE
- INSERT_UPDATE fill fields when inserting and updating
// Add padding to fields @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
2) Write a processor to handle this annotation
@Slf4j @Component // Don't forget to add the processor to the IOC container! public class MyMetaObjectHandler implements MetaObjectHandler { // Population policy at insertion @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill....."); // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } // Population policy when updating @Override public void updateFill(MetaObject metaObject) { log.info("start update fill....."); this.setFieldValByName("updateTime",new Date(),metaObject); } }
Plug in: optimistic lock - when you want to update a record, you hope that the record has not been updated by others
Optimistic lock: hence the name Siyi is very optimistic. It always thinks that there will be no problem. No matter what you do, don't lock it! If something goes wrong,
Update value test again
Pessimistic lock: hence the name Siyi is very pessimistic. It always thinks that there is always a problem and it will lock no matter what it does! Do it again!
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
newVersion = oldVersion + 1 auto assemble - If the version is incorrect, the update fails
1. Only supported data types are: int,Integer,long,Long,Date,Timestamp,LocalDateTime
2. newVersion = oldVersion + 1 under integer type
3.newVersion will be written back to entity
4. Only updateById(id) and update(entity, wrapper) methods are supported
5. Under the update(entity, wrapper) method, the wrapper cannot be reused!!!
1) Register components in configuration class
// Scan our mapper folder @MapperScan("com.yanyu.mapper") @EnableTransactionManagement @Configuration // Configuration class public class MyBatisPlusConfig { // Register optimistic lock plug-in @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
2) Add annotations to the corresponding fields of the entity class
@Version //Optimistic lock Version annotation private Integer version;
1.3 Select
Syntax:
// Query by ID T selectById(Serializable id); // Query a record according to the entity condition T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query (batch query by ID) List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // Query all records according to the entity condition List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query (based on columnMap criteria) List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // Query all records according to Wrapper conditions List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records according to Wrapper conditions. Note: only the value of the first field is returned List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records (and turn the page) according to the entity condition IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records (and turn pages) according to Wrapper conditions IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query the total number of records according to Wrapper conditions Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Query test:
// Test query @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); } // Using map operations by one of the conditional queries @Test public void testSelectByBatchIds(){ HashMap<String, Object> map = new HashMap<>(); // Custom query map.put("name","mybatis_plus"); map.put("age",3); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }
Plug in: pagination – pagination of query data
1) Register components in configuration class
@Configuration @MapperScan("scan.yanyu.mapper") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
2) Testing
Syntax:
// Query all records (and turn the page) according to the entity condition IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records (and turn pages) according to Wrapper conditions IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query the total number of records according to Wrapper conditions Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Test:
- The IPage of the input parameter cannot be null because the returned IPage = = the IPage of the input parameter
- List returned by IPage.setRecords;
// Test paging query @Test public void testPage(){ // Parameter 1: current page // Parameter 2: page size // After using the paging plug-in, all paging operations become simple! Page<User> page = new Page<>(2,5); userMapper.selectPage(page,null); page.getRecords().forEach(System.out::println); System.out.println(page.getTotal()); }
3) Custom mapper uses pagination
If the return type is IPage, the IPage of the input parameter cannot be null because the returned IPage = = the IPage of the input parameter
If the return type is List, the IPage of the input parameter can be null (null does not page), but you need to manually enter the IPage of the parameter
Ipage.setrecords (returned List);
IPage<UserVo> selectPageVo(IPage<?> page, Integer state); // or (class MyPage extends Ipage<UserVo>{ private Integer state; }) MyPage selectPageVo(MyPage page); // or List<UserVo> selectPageVo(IPage<UserVo> page, Integer state); --------------------------------------------------------- <select id="selectPageVo" resultType="xxx.xxx.xxx.UserVo"> SELECT id,name FROM user WHERE state=#{state} </select>
1.4 Delete
Syntax:
// Delete the record according to the entity condition int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // Delete (batch delete according to ID) int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // Delete by ID int deleteById(Serializable id); // Delete the record according to the columnMap condition int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Test delete
@Test public void testDeleteById(){ userMapper.deleteById(1L); } // Batch delete by id @Test public void testDeleteBatchId(){ userMapper.deleteBatchIds(Arrays.asList(1L,2L)); } // Delete by map @Test public void testDeleteMap(){ HashMap<String, Object> map = new HashMap<>(); map.put("name","Madness theory Java"); userMapper.deleteByMap(map); }
Extensions: logical deletion
Physical delete: remove directly from the database
Logical deletion: it is not removed from the database, but invalidated by a variable! deleted = 0 => deleted = 1
explain:
Only works for automatically injected sql:
- Insert: no restrictions
- Find: append a where condition to filter the deleted data, and the where condition generated by wrapper.entity will ignore this field
- Update: append a where condition to prevent updating to deleted data, and the where condition generated using wrapper.entity will ignore this field
- Delete: convert to update
For example:
Delete: update user set deleted=1 where id = 1 and deleted=0
Search: select id,name,deleted from user where deleted=0
Field type support Description:
All data types are supported (integer, Boolean, localdatetime are recommended)
If the database field uses datetime, the logical undeleted value and deleted value can be configured as string null, and the other value can be configured as a function to obtain the value, such as now()
1) Configure class registration component
// Delete components logically! @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }
2) The Profile sets logical undeleted and deleted values
mybatis-plus: global-config: db-config: logic-delete-value: 1 # Logical deleted value (default is 1) logic-not-delete-value: 0 # Logical undeleted value (0 by default)
3) Add annotation to entity class field
@TableLogic //Logical deletion private Integer deleted;