mybatis plus development
Service CURD interface
save
Mapper CURD interface
insert
// Insert a record int insert(T entity);
delete
// 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);
update
// 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);
select
// 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);
Conditional constructor
LambdaUpdateWrapper
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); updateWrapper.lambda().eq(User::getAge, 18).set(User::getAge, 20);
Wrappers. < entity > lambdaupdate ()
@Override @Transactional(rollbackFor = Exception.class) public CommcauseElementVO save(@NonNull CommcauseElementVO commcauseElementVO, @NonNull UserVO currUserVO) { if (Objects.nonNull(commcauseElementVO.getElementId())) { this.commcauseElementMapper.update(commcauseElementVO, Wrappers.<CommcauseElement>lambdaUpdate() .eq(CommcauseElement::getElementId, commcauseElementVO.getElementId())); } else { commcauseElementVO.setElementId(this.seqService.genLongSequence(CommcauseConstants.SEQ_NAME)); this.commcauseElementMapper.insert(commcauseElementVO); } return commcauseElementVO; }
Update only one field
return this.commcauseInfoMapper.update(null, Wrappers.<CommcauseInfo>lambdaUpdate() .set(CommcauseInfo::getCauseStatus, CommCauseStatus.DELETED).eq(CommcauseInfo::getCauseId, causeId));
If there are many updates, delete them first and then add them
queryWrapper
QueryWrapper<BannerItem> wrapper = new QueryWrapper<>(); wrapper.eq("banner_id", id); List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper);
lambdaQueryWrapper
LambdaQueryWrapper<BannerItem> wrapper = new QueryWrapper<BannerItem>().lambda();wrapper.eq(BannerItem::getBannerId, id);List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper);
Simplified, chain
List<BannerItem> bannerItems = new LambdaQueryChainWrapper<>(bannerItemMapper) .eq(BannerItem::getBannerId, id) .list();// BannerItem bannerItem = new LambdaQueryChainWrapper<>(bannerItemMapper) .eq(BannerItem::getId, id) .one();
Wrappers. < entity > lambdaquery ()
@Override public IPage<CommcauseElementVO> listPage(@NonNull CommcauseElementListPageDTO commcauseElementListPageDTO, @NonNull Integer current, @NonNull Integer size) { LambdaQueryWrapper<CommcauseElement> wrappers = Wrappers.<CommcauseElement>lambdaQuery() .eq(StringUtils.isNotBlank(commcauseElementListPageDTO.getElementCode()), CommcauseElement::getElementCode, commcauseElementListPageDTO.getElementCode()) .eq(StringUtils.isNotBlank(commcauseElementListPageDTO.getElementName()), CommcauseElement::getElementName, commcauseElementListPageDTO.getElementName()); IPage<CommcauseElementVO> selectPage = this.commcauseElementMapper.selectPage(new Page<>(current, size), wrappers); return selectPage; }
AbstractWrapper
The preceding conditions can be added. Only when the condition is true will it be executed
eq(boolean condition, R column, Object val)
- eq
- allEq example: allEq({id:1,name: "Lao Wang", age: null}) - > id = 1 and name = "Lao Wang" and age is null
- ne
- gt
- ge
- lt
- le
- between,notBetween
- like, notLike, likeLeft ('king '), likereight ('king%)
- isNull,isNotNull
- In, notIn, for example: in("id", new Object[]{1, 2}), in("id", list)
- inSql,notInSql
- groupBy
- orderByAsc,orderByDesc
- orderBy
- Having example: having("sum (age) > {0}", 11) - > having sum (age) > 11
- or example: eq("id", 1).or().eq("id", 2)
- and
- func
- nested
- apply
- last
- Exists, notExists example: exists("select id from table") - > exists (select id from table)
lambda can use the above methods
func(Consumer<Children> consumer)func(boolean condition, Consumer<Children> consumer)
- func method (it is mainly convenient to use different methods to continuously chain when if... else is called)
- Example: func (I - > if (true) {i.eq ("Id", 1)} else {i.ne ("Id", 1)})
nested(Consumer<Param> consumer)nested(boolean condition, Consumer<Param> consumer)
Normal nesting without AND OR
Example: nested (I - > i.eq ("name", "Li Bai"). ne("status", "alive") --- > (name = 'Li Bai' and status < > 'alive')
MP paging
IPage property
record getRecords Queried records total getTotal Total number size getSize Page size current getCurrent Current page pages getPages PageCount searchCount isSerachCount The default is true,Return the number of matching query criteria
@Override public IPage<CommcauseSchemeVO> listPage(@NonNull CommcauseSchemeListPageDTO listPageDTO, @NonNull Integer current, @NonNull Integer size) { LambdaQueryWrapper<CommcauseScheme> wrappers = Wrappers.<CommcauseScheme>lambdaQuery() .eq(StringUtils.isNotBlank(listPageDTO.getSchemeName()), CommcauseScheme::getSchemeName, listPageDTO.getSchemeName()) .eq(StringUtils.isNotBlank(listPageDTO.getSchemeStatus()), CommcauseScheme::getSchemeStatus, listPageDTO.getSchemeStatus()) .eq(Objects.nonNull(listPageDTO.getIsCanImport()), CommcauseScheme::getIsCanImport, listPageDTO.getIsCanImport()); IPage<CommcauseSchemeVO> selectPage = this.commcauseSchemeMapper.selectPage(new Page<>(current, size), wrappers); // Method 1: the method references selectPage.getRecords().forEach(this::translate)// Method 2: lambda expression / * list < commcauseschemevo > records = selectpage. Getrecords(); records.forEach(commcauseSchemeVO -> { commcauseSchemeVO.setSchemeStatusName(this.translate(commcauseSchemeVO)); });*/ return selectPage; } private void translate(CommcauseSchemeVO commcauseSchemeVO) { commcauseSchemeVO.setSchemeStatusName(this.dictionaryItemBI.getItemNameByDictCodeAndItemValue( CommcauseConstants.CommCauseDicCode.SCHEME_STATUS, commcauseSchemeVO.getSchemeStatus(), null)) / / method 2: / / return this. Dictionaryitembi. Getitemnamebydictcodeanditemvalue (/ / commcauseconstants. Commcausediccode. Scheme_status, commcauseschemevo. Getschemestatus(), null);}
MP annotation
@TableId
value = "id field", type = IdType.INPUT
IdType
value | 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 the interface identifier generator (the default implementation class is defaultidentifier generator) |
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) |
@TableField
attribute | type | Must specify | Default value | describe |
---|---|---|---|---|
value | String | no | "" | Database field name |
el | String | no | "" | Mapping to native #{...} logic is equivalent to the #{...} part written in xml |
exist | boolean | no | true | Is it a database table field |
condition | String | no | "" | Field where entity query and comparison criteria. If there is a value setting, the set value shall prevail. If there is no value setting, it is the default global% s=#{%s}, Reference (opens new window) |
update | String | no | "" | The field update set is partially injected, for example: update="%s+1": it means that set version = version + 1 will be updated (this attribute has higher priority than el attribute) |
insertStrategy | Enum | N | DEFAULT | Example: not_ NULL: insert into table_ a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>) |
updateStrategy | Enum | N | DEFAULT | Example: IGNORED: update table_a set column=#{columnProperty} |
whereStrategy | Enum | N | DEFAULT | Example: not_ EMPTY: where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> |
fill | Enum | no | FieldFill.DEFAULT | Field auto fill policy |
select | boolean | no | true | select query |
keepGlobalFormat | boolean | no | false | Do you want to keep using the global format for processing |
jdbcType | JdbcType | no | JdbcType.UNDEFINED | JDBC type (this default does not mean that it will take effect according to this value) |
typeHandler | Class<? extends TypeHandler> | no | UnknownTypeHandler.class | Type processor (this default does not mean that it will take effect according to this value) |
numericScale | String | no | "" | Specifies the number of digits to keep after the decimal point |
Sequcence primary key
The primary key generation policy must use INPUT
Support parent class definition @ KeySequence and subclass inheritance
Support primary key type assignment (automatic identification of primary key type from 3.3.0)
Built in support:
- DB2KeyGenerator
- H2KeyGenerator
- KingbaseKeyGenerator
- OracleKeyGenerator
- PostgreKeyGenerator
If the built-in support does not meet your needs, you can implement the IKeyGenerator interface for extension
Take a chestnut
@KeySequence("SEQ_USER")public class User { @TableId(value = "id", type = IdType.INPUT) private Long id; private String name; private Integer age; private String email;}
springboot
Mode 1:
@Configurationpublic class MybatisPlusConfig { /** * sequence For primary keys, you need to configure a primary key generator * with entity class annotation {@ link keysequence} + {@ link tableid} type = input * @ return */ @Bean public H2KeyGenerator h2KeyGenerator(){ return new H2KeyGenerator(); }}
Mode 2:
@Beanpublic MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() { return plusProperties -> plusProperties.getGlobalConfig().getDbConfig().setKeyGenerator(new H2KeyGenerator());}