1, Quick start
mybatis+MP
Step 1:
Based on the original code, let the XXXMapper (such as UserMapper) interface inherit the BaseMapper interface, so you can use the following methods defined in BaseMapper:
Note that inheriting BaseMapper requires specifying the generic type of the entity class of the operation
public interface UserMapper extends BaseMapper<User> { List<User> findAll(); }
Step 2: use MybatisSqlSessionFactoryBuilder in MP instead of SqlSessionFactoryBuilder in mybatis to build SqlSessionFactory objects
The integration is completed here. It can still be executed according to the original writing method of mybatis. If you want to use the method in BaseMapper to realize the function, you need to use @ TableName on the entity class object to specify the table name of the table to be operated., Otherwise, the database name will be found by default A lowercase table of entity classes
This is because the functions in baseMapper are used, and the sql statements are written by the mp plug-in, and we need to specify the table name.
spring+mybatis+MP
On the basis of integrating mybatis in spring, change the SqlSessionFactoryBean provided by mybatis to use the MybatisSqlSessionFactoryBean provided by mybatis plus
<!--Use here MP Provided sqlSessionFactory,It's done Spring And MP Integration of--> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean>
2, CRUD operation
The following is a detailed explanation of the methods in BaseMapper:
Add: insert
Note that the return value of this method is not the id value after data insertion, but the number of rows affected by the database
The real id will be backfilled into the entity object after calling the method, so you only need to use entity to obtain the id of the newly inserted data Getid().
To realize Id self growth, it needs to be combined with @ TableId annotation
@TableId source code:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) public @interface TableId { //Specify the field name of the corresponding database String value() default ""; //Specify id generation policy IdType type() default IdType.NONE; } public enum IdType { AUTO(0),//id self growth NONE(1),//The type is not set with primary key INPUT(2),// User input ID /* The following two types are automatically filled only when the inserted object ID is empty. */ ASSIGN_ID(3), ASSIGN_UUID(4); private final int key; private IdType(int key) { this.key = key; } public int getKey() { return this.key; } }
@TableField source code:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) public @interface TableField { /*Specify the corresponding database field, The property name used to resolve the problem does not match the property name of the class*/ String value() default ""; /*Declare that the attribute has no corresponding field in the database, This field does not need to be considered when inserting*/ boolean exist() default true; /*Specify that this field does not need to be queried during query*/ boolean select() default true; String condition() default ""; String update() default ""; FieldStrategy insertStrategy() default FieldStrategy.DEFAULT; FieldStrategy updateStrategy() default FieldStrategy.DEFAULT; FieldStrategy whereStrategy() default FieldStrategy.DEFAULT; FieldFill fill() default FieldFill.DEFAULT; boolean keepGlobalFormat() default false; String property() default ""; JdbcType jdbcType() default JdbcType.UNDEFINED; Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class; boolean javaType() default false; String numericScale() default ""; }
change
Update by id: updateById
This method updates the non null fields in the entity according to the id of the entity.
For example:
@Test public void testUpdateById() { User user = new User(); user.setId(6L); //Primary key user.setAge(21); //Updated fields //Update according to id, update non null fields this.userMapper.updateById(user); }
Update according to conditions: int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) WrapperupdateWrapper);
Using QueryWrapper
@Test public void testUpdate() { User user = new User(); user.setAge(22); //Updated fields //Updated conditions QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("id", 6); //Perform update operation int result = this.userMapper.update(user, wrapper); } }
Using UpdateWrapper
@Test public void testUpdate() { //Updated conditions and fields UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.set("age", 18).set("name","Zhang San").eq("id", 6); //Perform update operation int result = this.userMapper.update(null, wrapper); }
Delete:
deleteById: delete by id
@Test public void testDeleteById() { //Perform delete operation int result = this.userMapper.deleteById(6L); System.out.println("result = " + result); }
deleteByMap: use map as the parameter
@Test public void testDeleteByMap() { Map<String, Object> columnMap = new HashMap<>(); columnMap.put("age",20); columnMap.put("name","Zhang San"); //Set the element in the columnMap as the deletion condition, and the relationship between multiple elements is and int result = this.userMapper.deleteByMap(columnMap); System.out.println("result = " + result); }
delete: use QueryWrapper
@Test public void testDeleteByMap() { User user = new User(); user.setAge(20); user.setName("Zhang San"); //Wrap the entity object as an operating condition QueryWrapper<User> wrapper = new QueryWrapper<>(user); int result = this.userMapper.delete(wrapper); System.out.println("result = " + result); }
deleteBatchIds: deletes batches by id
Method definition
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable>idList);
Use the incoming ids collection. Note that ids cannot be an empty collection or null
@Test public void testDeleteByMap() { //Batch deletion based on id set int result = this.userMapper.deleteBatchIds(Arrays.asList(1L,10L,20L)); System.out.println("result = " + result); }
check
selectById
@Test public void testSelectById() { //Query data by id User user = this.userMapper.selectById(2L); System.out.println("result = " + user); }
selectBatchIds
@Test public void testSelectBatchIds() { //Batch query based on id set List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L)); for (User user : users) { System.out.println(user); } }
selectOne
@Test public void testSelectOne() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.eq("name", "Li Si"); //Query a piece of data according to the criteria. If the result exceeds one, an error will be reported User user = this.userMapper.selectOne(wrapper); System.out.println(user); }
selectCount
@Test public void testSelectCount() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.gt("age", 23); //Older than 23 //Query the number of data according to criteria Integer count = this.userMapper.selectCount(wrapper); System.out.println("count = " + count); }
selectList
@Test public void testSelectList() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.gt("age", 23); //Older than 23 //Query data according to criteria List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println("user = " + user); } }
selectPage
Configure paging plug-in
@Configuration @MapperScan("cn.edu.szu.Test.Mapper") //Set the scanning package of mapper interface public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
@Test public void testSelectPage() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.gt("age", 20); //Older than 20 Page<User> page = new Page<>(1,1);//Page(currentPage,pageSize) //Query data according to criteria IPage<User> iPage = this.userMapper.selectPage(page, wrapper); System.out.println("Total number of data:" + iPage.getTotal()); System.out.println("Total pages:" + iPage.getPages()); List<User> users = iPage.getRecords(); for (User user : users) { System.out.println("user = " + user); } }
3, Disposition
Basic configuration
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <!--MyBatis Configuration file location. Please configure its path to configLocation Yes.--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!--MyBatis Mapper Corresponding XML File location. be careful: Maven The scan path of a multi module project needs to be classpath*: Start (i.e. load multiple) jar Under the bag XML (file) --> <property name="mapperLocations" value="classpath*:mybatis/*.xml"/> <!--MyBaits Alias package scan path--> <property name="typeAliasesPackage" value="com.baomidou.mybatisplus.samples.quickstart.entity"/> </bean>
DB policy configuration
<!--Use here MP Provided sqlSessionFactory,It's done Spring And MP Integration of--> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="globalConfig"> <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"> <property name="dbConfig"> <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"> <!--Global default primary key type, After setting, you can omit the in the entity object@TableId(type=IdType.AUTO)to configure--> <property name="idType" value="AUTO"/> <!--Table name prefix, which can be omitted after global configuration@TableName()to configure--> <property name="tablePrefix" value="tb_"/> </bean> </property> </bean> </property> </bean>
4, Conditional constructor Wrapper
The interface has two important implementation classes: AbstractWrapper and AbstractChainWrapper. It mainly studies AbstractWrapper
allEq
allEq(Map<R, V> params) allEq(Map<R, V> params, boolean null2IsNull) allEq(boolean condition, Map<R, V> params, boolean null2IsNull) /* null2IsNull :Specifies whether null values are to be satisfied as a condition When true: isNull will be used as one of the conditions in the where part of the generated sql statement When it is false: this field will not be used as a condition to be met */ allEq(BiPredicate<R, V> filter, Map<R, V> params) allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) /*filter: Filter function, whether to allow the field to be passed into the comparison condition, which is often replaced by lambda expression For example: alleq ((k, V) - > k.equals ("name"), {ID: 1, name: "Lao Wang", age:null}) As described above, in the key value of the parameter map on the right, only the name field is used as the filter criteria. */
Basic comparison operation
eq: equal to=
neq: not equal to < >
gt: greater than >
ge: greater than or equal to >=
lt: less than<
le: less than or equal to<=
between: BETWEEN 1 AND 2
notBetween: NOT BETWEEN 1 AND 2
In: field in (value. Get (0), value get(1), …)
notIn: field NOT IN (v0, v1,...)
Fuzzy query
like:
Equivalent to LIKE% value%
Example: like("name", "Wang") - > name like '% Wang%'
notLike:
Equivalent to NOT LIKE '% value%'
Example: notLike("name", "Wang") - > name not like '%, Wang%'
likeLeft:
Equivalent to LIKE '% value'
Example: likeLeft("name", "King") - > name like '% King'
likeRight:
Equivalent to LIKE 'value%'
Example: likereight ("name", "Wang") - > name like "Wang%"
sort
orderBy:
Sorting: ORDER BY field
Example: orderBy(true, true, "id", "name") - > order by id ASC, name ASC
orderByAsc
Sorting: ORDER BY field,... ASC
Example: orderByAsc("id", "name") - > order by id ASC, name ASC
orderByDesc
Sorting: ORDER BY field,... DESC
Example: orderByDesc("id", "name") - > order by id DESC, name desc
Logical query
or
Splice OR
Actively calling or means that the next method is not connected with and! (if or is not called, and connection is used by default.)
//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name = ? OR age = ? wrapper.eq("name","Li Si").or().eq("age", 24);
select
//SELECT id,name,age FROM tb_user WHERE name = ? OR age = ? wrapper.eq("name", "Li Si")`Insert code slice here` .or() .eq("age", 24) .select("id", "name", "age");
5, ActiveRecord
The main idea of ActiveRecord is:
1. Create a class for each database table, and each object instance of the class corresponds to a row of records in the database table; Generally, each Field of the table has a corresponding Field in the class;
2.ActiveRecord is also responsible for persisting itself. ActiveRecord encapsulates the access to the database, namely CURD;
3.ActiveRecord is a domain model that encapsulates some business logic;
Use of ActiveRecord:
You can use some defined CRUD operations by inheriting the entity object from the Model.
@Data @NoArgsConstructor @AllArgsConstructor public class User extends Model<User> { private Long id; private String userName; private String password; private String name; private Integer age; private String email; }
@Test public void testAR() { //select User user = new User(); user.setId(2L); User user2 = user.selectById(); //insert user.setName("Liu Bei"); user.setAge(30); user.setPassword("123456"); user.setUserName("liubei"); user.setEmail("liubei@itcast.cn"); boolean insert = user.insert(); //update user.setId(8L); user.setAge(35); boolean update = user.updateById(); //delete user.setId(1L); } //Query by criteria QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); userQueryWrapper.le("age","20"); List<User> users = user.selectList(userQueryWrapper);
6, Plug in
Interceptor plug-in
Types of methods that interceptors can intercept:
-
Method of intercepting actuator:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) -
Processing of interception parameters:
ParameterHandler (getParameterObject, setParameters) -
Processing of interception result set:
ResultSetHandler (handleResultSets, handleOutputParameters) -
Processing of intercepting Sql syntax Construction:
StatementHandler (prepare, parameterize, batch, update, query)
Use of interceptors:
@Intercepts({@Signature( type= Executor.class, method = "update", args = {MappedStatement.class,Object.class})}) public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { //Interception method, location of specific business logic writing return invocation.proceed(); } @Override public Object plugin(Object target) { //Create a proxy object for the target object to add the current interceptor to the object /*This method will be called four times, corresponding to the above four method types*/ return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { //Property settings } }
Execute analysis plug-in
The MP provides a plug-in for the analysis of SQL execution, which can be used to block the operation of updating and deleting the whole table. When updating and deleting the whole table, the plug-in will block the operation and throw an exception to prevent misoperation.
be careful:
The plug-in is only applicable to the development environment, not the production environment.
to configure:
@Bean public SqlExplainInterceptor sqlExplainInterceptor(){ SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor(); List<ISqlParser> sqlParserList = new ArrayList<>(); // Attack SQL, block parser and join parsing chain sqlParserList.add(new BlockAttackSqlParser()); sqlExplainInterceptor.setSqlParserList(sqlParserList); return sqlExplainInterceptor; }
Performance analysis plug-in
The performance analysis interceptor is used to output each SQL statement and its execution time. The maximum execution time can be set. If it exceeds the time, an exception will be thrown.
<configuration> <plugins> <!-- SQL Perform performance analysis and use the development environment, which is not recommended online. maxTime refer to sql Maximum execution time --> <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor"> <property name="maxTime" value="100" /> <!--SQL Format default false--> <property name="format" value="true" /> </plugin> </plugins> </configuration>
Optimistic lock plug-in
Requirements: solve the problem of modifying the same data concurrently.
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
If the version is incorrect, the update fails
to configure:
xml configuration:
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
Annotation configuration:
@Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }
use:
1. Add the version field on the table to be operated and set the initial value to 1
2. Add Version attribute on entity class and use @ Version annotation
@Version private Integer version;
Auto fill function
Sometimes we may have such requirements. When inserting or updating data, we hope that some fields can be filled with data automatically, such as password and version
Wait.
1. Add @ TableField annotation
@TableField(fill = FieldFill.INSERT) //Populate when inserting data private String password; public enum FieldFill { DEFAULT, INSERT, UPDATE, INSERT_UPDATE }
2. Write MyMetaObjectHandler
@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { Object password = getFieldValByName("password", metaObject); if(null == password){ //The field is empty and can be filled in setFieldValByName("password", "123456", metaObject); } } @Override public void updateFill(MetaObject metaObject) { } }
Logical deletion
When developing the system, sometimes when realizing the function, the deletion operation needs to realize logical deletion. The so-called logical deletion is to mark the data as deletion, rather than the real physical deletion (non DELETE operation). The status conditions need to be carried during the query to ensure that the marked data is not queried. The purpose of this is to prevent the data from being really deleted.
1. Add the delete field to the database table
2. Use @ TableLogic annotation for the corresponding fields in the entity class
@TableLogic private Integer deleted;
application. Configuration in properties:
# Logical deleted value (default = 1) mybatis-plus.global-config.db-config.logic-delete-value=1 # Logical undeleted value (default is 0) mybatis-plus.global-config.db-config.logic-not-delete-value=0