What is Mybatis Plus

Website: baomidou.com/

MyBatis-Plus (Opens New Window) (MP for short) is a MyBatis enhancement tool, based on MyBatis only enhancement without change, to simplify development, improve efficiency.

features

  • No intrusion: only enhancements are made, no changes are made, and its introduction will not affect the existing project, as smooth as silk
  • Low loss: Basic CURD will be injected automatically upon startup, with basically no loss in performance and direct object-oriented operation
  • Powerful CRUD operations: built-in universal Mapper, universal Service, only through a small amount of configuration can achieve a single table most CRUD operations, more powerful condition constructor, to meet all types of use requirements
  • Support Lambda form call: through Lambda expressions, it is convenient to write all kinds of query conditions, without worrying about field write errors
  • Support automatic generation of primary keys: support up to four primary key policies (including distributed unique ID generator – Sequence), can be freely configured, perfect solution to the primary key problem
  • Support for ActiveRecord mode: Support for ActiveRecord form calls, entity classes only need to inherit from Model classes to perform powerful CRUD operations
  • Support custom global universal operations: support Write once (use anywhere)
  • Built-in code generator: using code or Maven plug-in can quickly generate Mapper, Model, Service, Controller layer code, support template engine, more than a lot of custom configuration you to use
  • Built-in paging plug-in: Based on MyBatis physical paging, developers do not need to care about specific operations, after configuring the plug-in, write paging is equal to ordinary List query
  • The paging plug-in supports a variety of databases: MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, Postgre, SQLServer, etc
  • Built-in performance analysis plug-in: outputs Sql statements and their execution time. It is recommended to enable this function during development and testing to quickly find out slow queries
  • Built-in global interception plug-in: provides intelligent analysis and blocking of delete and UPDATE operations on all tables, and can customize interception rules to prevent misoperations

Two, simple use cases

Only need to add Mybatis-Plus dependency (no need to add Mybatis dependency, Mybatis-Plus dependency is already included), write table mapping entity class and Mapper statement (inherit BaseMapper) to achieve access to the database, BaseMapper already includes basic SQL methods without having to write mapper.xml.

Database table structure

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `avatar` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL.PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `UK_ob8kqyqqgmefl0aco34akdtpe` (`email`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
Copy the code

1. Introduce dependencies

  • Import the Springboot Starter parent project

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>From 2.4.8</version>
            <relativePath/> <! -- lookup parent from repository -->
        </parent>
    Copy the code
  • Introduction of depend on

    Only need to introduce Spring Boot, MyBatis-Plus, database (Mysql) dependency.

    <! -- springboot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <! -- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> The < version > 3.3.1 < / version > < / dependency > <! -- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <! -- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> The < version > 1.18.10 < / version > < / dependency >Copy the code
  • Full dependency file

<? The XML version = "1.0" encoding = "utf-8"? > < project XMLNS = "http://maven.apache.org/POM/4.0.0" XMLNS: xsi = "http://www.w3.org/2001/XMLSchema-instance" Xsi: schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < the parent > < the groupId > org. Springframework. Boot < / groupId > < artifactId > spring - the boot - starter - parent < / artifactId > < version > from 2.4.8 < / version >  <relativePath/> <! -- lookup parent from repository --> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-mybatis-plus</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <! -- springboot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <! -- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> The < version > 3.3.1 < / version > < / dependency > <! -- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <! -- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> < version > 1.18.10 < / version > < / dependency > < / dependencies > < project >Copy the code

2. The entity class

@Data @Accessors(chain = true) public class User implements Serializable { /** * id * */ private Integer id; /** */ private String avatar; /** * email ** / private String email; /** * private String name; /** * private String password; /** * username ** / private String username; }Copy the code

3. UserMapper

Here you need to inherit the BaseMapper interface, which BaseMapper provides

public interface BaseMapper<T> extends Mapper<T> {
    / / insert
    int insert(T entity);
    
	// Delete by primary key
    int deleteById(Serializable id);
	// Delete the Map field
    int deleteByMap(@Param("cm") Map<String, Object> columnMap);
	// Delete via conditional Wrapper
    int delete(@Param("ew") Wrapper<T> wrapper);
	// Batch delete
    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    // Update by ID match
    int updateById(@Param("et") T entity);
	// Update matches by updating conditions
    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
	
    // Query through primary key
    T selectById(Serializable id);
	// Query through batch
    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
	// Query through Map
    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
	// Query through the query condition constructor to return the entity
    T selectOne(@Param("ew") Wrapper<T> queryWrapper);
	// Query the number of rows using the query condition constructor
    Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);
	// Query the condition constructor
    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
	// paging query
    <E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);

    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);
}
Copy the code

Usermapper. Java is based on BaseMapper. If the startup class uses the MapperScan annotation to scan the path of the Mapper, it does not need to use @mapper.

@Mapper
public interface UserMapper extends BaseMapper<User> {}Copy the code

Start class @ MapperScan (com. Stopping. “mapper”)

@SpringBootApplication
@MapperScan("com.stopping.mapper")
public class MybatisPlusApplication {
    public static void main(String[] args) { SpringApplication.run(MybatisPlusApplication.class,args); }}Copy the code

4. Configuration file

Configuring Data Source Information

spring:
  datasource:
    password: root
    username: root
    url: jdbc:mysql://localhost:3306/test? characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
Copy the code

5. Test

@SpringBootTest(classes = MybatisPlusApplication.class) class UserMapperTest { @Resource private UserMapper userMapper; @Test public void selectUser(){ userMapper.selectList(null).stream().forEach(System.out::println); }}Copy the code

The results of

User(id=1, avatar=null, [email protected], name=stopping, password=$2a$10$HMoRS.lxhl0mQ1D0uKVeFeMl7nQ1ZykhI/8N3z0AiND1HUMNCZk/y, username=admin)
User(id=2, avatar=null, [email protected], name=tom, password=123456, username=tom)
User(id=3, avatar=null, [email protected], name=job, password=123456, username=job)
Copy the code

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 quickly generated.

Through the database link, the Entity class of the database map, Entity, Mapper, Mapper XML, Service, and Controller are generated in reverse. The path where these makefiles exist can be configured.

1. Add a dependency

MyBatis-Plus removed the default dependencies between code generators and template engines from 3.0.3, requiring manual addition of dependencies

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.1</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>
Copy the code

2. Use the code generator to generate

Now generate the code related to the category table in the Test database from the code generator

CREATE TABLE `category` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `create_time` datetime DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `user_id` bigint(20) DEFAULT NULL.PRIMARY KEY (`id`) USING BTREE,
  KEY `FKpfk8djhv5natgshmxiav6xkpu` (`user_id`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
Copy the code

The generated code is shown below.

3. The test

@SpringBootTest(classes = MybatisPlusApplication.class)
class UserMapperTest {
    @Resource
    private UserMapper userMapper;
    @Resource
    private CategoryService categoryService;
    @Test
    public void selectUser(a){ categoryService.lambdaQuery().list().forEach(System.out::println); }}Copy the code

Results:

Category(id=2, createTime=null, name= default, userId=1) Category(id=3, createTime=2020-08-20T01:05:05, name= computer vision, userId=1) Category(id=4, createTime=2020-08-20T01:05:15, name=Spring, userId=1) Category(id=5, CreateTime =2020-08-20T01:05:24, userId=1) Category(id=6, createTime=2020-08-20T01:05:36, userId=1), UserId =1) Category(id=7, createTime=2020-08-20T01:05:50, name= userId) Category(id=8, createTime=2020-08-20T01:05:50, name= userId) Category(id=9, createTime=2020-08-20T01:21:44, name= server, userId=1) userId=1) Category(id=10, createTime=2020-08-20T01:23:06, name=Hibernate, userId=1) Category(id=11, CreateTime =2020-08-20T01:24:38, userId=1) Category(id=12, createTime=2020-08-20T03:16:06, userId=1) userId=1) Category(id=13, createTime=2020-09-16T03:29:30, name=java, userId=1)Copy the code

Sample code generator

/ * * *@Description GeneratorCode
 * @Author stopping
 * @date: 2021/6/28 these * /
public class GeneratorCode {
    /** * Database connection ** /
    private static final String dbUrl = "jdbc:mysql://localhost:3306/test? useUnicode=true&useSSL=false&characterEncoding=utf8";
    /** * database account ** /
    private static final String username = "root";
    /** * Database password ** /
    private static final String password = "root";
    /** * Module name ** /
    private static final String moduleName = "/spring-mybatis-plus";

    /** * <p> * Read the console contents *@param
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("Please enter" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                returnipt; }}throw new MybatisPlusException("Please enter the correct one" + tip + "!");
    }

    public static void main(String[] args) {
        // Code generator
        AutoGenerator mpg = new AutoGenerator();
        String module = scanner("Please enter module name");
        // Global configuration
        GlobalConfig gc = new GlobalConfig();
        //D:/code/springboot-orm/spring-mybatis-plus
        String projectPath = System.getProperty("user.dir")+moduleName;
        System.out.println(projectPath);
        // Set the file path and module file generation
        gc.setOutputDir(projectPath+"/src/main/java");
        gc.setAuthor("stopping");
        // Generate class name restrictions
        gc.setMapperName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImp");
        gc.setControllerName("%sController");
        gc.setXmlName("%sMapper");
        gc.setIdType(IdType.AUTO);
        gc.setOpen(false);
        // Whether to override
        gc.setFileOverride(true);
        // Entity attribute Swagger2 annotation
        gc.setSwagger2(false);
        mpg.setGlobalConfig(gc);

        // Data source configuration
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(dbUrl);
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername(username);
        dsc.setPassword(password);
        mpg.setDataSource(dsc);

        // Package configuration: generate file
        PackageConfig pc = new PackageConfig();
        / / package path
        pc.setParent("com.stopping");
        // Subpackage name under the package path
        pc.setMapper("mapper."+module);
        pc.setController("controller."+module);
        pc.setService("service."+module);
        pc.setServiceImpl("service."+module+".imp");
        pc.setEntity("model.entity");
        pc.setXml("Mapper");
        mpg.setPackageInfo(pc);

        // Custom configuration
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap(a) {
                // to do nothing}};// If the template engine is freemarker
        String templatePath = "/templates/mapper.xml.ftl";

        // Customize the output configuration
        List<FileOutConfig> focList = new ArrayList<>();
        // Custom configurations are printed first
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // Customize the output file name. If your Entity has a prefix or suffix, note that the XML name will change accordingly!!
                // Mapper file output
                String xmlUrl = projectPath + "/src/main/resources/mapper/" + module
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                System.out.println("XML generation path :"+xmlUrl);
                returnxmlUrl; }}); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg);// Configure the template
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // Policy configuration
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // Public fields written in the parent class
        //strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("Table name, separated by multiple Commas").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        // Whether to generate annotations
        strategy.setEntityTableFieldAnnotationEnable(true);
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(newFreemarkerTemplateEngine()); mpg.execute(); }}Copy the code