A. Instructions
Mybatis – Plus website: mp.baomidou.com/
Mybatis-Plus is a Mybatis framework enhancement plug-in, according to the official description,MP only do enhancement do not change, the introduction of it will not affect the existing project, as smooth as silk. And with simple configuration, CRUD operations can be performed quickly, saving a lot of time. Code generation, paging, performance analysis and other functions are available, the latest version has been updated to 3.1.1,3.X series support lambda syntax, let me write conditional construction when a lot of less “magic value “, from the code structure is more concise.
Ii. Project environment
MyBatis-Plus version: 3.2.0
SpringBoot version: 2.2.7
JDK version: 1.8
Maven has the following dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
<! -- mybatisPlus Core library -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<! Ali database connection pool -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
</dependencies>
Copy the code
The configuration is as follows:
# config port
server:
port: 8081
spring:
# configure data source
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_student? useUnicode=true&characterEncoding=utf-8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
# Mybatis -plus related configuration
mybatis-plus:
# XML scan, multiple directories separated by commas or semicolons (to tell Mapper where the corresponding XML file is)
mapper-locations: classpath:mapper/*.xml
The following configurations have default values
global-config:
db-config:
# primary key type AUTO:" database ID increment "INPUT:" user INPUT ID",ID_WORKER:" globally unique ID (number type unique ID)", UUID:" globally unique ID UUID";
id-type: auto
# field policy IGNORED:" ignore judgment "NOT_NULL:" non-null judgment ") NOT_EMPTY:" Non-null judgment"
field-strategy: NOT_EMPTY
# database type
db-type: MYSQL
configuration:
Enable automatic camel name mapping: a similar mapping from database column names to Java attribute camel names
map-underscore-to-camel-case: true
True: null is returned if the map is null. False: hidden if the map is null
call-setters-on-nulls: true
This configuration prints out the executed SQL for use during development or testing
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Copy the code
Table structure:
CREATE TABLE `user_info` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(32) DEFAULT NULL COMMENT 'name',
`age` int(11) DEFAULT NULL COMMENT 'age',
`skill` varchar(32) DEFAULT NULL COMMENT 'skills',
`evaluate` varchar(64) DEFAULT NULL COMMENT 'evaluation',
`fraction` bigint(11) DEFAULT NULL COMMENT 'scores'.PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COMMENT='Student Information Form';
CREATE TABLE `dept_info` (
`dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'department ID',
`dept_name` varchar(64) NOT NULL COMMENT 'Department Name',
`create_id` varchar(20) DEFAULT NULL COMMENT 'creator ID',
`create_time` timestamp NULL DEFAULT NULL COMMENT 'Creation time',
`update_id` varchar(20) DEFAULT NULL COMMENT 'Updater ID',
`update_time` timestamp NULL DEFAULT NULL COMMENT 'Update Time',
`deleted` tinyint(1) DEFAULT '0' COMMENT 'Logical delete 0: normal 1: delete'.PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4;
Copy the code
Table data:
INSERT INTO `user_info` VALUES (1.'Ming'.20.'drawing'.'The student has some talent in painting'.89);
INSERT INTO `user_info` VALUES (2.'xiao LAN'.19.'games'.'Recently, the student's score was lowered due to the game'.64);
INSERT INTO `user_info` VALUES (3.'his'.18.'English'.'The student recently won the second prize in the English competition'.90);
INSERT INTO `user_info` VALUES (4.'rhubarb'.20.'sports'.'The student recently suffered a foot injury due to participating in a basketball match'.76);
INSERT INTO `user_info` VALUES (5.'the great'.17.'painting'.'The student won the third prize in the art competition'.77);
INSERT INTO `user_info` VALUES (7.'little dragon'.18.'JAVA'.'The student is a coder fixing a BUG'.59);
INSERT INTO `user_info` VALUES (9.'Sans'.18.'sleep'.'Sans is a little fat man with a big skeleton and a short body who likes to sleep. '.60);
INSERT INTO `user_info` VALUES (10.'papyrus'.18.'JAVA'.'Papyrus is a loud, flamboyant, confident, charismatic skinny skeleton. '.58);
INSERT INTO `user_info` VALUES (11.'Delete data 1'.3.'Paint a portrait'.NULL.61);
INSERT INTO `user_info` VALUES (12.'Delete data 2'.3.NULL.NULL.61);
INSERT INTO `user_info` VALUES (13.'Delete data 3'.3.NULL.NULL.61);
INSERT INTO `user_info` VALUES (14.'Delete data 4'.5.'delete'.NULL.10);
INSERT INTO `user_info` VALUES (15.'Delete data 5'.6.'delete'.NULL.10);
Copy the code
Write the base class
Add annotations to scan the DAO on the startup class
@SpringBootApplication
@MapperScan(basePackages = {"com.mp.demo.dao"}) / / scanning DAO
public class DemoApplication {
public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}Copy the code
Write the Config configuration class
/ * * *@DescriptionMybatisPlus configuration class *@Author Sans
* @CreateTime2019/5/26 and * /
@Configuration
public class MybatisPlusConfig {
/** ** paging plug-in */
@Bean
public PaginationInterceptor paginationInterceptor(a) {
return newPaginationInterceptor(); }}Copy the code
Write the Entity class
/ * * *@DescriptionStudent information Entity class *@Author Sans
* @CreateTime2019/5/26 all * /
@Data
@TableName("user_info")// the value in @tablename corresponds to the TableName
public class UserInfoEntity {
/** * primary key *@TableId* AUTO: database ID increment * INPUT: user INPUT ID * ID_WORKER: globally unique ID, primary key of type Long * ID_WORKER_STR: String Globally unique ID * UUID: indicates a globally unique ID. Primary key of the UUID type * NONE: indicates that the primary key type is not set */
@TableId(type = IdType.AUTO)
private Long id;
/** * name */
private String name;
/** * age */
private Integer age;
/** * skills */
private String skill;
/** * evaluation */
private String evaluate;
/** * score */
private Long fraction;
}
Copy the code
Write the Dao class
/ * * *@DescriptionUser information DAO *@Author Sans
* @CreateTime2019/6/8 16:24 * /
public interface UserInfoDao extends BaseMapper<UserInfoEntity> {}Copy the code
Write the Service class
/ * * *@DescriptionUser business interface *@Author Sans
* @CreateTime7 all 2019/6/8 * /
public interface UserInfoService extends IService<UserInfoEntity> {}Copy the code
Write ServiceImpl class
/ * * *@DescriptionUser business implementation *@Author Sans
* @CreateTime7 all 2019/6/8 * /
@Service
@Transactional
public class UserInfoSerivceImpl extends ServiceImpl<UserInfoDao.UserInfoEntity> implements UserInfoService {}Copy the code
Basic demonstration of MyBatis-Plus
Here we see, we didn’t write any method in the service and official MyBatis – Plus encapsulates many basic CRUD methods, can directly use a lot of time saving, MP method is detailed in IService, common ServiceImpl, BaseMapper source code, write in Servic Transaction binding is already available in eImpl, so here we demonstrate some common methods.
/ * * *@Description UserInfoController
* @Author Sans
* @CreateTime2019/6/8 16:27 * /
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {
@Autowired
private UserInfoService userInfoService;
/** * Get user information based on ID *@Author Sans
* @CreateTime2019/6/8 o *@ParamUserId userId *@ReturnUserInfoEntity User entity */
@RequestMapping("/getInfo")
public UserInfoEntity getInfo(String userId){
UserInfoEntity userInfoEntity = userInfoService.getById(userId);
return userInfoEntity;
}
/** * query all information *@Author Sans
* @CreateTime2019/6/8 now *@ParamUserId userId *@ReturnList<UserInfoEntity> Set of user entities */
@RequestMapping("/getList")
public List<UserInfoEntity> getList(a){
List<UserInfoEntity> userInfoEntityList = userInfoService.list();
return userInfoEntityList;
}
/** ** ** ** ** ** ** ** **@Author Sans
* @CreateTime2019/6/8 scatter *@ReturnIPage<UserInfoEntity> paging data */
@RequestMapping("/getInfoListPage")
public IPage<UserInfoEntity> getInfoListPage(a){
// Paging plug-ins need to be configured in the Config configuration class
IPage<UserInfoEntity> page = new Page<>();
page.setCurrent(5); / / the current page
page.setSize(1); // Number of entries per page
page = userInfoService.page(page);
return page;
}
/** * Query user information set * based on the specified field@Author Sans
* @CreateTime2019/6/8 desired *@ReturnCollection<UserInfoEntity> Collection of user entities */
@RequestMapping("/getListMap")
public Collection<UserInfoEntity> getListMap(a){
Map<String,Object> map = new HashMap<>();
//kay is the field name and value is the field value
map.put("age".20);
Collection<UserInfoEntity> userInfoEntityList = userInfoService.listByMap(map);
return userInfoEntityList;
}
/** * Add user information *@Author Sans
* @CreateTime 2019/6/8 16:40
*/
@RequestMapping("/saveInfo")
public void saveInfo(a){
UserInfoEntity userInfoEntity = new UserInfoEntity();
userInfoEntity.setName("Small dragon");
userInfoEntity.setSkill("JAVA");
userInfoEntity.setAge(18);
userInfoEntity.setFraction(59L);
userInfoEntity.setEvaluate("The student is a coder fixing a BUG.");
userInfoService.save(userInfoEntity);
}
/** * Add user information in batches *@Author Sans
* @CreateTime2019/6/8 * / calm
@RequestMapping("/saveInfoList")
public void saveInfoList(a){
// Create an object
UserInfoEntity sans = new UserInfoEntity();
sans.setName("Sans");
sans.setSkill("Sleep");
sans.setAge(18);
sans.setFraction(60L);
sans.setEvaluate("Sans is a sleeping, short, fat little skeleton with a huge skeleton.");
UserInfoEntity papyrus = new UserInfoEntity();
papyrus.setName("papyrus");
papyrus.setSkill("JAVA");
papyrus.setAge(18);
papyrus.setFraction(58L);
papyrus.setEvaluate("Papyrus is a loud, flamboyant, confident, charismatic skinny skeleton.");
// Batch save
List<UserInfoEntity> list =new ArrayList<>();
list.add(sans);
list.add(papyrus);
userInfoService.saveBatch(list);
}
/** * Update user information *@Author Sans
* @CreateTime2019/6/8 yet * /
@RequestMapping("/updateInfo")
public void updateInfo(a){
If the value of other fields is null, this field will not be updated. Refer to the YML configuration file
UserInfoEntity userInfoEntity = new UserInfoEntity();
userInfoEntity.setId(1L);
userInfoEntity.setAge(19);
userInfoService.updateById(userInfoEntity);
}
/** * Add or update user information *@Author Sans
* @CreateTime2019/6/8 thus * / were
@RequestMapping("/saveOrUpdateInfo")
public void saveOrUpdate(a){
// If the ID is null in the incoming entity class userInfoEntity, it will be added.
// The entity class ID value exists, if the database ID exists, it will be updated, if not, it will be added
UserInfoEntity userInfoEntity = new UserInfoEntity();
userInfoEntity.setId(1L);
userInfoEntity.setAge(20);
userInfoService.saveOrUpdate(userInfoEntity);
}
/** * Delete user information based on ID *@Author Sans
* @CreateTime2019/6/8 hast judged * /
@RequestMapping("/deleteInfo")
public void deleteInfo(String userId){
userInfoService.removeById(userId);
}
/** * Delete user information in batches based on ID *@Author Sans
* @CreateTime 2019/6/8 16:55
*/
@RequestMapping("/deleteInfoList")
public void deleteInfoList(a){
List<String> userIdlist = new ArrayList<>();
userIdlist.add("12");
userIdlist.add("13");
userInfoService.removeByIds(userIdlist);
}
/** * Deletes user information * based on the specified field@Author Sans
* @CreateTime2019/6/8 16:57 * /
@RequestMapping("/deleteInfoMap")
public void deleteInfoMap(a){
//kay is the field name and value is the field value
Map<String,Object> map = new HashMap<>();
map.put("skill"."Delete");
map.put("fraction".10L); userInfoService.removeByMap(map); }}Copy the code
MyBatis-Plus QueryWrapper conditional constructor
When query conditions are complex, we can use MP’s conditional constructor, as described below in the QueryWrapper conditional parameter description
A query | Method statement |
---|---|
setSqlSelect | Set the SELECT query field |
where | WHERE statement, concatenation + WHERE condition |
and | AND statement, concatenate + AND field = value |
or | OR statement, concatenation + OR field = value |
eq | Equal to = |
allEq | Map based content is equal to = |
ne | Is not the same as < > |
gt | More than > |
ge | The value is greater than or equal to >= |
lt | < < |
le | Less than or equal to <= |
like | Fuzzy query LIKE |
notLike | Fuzzy query NOT LIKE |
in | IN the query |
notIn | NOT IN the query |
isNull | A NULL value query |
isNotNull | IS NOT NULL |
groupBy | GROUP BY GROUP |
having | HAVING keywords |
orderBy | Sort ORDER BY |
orderByAsc | ASC sort ORDER BY |
orderByDesc | DESC sort ORDER BY |
exists | EXISTS condition statement |
notExists | NOT EXISTS Conditional statement |
between | BETWEEN conditional statement |
notBetween | NOT BETWEEN conditional statement |
addFilter | Free concatenation SQL |
last | Splice at the end, e.g. : last(“LIMIT 1”) |
Here are some common examples | |
“` java | |
/ * * |
- @Description UserInfoPlusController
- @Author Sans
- @CreateTime 2019/6/9 14:52
*/ @RestController @RequestMapping(“/userInfoPlus”) public class UserInfoPlusController {
@Autowired private UserInfoService userInfoService; /** * MP extension demo * @author Sans * @createTime 2019/6/8 16:37 * @return Map<String,Object> Returns data */ @requestMapping ("/getInfoListPlus") public Map<String,Object> getInfoListPage(){// Initialize class Map<String,Object> result = new HashMap<>(); Select * from student where age = 18; SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age = 18 QueryWrapper<UserInfoEntity> queryWrapper1 = new QueryWrapper<>(); queryWrapper1.lambda().eq(UserInfoEntity::getAge,18); List<UserInfoEntity> userInfoEntityList1 = userInfoService.list(queryWrapper1); result.put("studentAge18",userInfoEntityList1); Select * from student where age > 5 and age < 18; SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age > 5 AND age <= 18 QueryWrapper<UserInfoEntity> queryWrapper2 = new QueryWrapper<>(); queryWrapper2.lambda().gt(UserInfoEntity::getAge,5); queryWrapper2.lambda().le(UserInfoEntity::getAge,18); List<UserInfoEntity> userInfoEntityList2 = userInfoService.list(queryWrapper2); result.put("studentAge5",userInfoEntityList2); // Fuzzy query skill field with "draw" data, and descending order by age // equivalent SQL: SELECT id, name, age, skill, evaluate, fraction FROM user_info WHERE skill LIKE '% % painting' ORDER BY age DESC QueryWrapper<UserInfoEntity> queryWrapper3 = new QueryWrapper<>(); QueryWrapper3. Lambda (.) like (UserInfoEntity: : getSkill, "painting"); queryWrapper3.lambda().orderByDesc(UserInfoEntity::getAge); List<UserInfoEntity> userInfoEntityList3 = userInfoService.list(queryWrapper3); result.put("studentAgeSkill",userInfoEntityList3); // select * from students whose names are younger or older than 18; SELECT id, name, age, skill, evaluate, fraction FROM user_info WHERE the name LIKE 'little % %' OR the age 18 QueryWrapper > < UserInfoEntity > queryWrapper4 = new QueryWrapper<>(); QueryWrapper4. Lambda (.) like (UserInfoEntity: : getName, "small"); queryWrapper4.lambda().or().gt(UserInfoEntity::getAge,18); List<UserInfoEntity> userInfoEntityList4 = userInfoService.list(queryWrapper4); result.put("studentOr",userInfoEntityList4); SQL > select * from student where evaluation is not NULL; SELECT id, name, age, skill, evaluate, fraction FROM user_info WHERE the evaluate IS NOT NULL LIMIT 0, 5 IPage < UserInfoEntity > page = new Page<>(); page.setCurrent(1); page.setSize(5); QueryWrapper<UserInfoEntity> queryWrapper5 = new QueryWrapper<>(); queryWrapper5.lambda().isNotNull(UserInfoEntity::getEvaluate); page = userInfoService.page(page,queryWrapper5); result.put("studentPage",page); return result; }Copy the code
}
The introduction of Mybatis-Plus will not affect the existing Mybatis architecture of the project. And Mybatis-Plus supports all Mybatis native features, which is also one of the reasons I like to use it, because some business is complex, we may have to write some more complex SQL statements, we give a simple example to demonstrate the custom SQL. Scores (example: query is greater than the set points of students for the dynamic input, and there are pages) written Mapper. The XML file ` ` ` XML < Mapper namespace = "com. Mp. Demo. Dao. UserInfoDao" > <! -- Sans 2019/6/9 14:35 --> <select id="selectUserInfoByGtFraction" resultType="com.mp.demo.entity.UserInfoEntity" parameterType="long"> SELECT * FROM user_info WHERE fraction > #{fraction} </select> </mapper>Copy the code
Add methods to DAO
/** * select * from students whose score is greater than this@Author Sans
* @CreateTime14:28 2019/6/9 *@ParamPage page parameter *@ParamFraction score *@ReturnIPage<UserInfoEntity> paging data */
IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction);
Copy the code
Add methods to service
/** * select * from students whose score is greater than this@Author Sans
* @CreateTime 2019/6/9 14:27
* @ParamPage page parameter *@ParamFraction score *@ReturnIPage<UserInfoEntity> paging data */
IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page,Long fraction);
Copy the code
Add methods in serviceImpl
/** * select * from students whose score is greater than this@Author Sans
* @CreateTime 2019/6/9 14:27
* @ParamPage page parameter *@ParamFraction score *@ReturnIPage<UserInfoEntity> paging data */
@Override
public IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction) {
return this.baseMapper.selectUserInfoByGtFraction(page,fraction);
}
Copy the code
Test in Controller
/** * MP custom SQL *@Author Sans
* @CreateTimeHe 2019/6/9 *@ReturnIPage<UserInfoEntity> paging data */
@RequestMapping("/getInfoListSQL")
public IPage<UserInfoEntity> getInfoListSQL(a){
// Select * from student whose score is greater than 60
IPage<UserInfoEntity> page = new Page<>();
page.setCurrent(1);
page.setSize(5);
page = userInfoService.selectUserInfoByGtFraction(page,60L);
return page;
}
Copy the code
Automatic fill and logical delete
The MybaitS-Plus extension features such as auto-fill, logical deletion and optimistic locking, which can be used to reduce the amount of code and improve readability at development time.
- Entity test cases
/** * Department information entity class *@Author Sans
* @CreateTime2020/8/15 20:03 * /
@Data
@TableName("dept_info")
public class DeptInfoEntity {
/**
* ID主键
*/
@TableId(type = IdType.AUTO)
private Long deptId;
/** * Department name */
private String deptName;
INSERT_UPDATE Inserts and updates the fill field * FieldFill.UPDATE Updates the fill field * FieldFill.DEFAULT */ is not processed by default
/** * creator ID */
@TableField(fill = FieldFill.INSERT)
private String createId;
/** * create time */
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/** * update ID */
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateId;
/** * update time */
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/** * logical delete * TableLogic is a logical delete annotation. If yML is configured with a global logical delete field, this annotation can be omitted
@TableLogic
private Integer deleted;
}
Copy the code
- Autofill configuration
/** * MP automatically fills Handler *@Author Sans
* @CreateTime2020/8/15 21:49 * /
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/** * Insert operation populates field method */
@Override
public void insertFill(MetaObject metaObject) {
/** * Fill operator/update * The DEMO is just an example, the actual project here can be determined by the business ** for example, from Shrio securityutils.getSubject ().getPrincipal() to get the current user information fill */
this.strictInsertFill(metaObject, "createId", String.class,"ADMIN");
this.strictInsertFill(metaObject, "updateId", String.class, "ADMIN");
// Fill time
Date date = new Date();
this.strictInsertFill(metaObject, "createTime", Date.class, date);
this.strictInsertFill(metaObject, "updateTime", Date.class, date);
}
/** * Update operation populates field method */
@Override
public void updateFill(MetaObject metaObject) {
Date date = new Date();
this.strictUpdateFill(metaObject, "updateId", String.class, "ADMIN");
this.strictUpdateFill(metaObject, "updateTime", Date.class, date); }}Copy the code
Seven. Project source code
Project source: gitee.com/liselotte/s…
Personally, I really like using MyBatis Plus. It saves time and the code is clean and it gives me the feeling of transitionfrom SSM to SpringBoot at that time
Yeah, it smells good
Thank you for reading this article. If you like it, please click “like”. If there are shortcomings in this article, please give your valuable opinions.