Sorry, it’s time to change Mybatis Plus!

Source: juejin.cn/post/6886019929519177735

Using fluent mybatis, you don’t need to write specific xml files. You can construct more complex business sql statements through java api to achieve the integration of code logic and sql logic. It is no longer necessary to assemble queries or update operations in Dao, and then assemble parameters in xml or mapper. So compared with native Mybatis, Mybatis Plus or other frameworks, what conveniences does FluentMybatis provide?

Part1 warehouse address

For detailed API and usage, please refer to the official warehouse

https://gitee.com/fluent-mybatis/fluent-mybatis

Part2 Requirement Scenario Settings

Let’s implement and compare it through a relatively typical business requirement. If there is a student score sheet, the structure is as follows:

create table `student_score`
(
    id bigint auto_increment comment 'primary key ID' primary key,
    student_id bigint not null comment 'student number',
    gender_man tinyint default 0 not null comment 'Gender, 0: female; 1: male',
    school_term int null comment 'term',
    subject varchar(30) null comment 'subject',
    score int null comment 'score',
    gmt_create datetime not null comment 'record creation time',
    gmt_modified datetime not null comment 'Record the last modified time',
    is_deleted tinyint default 0 not null comment 'logical deletion identification'
) engine = InnoDB default charset=utf8;

There is a need now for:

Statistics on the passing scores of three subjects (‘English’, ‘Mathematics’, ‘Chinese’) in 2000 by semester, subject statistics of the minimum score, maximum score and average score, and the sample number needs to be greater than 1 Articles, statistical results are sorted by semester and subject

We can write SQL statements as follows

select school_term,
       subject,
       count(score) as count,
       min(score) as min_score,
       max(score) as max_score,
       avg(score) as max_score
from student_score
where school_term >= 2000
  and subject in ('English', 'Mathematics', 'Chinese')
  and score >= 60
  and is_deleted = 0
group by school_term, subject
having count(score) > 1
order by school_term, subject;

The above requirements can be achieved using fluent mybatis, native mybatis and Mybatis plus respectively.

Recommend an open source and free Spring Boot practical project:

https://github.com/javastacks/spring-boot-best-practice

Part3 Comparison of the three implementations

1Use fluent mybatis to realize the above functions

We can see the capabilities of fluent api and the IDE’s rendering effect on the code.

2. Switch to mybatis native to achieve the effect

Define Mapper interface

public interface MyStudentScoreMapper {
    List<Map<String, Object>> summaryScore(SummaryQuery paras);
}

Define the parameter entities needed for the interface SummaryQuery

@Data
@Accessors(chain = true)
public class SummaryQuery {
    private Integer schoolTerm;

    private List<String> subjects;

    private Integer score;

    private Integer minCount;
}

Define the mapper xml file that implements business logic

<select id="summaryScore" resultType="map" parameterType="cn.org.fluent.mybatis.springboot.demo.mapper.SummaryQuery">
    select school_term,
    subject,
    count(score) as count,
    min(score) as min_score,
    max(score) as max_score,
    avg(score) as max_score
    from student_score
    where school_term >= #{schoolTerm}
    and subject in
    <foreach collection="subjects" item="item" open="(" close=")" separator=",">
        #{item}
    </foreach>
    and score >= #{score}
    and is_deleted = 0
    group by school_term, subject
    having count(score) > #{minCount}
    order by school_term, subject
</select>

Implement the business interface (here is the test class, which should correspond to the Dao class in actual applications)

@RunWith(SpringRunner.class)
@SpringBootTest(classes = QuickStartApplication.class)
public class MybatisDemo {
    @Autowired
    private MyStudentScoreMapper mapper;

    @Test
    public void mybatis_demo() {
        // Construct query parameters
        SummaryQuery paras = new SummaryQuery()
            .setSchoolTerm(2000)
            .setSubjects(Arrays.asList("English", "Math", "Chinese"))
            .setScore(60)
            .setMinCount(1);

        List<Map<String, Object>> summary = mapper.summaryScore(paras);
        System.out.println(summary);
    }
}

In short, using mybatis directly, the implementation steps are still quite cumbersome and the efficiency is too low. What is the effect of switching to mybatis plus?

Recommend an open source and free Spring Boot practical project:

https://github.com/javastacks/spring-boot-best-practice

3. Replace with mybatis plus to achieve the effect

The implementation of mybatis plus is much simpler than mybatis. The implementation effect is as follows

As circled in the red box, the implementation of mybatis plus uses a lot of hard coding of strings (you can use Entity’s get lambda method to partially replace the string encoding). The hard coding of strings will create a lot of barriers for developers to use. I personally think there are two main points:

  1. Difficulty remembering and typing field names
  2. Runtime error after Entity property changes following database field

Other frameworks, such as TkMybatis, are weaker than mybatis plus in terms of encapsulation and ease of use, so they will not be compared.

Part4 generated code encoding comparison

4. fluent mybatis generated code settings

public class AppEntityGenerator {
    static final String url = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false & amp;useUnicode=true & amp;characterEncoding=utf-8";

    public static void main(String[] args) {
        FileGenerator.build(Abc.class);
    }

    @Tables(
        /** Database connection information **/
        url = url, username = "root", password = "password",
        /** Entity class parent package path **/
        basePack = "cn.org.fluent.mybatis.springboot.demo",
        /** Entity code source directory **/
        srcDir = "spring-boot-demo/src/main/java",
        /** Dao code source directory **/
        daoDir = "spring-boot-demo/src/main/java",
        /** If the table defines record creation, record modification, and logical deletion of fields **/
        gmtCreated = "gmt_create", gmtModified = "gmt_modified", logicDeleted = "is_deleted",
        /** The table where the file needs to be generated (table name: corresponding Entity name) **/
        tables = @Table(value = {"student_score"})
    )
    static class Abc {
    }
}

5. mybatis plus code generation settings

public class CodeGenerator {

    static String dbUrl = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false & amp;useUnicode=true & amp;characterEncoding=utf-8";

    @Test
    public void generateCode() {
        GlobalConfig config = new GlobalConfig();
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)
            .setUrl(dbUrl)
            .setUsername("root")
            .setPassword("password")
            .setDriverName(Driver.class.getName());
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
            .setCapitalMode(true)
            .setEntityLombokModel(false)
            .setNaming(NamingStrategy.underline_to_camel)
            .setColumnNaming(NamingStrategy.underline_to_camel)
            .setEntityTableFieldAnnotationEnable(true)
            .setFieldPrefix(new String[]{"test_"})
            .setInclude(new String[]{"student_score"})
            .setLogicDeleteFieldName("is_deleted")
            .setTableFillList(Arrays.asList(
                new TableFill("gmt_create", FieldFill.INSERT),
                new TableFill("gmt_modified", FieldFill.INSERT_UPDATE)));

        config
            .setActiveRecord(false)
            .setIdType(IdType.AUTO)
            .setOutputDir(System.getProperty("user.dir") + "/src/main/java/")
            .setFileOverride(true);

        new AutoGenerator().setGlobalConfig(config)
            .setDataSource(dataSourceConfig)
            .setStrategy(strategyConfig)
            .setPackageInfo(
                newPackageConfig()
                    .setParent("com.mp.demo")
                    .setController("controller")
                    .setEntity("entity")
            ).execute();
    }
}

Part5 FluentMybatis feature list

Comparison summary of the three parts of Part6

After reading the implementation of the same function point by the three frameworks, you will definitely have your own judgment. The author has also summarized a comparison here.

Mybatis Plus Fluent Mybatis
Code generation Generate Entity Generate Entity, and then compile to generate Mapper, Query, Update and SqlProvider
Generator is easy to use Sex Low High
Symbiotic relationship with Mybatis Need to replace the original SqlSessionFactoryBean There is no modification to Mybatis, how to use it originally Or how to use it
Dynamic SQL construction method When the application starts, according to the Entity annotation information Construct a dynamic xml fragment and inject it into the Mybatis parser When the application is compiled, according to the Entity annotation, the SqlProvider of the corresponding method is compiled and generated, and the @InsertProvider @SelectProvider @UpdateProvider is used on the Mybatis Mapper. Annotation association
Is the dynamic SQL result easy to DEBUG track Not easy to debug Easy, just locate the SQLProvider method and set a breakpoint
Dynamic SQL construction By hardcoding the field name, or using the lambda expression of Entity’s get method Generating the corresponding method through compilation Name, just call the method directly
Error detection after field change Through get The lambda expression of the method can be found through compilation, but the field encoding cannot be found through compilation It can be found during compilation
Dynamic SQL construction method for different fields By interface parameter method By interface name method, FluentAPI The coding efficiency is higher
Syntax rendering features None You can use IDE syntax rendering through key variables select, update, set, and, or, which is more readable

Recommended recent hot articles:

1.1,000+ Java interview questions and answers compiled (2022 latest version)

2. Explosive! Java coroutines are coming. . .

3. Spring Boot 2.x tutorial, so complete!

4. Stop filling the screen with explosive categories and try the decorator mode. This is the elegant way! !

5. “Java Development Manual (Songshan Edition)” is newly released, download it quickly!

If you think it’s good, don’t forget to like + retweet!