“This is the 40th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

A, MyBatis – Plus Introduce

MyBatis-Plus is a very powerful MyBatis enhancement kit, only do enhancement do not change, without writing any SQL statements that can be extremely convenient to achieve a single, batch, paging and other operations.

MyBatis-Plus supports universal CRUD operation, built-in universal Mapper and universal Service and powerful conditional constructor, and supports reverse engineering that is to support code generator, other features can refer to MyBatis-Plus official website; MyBatis Mapper (Part A) – MyBatis Mapper (Part D) These four articles

1.1 Project Construction

1.1.1 MyBatis – Spring integration

Create mybatis- Plus project, add Spring dependencies, MyBatis dependencies, and other dependencies. The resources directory also requires the Spring configuration file application. XML, MyBatis global configuration file MyBatis -config. XML, log configuration logback. XML, and database connection information configuration db.properties. Specific configuration can refer to QA from shallow to deep persistence layer framework (10) – MyBatis General Mapper (Part A).

Added Entity package, added entity class Tesla

@Data
public class Tesla {

    private Integer id;
    private String name;
    private Double price;
    private String vehicleType;
    private String factory;
}
Copy the code

Added the TeslaMapper interface to the Mapper package

public interface TeslaMapper {

    Tesla selectTeslaById(Integer id);
}
Copy the code

Add teslamapper.xml to mappers folder under resources


      
<! DOCTYPEmapper
        PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lilith.mapper.TeslaMapper">
    <sql id="teslaAllColums">
        id,name,price,vehicle_type,factory
    </sql>

    <select id="selectTeslaById" resultType="com.lilith.entity.Tesla">
        SELECT
        <include refid="teslaAllColums"></include>
        FROM tesla where id = #{id}
    </select>
</mapper>
Copy the code

TeslaMapperTest adds the TeslaMapperTest class to the Test package to test the SelecttesID method

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class TeslaMapperTest {

    @Autowired
    private TeslaMapper teslaMapper;

    @Test
    public void selectTeslaById(a){
        Tesla tesla = teslaMapper.selectTeslaById(2);
        System.out.println("The query output is:"+ tesla); }}Copy the code

Perform the test

1.1.2 integration MyBatis – Plus

Integrating MyBatis-Plus is very easy, only takes two steps, and MyBatis-Plus automatically maintains MyBatis and MyBatis-Spring, so just import MyBatis-Plus dependencies to replace MyBatis and MyBatis-Spring.

The first step is to add the MyBatis-Plus dependency and comment out the MyBatis and MyBatis-Spring dependencies

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.5.0</version>
</dependency>
Copy the code

The second step is to replace the SqlSessionFactory

<! For MyBatis - Plus MyBatisSqlSessionFactoryBean, turned out to be MyBatis SqlSessionFactoryBean -- -- >
<bean id="mybatisSqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<! -- The contents of the tag remain unchanged -->
</property>
</bean>
Copy the code

Plus: The difference between integrating MyBatis-Plus and integrating universal Mapper:

Depend on the different

  • Mapper does not maintain MyBatis and MyBatis-Spring dependencies. When importing dependencies, you need to import Mapper dependencies, MyBatis dependencies, and MyBatis-Spring dependencies

The configuration file can be modified in different ways

  • If MyBatis inherits the common Mapper, you need to modify MapperScannerConfigurer in the Spring configuration file to run the common Mapper. MP uses MapperScannerConfigurer of MyBatis
  • MyBatis inheritance MP need to modify the SqlSessionFactoryBean MyBatisSqlSessionFactoryBean under for MP, gm is MyBatis Mapper use SqlSessionFactoryBean itself

Run the test again

The MP logo is displayed on the console, and the queried data is displayed. The MP integration is successful

Second, MyBatis-Plus CRUD

During the construction project, I used the native MyBatis integrated Spring to conduct a query operation on tesla table. What is the difference between using MyBatis and using general Mapper and using MP(MyBatis-Plus) to operate table steps?

The steps to operate a table with MyBatis are:

  1. Create TeslaMapper interface, add CRUD method
  2. Create the teslamapper. XML mapping file and add THE SQL statements corresponding to CRUD to the mapping file

The steps to use the generic Mapper action table are:

  1. Create a TeslaMapper interface that integrates with the Mapper interface of the universal Mapper, and you automatically obtain CRUD methods without the need for Mapper XML files

The steps to use the MP action table are:

  1. Create the TeslaMapper interface and inherit from the BaseMapper interface, and you get CRUD methods without even the usual Mapper XML files

2.1 BaseMapper interface

View the BaseMapper interface source code

As you can see, the BaseMapper interface provides a number of CRUD methods that are automatically acquired by inheriting the BaseMapper interface

2.2 Use of important notes

@ TableId annotations

TeslaMapperTest added the Insert method test to insert a record into the Tesla table

@Test
public void insert(a){
    Tesla tesla = new Tesla();
    tesla.setName("Model 3 Performance");
    tesla.setPrice(330000d);
    tesla.setVehicleType("Compact Car");
    tesla.setFactory("Shanghai Gigafactory");
    
    teslaMapper.insert(tesla);
}
Copy the code

Perform the testThe console output of the INSERT statement with the primary key 1166057474 is not incrementated according to existing data because no primary key policy is set.

The @tableID annotation sets the primary key policy

Add @tableId annotation @tableID (type = idtype.auto) to id attribute to test again

View the data inserted into the databaseThe inserted primary key is automatically incremented

If you want to get the annotation, you can get it directly from the inserted object after the insertion. MP automatically writes the primary key back to the entity class. Add a line of code at the end of the INSERT method

System.out.println(tesla.getId());
Copy the code

Execute insert methodThe console prints the primary key value for inserting the database

@ TableName annotations

In the universal Mapper, it is necessary to achieve one-to-one correspondence between entity class and table, entity class attribute and field through annotation, so as to prevent the entity class attribute name cannot be converted to be consistent with the field name of the table through the hump transformation method, or the entity class class name is inconsistent with the table name, or some attributes in the entity class have no corresponding field in the table. Then, like a generic Mapper, MP inherits its interface to get generic CRUD methods, and MP should have some annotations that match table and entity classes, fields, and attributes.

Let’s start by looking at what can go wrong if the table name and class name do not match and insert again. Alter table TESLA to rename table T_TESLA

Added test methods to test selectById methods provided by MP

@Test
public void selectById(a){
    Tesla tesla = teslaMapper.selectById(2);
    System.out.println("The query output is:" + tesla);
}
Copy the code

Execute the selectById method

The default query table name is lowercase with the first letter of the entity class name

You need to use the @tablename annotation to associate the Tesla entity class with the T_Tesla table @tablename (value = “t_Tesla “)

Execute the selectById method again

The record with ID 2 was successfully queried with the table name specified in the annotation

MP global policy configuration

In the case of a large number of tables, it would also be cumbersome to specify a primary key generation policy for each table and to specify the table name using annotations, so this can be solved by global configuration

Global configuration of primary keys

In the application. The XML configuration files can be set in the MP global strategy, through the bean label Settings and in mybatisSqlSessionFactoryBean into the global configuration.

<! Insert DB configuration into global configuration -->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="dbConfig" ref="dbConfig"/> <! -- Not required -->
</bean>

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    <! -- Globally configure primary key policy, AUTO or index 0-->
    <property name="idType" value="AUTO"></property>
</bean>
Copy the code

In mybatisSqlSessionFactoryBean into the global configuration

<! For MyBatis - Plus MyBatisSqlSessionFactoryBean, turned out to be MyBatis SqlSessionFactoryBean -- -- >
<bean id="mybatisSqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
</property>
    <! Inject global configuration into SqlSessionFactoryBean-->
    <property name="globalConfig" ref="globalConfig" />
</bean>
Copy the code

Annotate the @TableId annotation on the Tesla entity class and perform the INSERT method

View records inserted into the database

Automatic primary key increment is also possible, eliminating the need to add the @TableID annotation to the primary key attribute of each entity class

Global configuration of table names

If all table names have a uniform prefix, you can also use global configuration

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    <! -- Globally configure primary key policy, AUTO or index 0-->
    <property name="idType" value="AUTO"></property>
    <! -- Set table name prefix -->
    <property name="tablePrefix" value="t_" />
</bean>
Copy the code

To annotate the @Tablename annotation on the entity class, execute the selectById method

The queried table name was successfully prefixed with the specified name.

For other MP configurations, see the official configuration documents

@ TableField annotations

If table fields and entity-class attributes are completely inconsistent, this can be resolved by more than just configuring a camel name.

Modify the Tesla entity class properties to vehicleName and vehiclePrice

@Data
public class Tesla {

    private Integer id;
    private String vehicleName;
    private Double vehiclePrice;
    private String vehicleType;
    private String factory;
}
Copy the code

Perform the selectById test

The @TableField annotation can be used when the entity class attribute and the field name are inconsistent to indicate that the attribute corresponds to the specified field. Modify the Tesla entity class

@Data
public class Tesla {

    private Integer id;
    @TableField(value = "name")
    private String vehicleName;
    @TableField(value = "price")
    private Double vehiclePrice;
    private String vehicleType;
    private String factory;
}
Copy the code

SelectById test again

Console output SQL statement added alias, alias is the original property name, successfully query data.

The attributes of @tableField are value and exist. Value is to specify the name of the corresponding field. Exist indicates whether the attribute has a corresponding field in the table. The default is true

2.3 Differences between table and entity class annotations in MP and general Mapper

MP uses annotations to resolve the correspondence between entity classes and tables, as well as properties and fields

  • TableName: matches the entity class to the specified table. The default TableName is lowercase
  • @tableID: Specifies the primary key generation policy. There is a default generation policy
  • @tableField: Sets a one-to-one mapping between a property and the specified field

Annotations can also be used to resolve entity class and table mappings in the generic Mapper

  • @table: This annotation is used to map the entity class to the specified Table
  • @ID: This annotation is used to specify that the attribute corresponds to the primary key field in the table
  • @GeneratedValue: This annotation is used to specify the primary key generation strategy, used in conjunction with @ID
  • Column: This annotation is used to map entity class attributes to fields
  • @TRANSIENT: This annotation represents the field corresponding to the attribute in the table

The native MyBatis annotation strategy requires the use of two attributes useGeneratedKeys and keyProperty within the INSERT tag to obtain the generated primary key.

<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO t_employee(empname,gender,email) values (#{empName},#{gender},#{email})
</insert>
Copy the code

2.4 MP insert related methods

BaseMapper’s insert method in MP will insert the entity class into the table with database. MP will judge the value of the inserted attribute. It can insert the field with value, and the attribute with value is empty will not perform the insert operation.

Change the insert method in TeslaMapperTest to comment out some of the code for assigning attributes,

@Test
public void insert(a){
    Tesla tesla = new Tesla();
    tesla.setVehicleName("Model 3 Performance");
    // tesla.setVehiclePrice(330000d);
    // tesla.setVehicleType("Compact Car");
    tesla.setFactory("Shanghai Gigafactory");

    teslaMapper.insert(tesla);
    System.out.println(tesla.getId());
}
Copy the code

Perform the test

Based on the SQL statement output from the console, you can determine that MP only inserts fields that have values. If you want empty fields to appear in INSERT statements, you need to set the fields to NULL.