2, General Mapper implements basic addition, deletion, modification and query BaseMapper
2.5 insert related methods
copy// When an entity is saved, the null attribute will also be saved. The default value of the database will not be used int insert(T record); // Save an entity. The null attribute will not be saved. The default value of the database will be used int insertSelective(T record);
2.5.1 insert method
Add save method in PorscheService
copyvoid save(Porsche porsche);
Implementation of save method in PorscheServiceImpl
copy@Override public void save(Porsche porsche) { porscheMapper.insert(porsche); }
Test the save method in PorscheServiceTest
copy@Test public void save(){ // Construct the inserted entity class Porsche porsche = new Porsche(); porsche.setPorName("Panamera 4S 2022"); porsche.setPorPrice(880000d); porsche.setPorStock(10); porscheService.save(porsche); }
Execute the save test method

The database has updated one row, and the insertion is successful. Add the test code, output the self increasing primary key, and execute the test again

The output primary key is null. The self increasing primary key has been generated after the actual insertion into the database, but the program has not obtained the primary key generated after the successful insertion. To obtain the generated primary key Value, you need to add @ GeneratedValue(strategy = GenerationType.IDENTITY) on the attribute corresponding to the Porsche entity class and the data primary key to execute the test again

Two SQL statements are executed, one is an insert statement, and the other is to query the Value of the latest primary key. The console successfully outputs the Value of the self increasing primary key generated after the successful insertion.
@The GeneratedValue annotation enables the general Mapper to write back the value of the self increasing primary key automatically generated by the database to the entity class after executing the insert operation
2.5.2 insertSelective method
Add savePorscheSelective method in PorscheService
copyvoid savePorscheSelective(Porsche porsche);
Add the implementation of savePorscheSelective method in PorscheServiceImpl
copy@Override public void savePorscheSelective(Porsche porsche) { porscheMapper.insertSelective(porsche); }
Add savePorscheSelective test method
copy@Test public void savePorscheSelective(){ Porsche porsche = new Porsche(); porsche.setPorName("Porsche 911 2022"); porscheService.savePorscheSelective(porsche); }
If the non primary key field is null, it will not be added to the SQL statement

It is suitable for the case where there are many entity class attributes, but there is less NULL data in the inserted attribute part when inserting
2.6 update related methods
copy// Update all fields of the entity according to the primary key, and the null value will be updated int updateByPrimaryKey(T record); // Update the non null value of the property according to the primary key int updateByPrimaryKeySelective(T record);
2.6.1 updateByPrimaryKeySelective
Add updatePorscheSelective method in PorscheService
copyvoid updatePorscheSelective(Porsche porsche);
Add the implementation of updatePorscheSelective method in PorscheServiceImpl
copy@Override public void updatePorscheSelective(Porsche porsche) { porscheMapper.updateByPrimaryKeySelective(porsche); }
Add updatePorscheSelective test method
copy@Test public void updatePorscheSelective(){ Porsche porsche = new Porsche(); porsche.setPorId(1); porsche.setPorPrice(900000d); porscheService.updatePorscheSelective(porsche); }
Perform tests

For entity classes updated for some fields, use this method to update fields with values. Fields without values remain unchanged
2.7 delete related methods
copy// Delete according to the entity attribute as a condition, and the query condition uses an equal sign int delete(T record); // Delete according to the primary key field. The method parameter must contain the complete primary key attribute int deleteByPrimaryKey(Object key);
2.7.1 delete
Add the removePorsche method in Porsche service
copyvoid removePorsche(Porsche porsche);
Add the implementation of removePorsche method in PorscheServiceImpl
copy@Override public void removePorsche(Porsche porsche) { porscheMapper.delete(porsche); }
Added test method for removePorsche
copy@Test public void removePorsche(){ // Construct the entity class to be deleted Porsche porsche = new Porsche(); porsche.setPorName("Panamera 4S 2022"); porsche.setPorPrice(880000d); porsche.setPorStock(10); porscheService.removePorsche(porsche); }
Perform tests

If the passed object is null, comment out the setter method of the object and execute the test again

The data has been completely deleted. You must be careful and judge the conditions when using this method
2.7.2 deleteByPrimaryKey
Add the removePorscheById method in PorscheService
copyvoid removePorscheById(Integer id);
Add the implementation of removePorscheById method in PorscheServiceImpl
copy@Override public void removePorscheById(Integer id) { porscheMapper.deleteByPrimaryKey(id); }
Added removePorscheById test method
copy@Test public void removePorscheById(){ // Delete primary key of record Integer id = 1; porscheService.removePorscheById(id); }
Perform tests

deleteByPrimaryKey: the most commonly used deletion method
3, General Mapper to realize complex query - ExampleMapper
3.1 QBC query
QBC is Query By Criteria, and QBC query is to modularize and encapsulate query conditions through Java objects.
Criterion is an internal class. It is the plural form of criterion, which means standard; It is the same as the internal class code of criterion in the entity class CatExample of complex query conditions generated by MBG. It also provides the createCriteria method to create composite query conditions
The Example class of XXXExample VS general Mapper generated by MBG that encapsulates query conditions

Both encapsulate a large number of query conditions. The two methods are different. MBG directly generates XXXExample for Entity entity class, such as the generated CatExample and TeacherExample; When general Mapper uses conditional query, it needs to pass in an Entity class to query when creating an Example
copyExample porscheExample = new Example(Porsche.class);
3.1.1 query using QBC
Use QBC to create the following composite query:
copyWHERE (por_id > 1 and por_stock > 20) OR ( por_price < 1000000 and por_stock > 20)
Add getPorschesByPriceAndStock method in PorscheService
copyList<Porsche> getPorschesByPriceAndStock(Example porscheExample);
Add the implementation of getPorschesByPriceAndStock method in PorscheServiceImpl
copy@Override public List<Porsche> getPorschesByPriceAndStock(Example porscheExample) { return porscheMapper.selectByExample(porscheExample); }
Add the test method getPorscheByPriceAndStock in PorscheServiceTest, and view the comments during the construction of query conditions.
copy@Test public void getPorscheByPriceAndStock(){ Example porscheExample = new Example(Porsche.class); // WHERE (por_id > 1 and por_stock > 20) OR ( por_price < 1000000 and por_stock > 20) // Create two query conditions. The two parentheses behind the WHERE keyword correspond to two query conditions respectively Example.Criteria criteria1 = porscheExample.createCriteria(); Example.Criteria criteria2 = porscheExample.createCriteria(); // Set two query criteria: criteria1.andGreaterThan("porId",1) .andGreaterThan("porStock",20); criteria2.andLessThan("porPrice",1000000d) .andGreaterThan("porStock",20); // Connect query condition 1--criteria1 and query condition 2--criteria2 through OR // Porschample is equivalent to the select field name from, indicating WHERE criteria 1 // Just call the or method to connect criteria2, and the completed SQL statement is formed // select field name from indicates WHERE (criteria1) OR (criteria2) porscheExample.or(criteria2); List<Porsche> porscheList = porscheService.getPorschesByPriceAndStock(porscheExample); for (Porsche porsche : porscheList) { System.out.println("The query contents are:" + porsche); } }
Perform tests

3.1.2 other QBC settings
QBC query can be set at the same time, such as sorting, de duplication, and setting query fields. Relevant codes are added in the getPorscheByPriceAndStock test method,
copyporscheExample.setDistinct(true); porscheExample.orderBy("porPrice").asc().orderBy("porName").desc(); porscheExample.selectProperties("porName","porPrice");
Perform the test again

View the SQL statements deleted by the console. The built composite conditions will take effect when the SQL is executed.
4, General Mapper implementation paging - RowBoundsMapper
4.1 paging related methods
copy// Perform paging query according to example conditions and rowboundaries List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds); // Pagination query based on entity attributes and rowboundaries List<T> selectByRowBounds(T record, RowBounds rowBounds);
4.1.1 selectByRowBounds
Add the paging query method getPorschesByRowBounds in the PorscheService interface
copyList<Porsche> getPorschesByRowBounds(Porsche record, RowBounds rowBounds);
Implement the paging query method getPorschesByRowBounds in PorscheServiceImpl
copy@Override public List<Porsche> getPorschesByRowBounds(Porsche record, RowBounds rowBounds) { return porscheMapper.selectByRowBounds(record,rowBounds); }
Add the test code of this method
copy@Test public void getPorschesByRowBounds(){ int pageNo = 2; int pageSize = 3; int index = (pageNo - 1) * pageSize; RowBounds rowBounds = new RowBounds(index, pageSize); List<Porsche> porscheList = porscheService.getPorschesByRowBounds(null, rowBounds); for (Porsche porsche : porscheList) { System.out.println("The query contents are:" + porsche); } }
Perform tests

According to the SQL statement output by the console, it is indicated that the general Mapper still queries all data, and the paging operation in memory is "false paging". It is not recommended to use this paging query, and it is recommended to use the PageHelper plug-in to realize real paging
4.2 @Transient
In general, the attributes in the entity class correspond to the fields in the database table one-to-one. However, some attributes may not have corresponding fields in the database. In this case, you need to use the @ Transient annotation to indicate that this is not a field in the table.
5, Reverse engineering of general Mapper
5.1 reverse engineering of general Mapper
The code generated by reverse engineering of general Mapper is slightly different from the code generated by native MyBatis. First of all, it contains Entity entity class, XxxMapper interface and XxxMapper XML, but the Entity entity class generated by the general Mapper will contain annotations such as @ Table annotation, @ Column annotation, @ Id annotation and @ GeneratedValue; The generated XxxMapper interface inherits the Mapper < XXX > class; There is no SQL statement in the generated XxxMapper.xml, only a resultMap tag.
5.2 reverse engineering using general Mapper
Create a new project, common Mapper MBG. The dependencies, Spring configuration and MyBatis configuration used in this project are the same as those used in the general Mapper project. The difference is that the new general Mapper MBG project does not include the Entity class Mapper interface, Service class and test class.
In the POM The code generator dependency of general Mapper and the maven plug-in are added in the XML file. The code generator can be executed by the maven plug-in to generate the code. The code generator can also be run by using Java code or command line, and will not be described here.
copy<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-generator</artifactId> <version>1.0.0</version> </dependency>
Add generatorConfig.xml in the resources directory
copy<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="db.properties"/> <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat"> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <!--currency Mapper of MBG plug-in unit--> <plugin type="tk.mybatis.mapper.generator.MapperPlugin"> <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/> <property name="caseSensitive" value="true"/> </plugin> <jdbcConnection driverClass="${jdbc_driver}" connectionURL="${jdbc_url}" userId="${jdbc_username}" password="${jdbc_password}"> </jdbcConnection> <javaModelGenerator targetPackage="com.citi.entity" targetProject="./src/main/java"/> <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources"/> <javaClientGenerator targetPackage="com.citi.mapper" targetProject="./src/main/java" type="XMLMAPPER"/> <!--tableName="%"Indicates that all tables are involved in reverse engineering--> <table tableName="t_teacher" domainObjectName="Teacher"> <generatedKey column="id" sqlStatement="Mysql"/> </table> </context> </generatorConfiguration>
Add plug-ins in pom.xml
copy<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.7</version> <configuration> <configurationFile> ${basedir}/src/main/resources/generatorConfig.xml </configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>4.0.0</version> </dependency> </dependencies> </plugin> </plugins> </build>
MBG running general Mapper

Code generator runs successfully
5.3 test the code generated by general Mapper
Create a new test class for TeacherMapper generated by the code generator
copy@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:application.xml") public class TeacherMapperTest { @Resource private TeacherMapper teacherMapper; @Test public void selectAll(){ List<Teacher> teachers = teacherMapper.selectAll(); for (Teacher teacher : teachers) { System.out.println("The content queried is::" + teacher.getTeacherName()); } } }
Perform the test

The console successfully outputs the query content, and the code generated by reverse engineering of general Mapper is verified successfully.