MybatisPlus and code automatic generator
- MybatisPlus
-
- Introduction to MybatisPlus
- MybatisPlus basic configuration
- The first MybatisPlus case
-
- Automatically generate yml and startup classes---JBLSpringBootAppliacation plug-in
- Service extends IService<Pojo>
- ServiceImpl extends ServiceImpl<Mapper,Pojo> implents Service
- Mapper extends BaseMapper<Pojo>
- MP condition query API
- Controller encapsulates Wrapper objects and query conditions
- Passed the test using PostMan
- Four important notes
- Code generator
- Mapper adds query supplementary exercises
MybatisPlus
Introduction to MybatisPlus
MybatisPlus is an enhancement to the Mybatis framework. It does not change the content of the Mytatis framework. It just makes development more convenient and improves development efficiency. The addition, deletion, modification and query operations of single table queries have been encapsulated in MybatisPlus, and we do not need to write any more. For operations between multiple tables, we also need to write mapper and sql. Wrapper can be regarded as some conditions of encapsulation, including some code methods of sql statements, which are placed below.
Official page:https://baomidou.com/,Bottom side is its characteristics:
- Non-intrusive: only enhancements and no changes will be made, and will not affect existing projects.
- Powerful CRUD operation: Built-in universal Mapper, single-table CRUD operation can be implemented with a small amount of configuration
- Support Lambda: write query conditions without worrying about mistyping fields
- Support automatic generation of primary keys
- Built-in paging plugin
MybatisPlus basic configuration
MybatisPlus starting dependencies
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
Yaml configuration
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_demo
username: root
password: root
Configure table name mapping
@Tablename("")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("tbl_product")
public class Product {
@TableId(value = "id",type = IdType.ASSIGN_ID)
// @TableId(value = "id",type = IdType.AUTO)
private Long id;
private String pname;
private String brand;
private Double price;
private Integer num;
private Integer online;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date lastUpdateTime;
private Integer version;
private Integer deleted;
@TableField(exist = false)
private String desc;
}
Mapper inherits the BaseMapper<Entity Class> interface
//@Mapper
public interface ProductMapper extends BaseMapper<Product> {
}
The first MybatisPlus case
Automatically generate yml and startup classes—JBLSpringBootAppliacation plug-in
Service extends IService
In order to simplify service code writing, mybatisPlus provides a universal Service CRUD packageIServiceinterface
- Further encapsulate CRUD using
get 查询单行
remove 删除
list 查询集合
page 分页
prefix naming method to distinguishMapper
layers to avoid confusion
Classification | method | describe |
---|---|---|
New | boolean save(T entity) | Added, entity object |
boolean saveOrUpdate(T entity) | If the id exists, update the record; if not, insert a record. | |
boolean saveBatch(Collection entityList) | Insert (batch), 1000 pieces of data can be saved at a time by default | |
Revise | boolean updateById(T entity) | Modify by ID |
boolean update(T entity,Wrapper updateWrapper) | Modify according to conditions | |
Inquire | T getById(Serializable id) | Query by ID |
List listByIds(Collection idList) | Query (batch query based on ID) | |
List list() | Search all | |
List list(Wrapper queryWrapper) | Conditional query | |
delete | boolean removeById(Serializable id) | Delete by ID |
boolean removeByIds(Collection idList) | Delete (batch delete based on ID) | |
boolean remove(Wrapper queryWrapper) | Delete based on conditions |
public interface ProductService extends IService<Product> {
}
ServiceImpl extends ServiceImpl<Mapper,Pojo> implents Service
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
}
Mapper extends BaseMapper
**BaseMapper<T>**:通用 CRUD 封装 `BaseMapper` 接口, 泛型 `T` 为任意实体对象
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
}
MyBatisPlus provides the Wrapper 条件构造器
interface for setting conditions
- QueryWrapper LambdaQueryWrapper sets query and deletion conditions
- UpdateWrapper LambdaUpdateWrapper sets modification conditions
MP condition query API
AbstractWrapper provides a large number of methods for setting conditions
method | illustrate |
---|---|
eq (equals) | equal to = |
ne (not equals) | Not equal to <> |
gt (greater than) | Greater than> |
ge (greater equals) | Greater than or equal to>= |
lt (less than) | less than < |
le (less equals) | Less than or equal to<= |
between | between…and… |
like | Fuzzy query LIKE |
in | IN query |
swimming | NOT IN query |
isNull | NULL value query |
isNotNull | IS NOT NULL |
or | or |
public interface ProductMapper extends BaseMapper<Product> {
}
Controller encapsulates Wrapper objects and query conditions
@Component
public class MyMateObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
metaObject.setValue("createTime", new Date());
metaObject.setValue("lastUpdateTime", new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
metaObject.setValue("lastUpdateTime", new Date());
}
}
Passed the test using PostMan
Four important notes
@TableName (table name)
When the entity class names corresponding to the database table are the same, they can also be omitted, mainly to establish a mapping relationship between the data table and the entity class.
yml global configuration TableName prefix (keyword table-prefix)
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
@TableId (value="can be named if inconsistent", type= 3 common primary key auto-increment attributes 2 4 5 )
Mainly to set the auto-increment strategy of the primary key field in the data table. There are three common ones 2 4 5
value | describe |
---|---|
NONE | 默认值 Equivalent to INPUT+ASSIGN_ID |
AUTO | Database primary key auto-increment |
INPUT | Manually set primary key values |
ASSIGN_ID | The corresponding type of the primary key can be a numeric type or a numeric type string The unique primary key is generated by the java client and the underlying layer is based on the snowflake algorithm |
ASSIGN_UUID | The generated primary key value contains a string of numbers and lettersUUID Example: b463ec84690de187e3f9ad9229327d15 |
yml global configuration TableId (keyword id-type)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 标准注解
global-config:
db-config:
table-prefix: tbl_
id-type: auto
Annotation configuration (annotations will prevail in case of conflict)
When the id field and the attribute name are inconsistent, the value field can also be used for mapping.
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
@TableFiled (4 common properties)
Attributes | type | default value | describe |
---|---|---|---|
value | String | “” | Database field name, you can omit it if it has the same name |
exist | boolean | true | Whether it is a database table field. If the field does not exist in the table, it must be set to false. CRUD will not include this field. |
fill | Enum | FieldFill.DEFAULT | Field auto-fill strategy, values will not be auto-filled by default |
value
Correspond between entity class attributes and database table fields
select()
The default value is true, which can be set to false to specify a field not to be queried when querying, for example: password or sensitive field
exist()
When there is a certain attribute on the attribute of the entity class but there is no corresponding field in the database table field, the setting can be false.
fill
Official sample code:https://baomidou.com/pages/4c6bcf/
Automatically fill in certain fields, such as create_time , there are several common values (2 4 commonly used)
value | describe |
---|---|
DEFAULT | Not processed by default |
INSERT | Populate fields on insert |
UPDATE | Populate fields on update |
INSERT_UPDATE | Populate fields on insert and update |
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date lastUpdateTime;
Autofill configuration class
package com.itheima.mp.config;
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.util.Date;
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "lastUpdateTime", Date.class, new Date()); // 起始版本 3.3.0(推荐使用)
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "lastUpdateTime", Date.class, new Date()); // 起始版本 3.3.0(推荐)
}
}
@TableLogic (logical deletion)
Logical deletion: Set for data字段
to identify whether the data is available. The default status is available. When deleting, set the status field to unavailable and the data will still remain in the database
-- 删除改成更新状态
UPDATE tbl_product SET deleted=1 WHERE id=? AND deleted=0
-- 查询需要添加一个逻辑删除条件
SELECT * FROM tbl_product WHERE deleted=0
Add tombstone fields to table
Modify entity class
Add the corresponding field to the entity class, and use the @TableLogic
annotation to identify this as a tombstone field
@TableLogic
private Integer deleted;
Global configuration logical deletion (keyword logic)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
table-prefix: tbl_
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
Pagination query plug-in
Mybatis has a built-in plug-in specifically for paging, which is very simple to use. It implements paging based on the interceptor principle.
Official sample code:https://baomidou.com/pages/97710a/#paginationinnerinterceptor
Add paging plugin interceptor
// MP配置类
@Configuration
public class MybatisPlusConfig {
// MyBatisPlust拦截器配置
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
Pagination test
@Test
public void test() {
Page<Product> page = new Page<>(2,5); //分页参数
LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper();
productMapper.selectPage(page, wrapper);// 返回那个page
System.out.println(page.getTotal());
List<Product> records = page.getRecords();
records.forEach(System.out::println);
}
Code generator
MybatisPlus plug-in
After installing the plug-in, restart an IDEA
Configure data source
code generation
You can click check filed to choose whether to generate a certain field
Mapper adds query supplementary exercises
Lambda expressions can be used
API
AbstractWrapper provides a large number of methods for setting conditions
method | illustrate |
---|---|
eq (equals) | equal to = |
ne (not equals) | Not equal to <> |
gt (greater than) | Greater than> |
ge (greater equals) | Greater than or equal to>= |
lt (less than) | less than < |
le (less equals) | Less than or equal to<= |
between | between…and… |
like | Fuzzy query LIKE |
in | IN query |
swimming | NOT IN query |
isNull | NULL value query |
isNotNull | IS NOT NULL |
or | or |
Basic query
Query optimization - simplified judgments (there are a lot of if judgments in the query, simplify writing)
Query optimization-lambda query
Query Optimization-Chain Programming
Set query fields
group sort sort
Homework
Tips: Use the method name + return value type provided by BaseMpper to determine whether the requirements can be achieved
Exercise 1: Query the product name starting with OPPO, the price > 1500, and the product is on the shelf, the results are sorted in descending order by price selectList(wrapper)
@Test
public void test() {
QueryWrapper<Product> wrapper = new QueryWrapper<>();
wrapper.likeRight("pname", "OPPO")
.gt("price",1500D)
.eq("online","1")
.orderByDesc("price");
List<Product> products = productMapper.selectList(wrapper);
products.forEach(System.out::println);
}
Exercise 2: Query the product information whose id contains 1,2,6,8 and pname is not null and is on the shelves selectList(wrapper)
@Test
public void testDemo2() {
QueryWrapper<Product> wrapper = new QueryWrapper<>();
wrapper.in("id", "1", "2", "6", "8")
.isNotNull("pname")
.eq("online","1");
List<Product> products = productMapper.selectList(wrapper);
products.forEach(System.out::println);
}
Exercise 3: Query product information whose ID contains 1,2,6,8 selectBatchIds(Collection)
@Test
public void testDemo3() {
QueryWrapper<Product> wrapper = new QueryWrapper<>();
// wrapper.like("id",1)
// .or()
// .like("id",2)
// .or()
// .like("id",6)
// .or()
// .like("id",8);
List<Long> list = new ArrayList();
list.add(1L);
list.add(2L);
list.add(6L);
list.add(8L);
List<Product> products = productMapper.selectBatchIds(list);
products.forEach(System.out::println);
}
Exercise 4: Count the quantity of items with price > 5000 selectCount(wrapper)
@Test
public void testDemo4() {
QueryWrapper<Product> wrapper = new QueryWrapper<>();
wrapper.gt("price", 5000.0);
int sum = productMapper.selectCount(wrapper);
System.out.println(sum);
}
Condition modification
conditional delete
Use updateWrapper and LambdaUpdateWrapper for modification
Query and delete using queryWrapper or LambdaQueryWrapper