A quick start
Official document: mp.baomidou.com/
Steps:
1, create database mybatis-plus
Create table user
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT 'primary key ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT 'name',
age INT(11) NULL DEFAULT NULL COMMENT 'age',
email VARCHAR(50) NULL DEFAULT NULL COMMENT 'email'.PRIMARY KEY (id)
);
Copy the code
2.1. Insert test data
INSERT INTO user (id, name, age, email) VALUES
(1.'Jone'.18.'[email protected]'),
(2.'Jack'.20.'[email protected]'),
(3.'Tom'.28.'[email protected]'),
(4.'Sandy'.21.'[email protected]'),
(5.'Billie'.24.'[email protected]');Copy the code
3. Create a project with IDEA (the details are not mentioned here)
4. Import dependencies
<! -- Database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<! --mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<! --lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Copy the code
Special note: Using Mybatis- Plus can save us a lot of code, but try not to import both Mybatis and Mybatis- Plus dependencies!
5. Connect to the database
spring.datasource.username=root
spring.datasource.password=426457
spring.datasource.url=jdbc:mysql://localhost:3306/work? useSSl=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Copy the code
6. No need to write services, Impl, and Mapper with Mybatis plus
pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private long id;
private String name;
private int age;
private String email;
@Version
private int version;
@TableLogic// Logical delete
private int deleted;
}
Copy the code
Mapper interfaces
@Repository // represents the persistence layer
public interface UserMapper extends BaseMapper<User> {}Copy the code
To scan all interfaces under our Mapper package on the main startup class
@MapperScan("com.lyw.Mapper") // Scan the Mapper folder
@SpringBootApplication
public class MybatisPlusApplication {
public static void main(String[] args) { SpringApplication.run(MybatisPlusApplication.class, args); }}Copy the code
Test in the test class
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
UserMapper userMapper;
@Test
void contextLoads(a) {
// Query all users
List<User> users = userMapper.selectList(null); users.forEach(System.out::println); }}Copy the code
2. Configure logs
Now that we don’t need to write our own SQL statements, to see how the SQL executes, we need to turn on the log, right
# config log
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
Copy the code
After the configuration is complete, you can see what the internal automatically generated SQL statement looks like
Three, add, delete, change, check
1.Increasing (insert)
@Test
public void testInsert(a) {
User user = new User();
user.setName("Dainel");
user.setAge(3);
user.setEmail("[email protected]");
int result = userMapper.insert(user);// Help us automatically generate id
System.out.println(result);// The number of rows affected
System.out.println(user);// Discovery: the ID is automatically backfilled
}
Copy the code
The value of id is not set (if the id is set to increment).
The rest of the source code interpretation
public enum IdType {
AUTO(0), // The database ID is automatically increased
NONE(1), // The primary key is not set
INPUT(2), // Enter the id manually and write the id yourself
ID_WORKER(3), // The default global unique ID
UUID(4), // Globally unique ID UUID
ID_WORKER_STR(5); // ID_WORKER string notation
}
Copy the code
2. Update operation
@Test
/* Update operation */
void updateUser(a) {
// Query the user to be updated
User user = userMapper.selectById(7);
// The value to update
user.setName("demo");
user.setAge(21);
// Perform the update
userMapper.updateById(user);
}
Copy the code
3. Automatic filling
Usually when we’re working with create time and change time, we don’t want to change it manually and that’s when we need to use auto-fill
Method 1: Directly change the database Settings
Add create_time,update_time; Note that the updated timestamp is checked
2. Test the insert method again (don’t forget to update the entity class)
Method 2: Change the code
1. Delete the default values and update the database
2. Add annotations to the field attributes of the entity class
// Add padding to the field
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
Copy the code
3, write processor to deal with this annotation: handler/MyMetaObjectHandler
package com.kuang.handler;
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 Don't forget to add the handler to the IOC container
public class MyMetaObjectHandler implements MetaObjectHandler {
// The padding strategy at insertion time
@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);
}
// The populating strategy for the update
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ...");
this.setFieldValByName("updateTime".newDate(), metaObject); }}Copy the code
Test again, success!
4. Optimistic Lock
Optimistic Lock: As the name implies, it always thinks there will be no problem, no matter what to do to lock! If something goes wrong, update the value test again!
Pessimistic lock: As the name implies, it always thinks there is always a problem, no matter what to lock! Operate again!
Optimistic lock implementation:
- When the record is fetched, the current version is retrieved
- When you update, take this version with you
- When performing an update, set version = newVersion where version = oldVersion
- If the version is incorrect, the update fails
Testing:
Add a version field to the database with an initial value of 1
Add the version annotation to the entity class
@Version // Optimistic lock version annotation
private Integer version;
Copy the code
3. Write config/MybatisPlusConfig
@Configuration
public class MybatisPlusConfig {
// Register the lockup
@Bean
public OptimisticLockerInterceptor optimisticLockerInnerInterceptor(a){
return newOptimisticLockerInterceptor(); }}Copy the code
Testing:
Success: Changed the name of Number 2 to Lipu. View the version change
@Test
void OptimisticLock(a) {
// Query the user to be updated
User user = userMapper.selectById(2);
// Modify user attributes
user.setName("lipu");
user.setAge(28);
// Commit the update
userMapper.updateById(user);
}
Copy the code
Failure: in the case of multithreading
// Test optimistic lock failed! Under the multithreading
@Test
public void testVersionFall(a) {
/ / thread 1
User user1 = userMapper.selectById(9);
user1.setName("fan111");
user1.setAge(14);
/ / thread 2
User user2 = userMapper.selectById(9);
user2.setName("fan222");
user2.setAge(24);
userMapper.updateById(user2);
// Spin lock to try to commit many times!
userMapper.updateById(user1); // If there is no optimistic lock, the queue-jumping thread will be overwritten
}
Copy the code
Select * from (select)
// Test the query
@Test
public void testSelectById(a){
User user = userMapper.selectById(1);
System.out.println(user);
}
// Batch query
@Test
public void testSelectByBatchIds(a){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1.2.3));
users.forEach(System.out::println);
}
// Use map as one of the conditional queries
@Test
public void testSelectByMap(a){
HashMap<String, Object> map = new HashMap<>();
// Custom to query
map.put("name"."Dainel");
map.put("age"."6");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
Copy the code
6, paging query
Pagination is often used in web pages. Here are a few common ways
- Limit was originally used for paging
- PageHelper third-party plugin
- MybatisPlus has a built-in paging plug-in
There is a built-in paging plug-in using MybatisPlus
1. Configure the paging plug-in
// Paging plug-in
@Bean
public PaginationInterceptor paginationInterceptor(a) {
return new PaginationInterceptor();
}
Copy the code
2, write paging query statements
// paging query
@Test
void selectLimit(a) {
Page<User> page = new Page<User>(2.5);
// Get the number of entries queried through paging
page.getRecords().forEach(System.out::println);
/ / query
userMapper.selectPage(page, null);
// Query the total number of entries
System.out.println("Total number of items:" + page.getTotal());
}
Copy the code
7. Delete
// Test delete
@Test
public void testdelete(a){
userMapper.deleteById(6L);
}
// Test batch delete
@Test
public void testdeleteBatchId(a){
userMapper.deleteBatchIds(Arrays.asList(1.14));
}
// Delete using map
@Test
public void testDeleteByMap(a){
HashMap<String, Object> map = new HashMap<>();
map.put("name"."KUANG");
userMapper.deleteByMap(map);
}
Copy the code
8. Logical deletion
Physical delete: Directly remove from the database
Logical delete: it is not removed from the database, but made valid by a variable! deleted=0 –> deleted=1
Administrators can view deleted records! Prevent data loss! It’s like a recycle bin!
Steps:
1. Add a deleted field in the database. The default value is 0
2. Modify the entity class
// Table logical drop
@TableLogic
private int deleted;
Copy the code
3. Add the configuration
// Remove the component logically
public ISqlInjector sqlInjector(a){
return new LogicSqlInjector();
}
Copy the code
4. Add the configuration in properties
Delete the configuration logic
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
Copy the code
5, test,
// Logical delete
@Test
void deleteLogic(a) {
userMapper.deleteById(1);
}
Copy the code
Delete the success
The query result for user 1 is 0
Performance analysis plug-in
In the usual development process, will encounter some slow SQL problems. The purpose of the performance analysis plug-in is to output each SQL statement and its execution time, and if this time is exceeded, the execution will be stopped. 1. Import the plug-in
// SQL execution efficiency plug-in
@Bean
@Profile({"dev","test"})
public PerformanceInterceptor performanceInterceptor(a){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100); //ms Sets the maximum time for SQL execution
performanceInterceptor.setFormat(true); // Whether to format
return performanceInterceptor;
}
Copy the code
Note: The environment configured in Springboot is dev or test
# Development environment
spring.profiles.active=dev
Copy the code
2. Test use
// paging query
@Test
void selectLimit(a) {
Page<User> page = new Page<User>(1.5);
// Get the number of entries queried through paging
page.getRecords().forEach(System.out::println);
/ / query
userMapper.selectPage(page, null);
// Query the total number of entries
System.out.println("Total number of items:" + page.getTotal());
}
Copy the code
Whenever the time is exceeded, an exception is thrown.
Performance analysis plugins can be used to improve efficiency. In the new version of MP, this widget has been removed and druid can be used
Code generators
AutoGenerator is the code generator of MyBatis-Plus, through which the code of Entity, Mapper, Mapper XML, Service, Controller and other modules can be generated quickly. Greatly improved the development efficiency.
Pom dependencies needed
<dependencies> <! --> <dependency> <groupId> IO. Springfox-swagger2 </artifactId> < version > 2.7.0 < / version > < / dependency > < the dependency > < groupId >. IO springfox < / groupId > < artifactId > springfox swagger - UI < / artifactId > < version > 2.7.0 < / version > < / dependency > <! <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> The < version > 2.0 < / version > < / dependency > <! <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> < the dependency > < groupId > com. Baomidou < / groupId > < artifactId > mybatis - plus - the boot - starter < / artifactId > < version > 3.0.5 < / version > </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>Copy the code
The test code
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
// Automatic code generator
public class zhixiCode {
public static void main(String[] args) {
// A code automatic generator object needs to be built
AutoGenerator mpg = new AutoGenerator();
// Configure the policy
// 1
GlobalConfig gc = new GlobalConfig();
// Which directory to output the code to (get the project directory)
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
// Set the author
gc.setAuthor("Zhang Zhixi");
// Whether to open explorer (open directory after generating code)
gc.setOpen(false);
// Whether to overwrite the original file
gc.setFileOverride(false);
// Remove the IService I prefix (re)
gc.setServiceName("%sService");
// Set the field
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
/ / configuration swagger
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2. Set the data source
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("JDBC: mysql: / / 182.92.209.212:3306 / mybatis_plus? useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("Password");
// Database type
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// package configuration (only need to change entity class name and package name and database configuration)
PackageConfig pc = new PackageConfig();
/ / module name
pc.setModuleName("blog");
// Set the package to be placed under
pc.setParent("com.kuang");
// Set the entity class
pc.setEntity("entity");
/ / set the mapper
pc.setMapper("mapper");
// Set up the Services layer
pc.setService("service");
// Set the controller layer
pc.setController("controller");
mpg.setPackageInfo(pc);
//4
StrategyConfig strategy = new StrategyConfig();
// Set the name of the table to be mapped
strategy.setInclude("blog_tags"."course"."links"."sys_settings"."user_record"." user_say");
// Set the underline to camel name
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// Automatic lombok;
strategy.setEntityLombokModel(true);
// Set the logical deletion column name
strategy.setLogicDeleteFieldName("deleted");
// Automatically populate the configuration
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);/* Create time */
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);/* Change the time */
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
// Add auto-fill
strategy.setTableFillList(tableFills);
/ / optimistic locking
strategy.setVersionFieldName("version");/* Sets the version field name */
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);// localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); / / execution}}Copy the code
This is the strength of MP!!