π’π’π’π£π£π£
Hello! Hello, everyone. I'm [one heart classmate], a highly motivated [Java domain blogger]! πππ
β¨ Writing style of [one heart students]: I like to explain every knowledge point in [easy to understand] style, rather than using [tall and tall] official statement.
β¨ The field of the blog is the learning of back-end technology, and more back-end technology and learning experience will be continuously updated in the future.
β¨ If there are [cute] who are interested in [back-end technology], please pay attention to [one heart students] πππ
β€οΈβ€οΈβ€οΈ Thank you, big and small! β€οΈβ€οΈβ€οΈ ‘
catalogue
2, Automatic code generator construction
2.1. Create a SpringBoot project.
2.3 preparation of configuration files
2.5 start and run code generator class
2.6 writing auto fill processor
2.7 optimistic lock and logical deletion configuration
3.2} insert or update operation
preface
Recall our previous development process. First, we need to write entity classes corresponding to database tables, and then create packages (mapper,service,impl) at various levels. Does this process feel particularly long? Now an artifact has appeared, which is the automatic code generator of mpbatis plus.
1, Introduction
The automatic code generator is very easy to use. We only need to provide the table name of our database, and then let the generator automatically help us complete the creation of various codes. The whole process is very refreshing, which can be said to be the welfare of overtime workers!
Now let's explain how to build this automatic code generator!
2, Automatic code generator construction
preparation
CREATE DATABASE mybatis_plus_db; USE `mybatis_plus_db`; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'User primary key', `name` varchar(20) DEFAULT NULL COMMENT 'User name', `age` int DEFAULT NULL COMMENT 'User age', `version` int DEFAULT '1' COMMENT 'Optimistic lock', `deleted` int DEFAULT '0' COMMENT 'Logical deletion', `create_time` datetime DEFAULT NULL COMMENT 'Creation time', `update_time` datetime DEFAULT NULL COMMENT 'Update time', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1482996505408204804 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
The database structure is as follows:
2.1. Create a SpringBoot project.
Select web dependency.
2.2} import dependency
<!-- Database driven --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> <!-- Code auto generator dependency--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency>
2.3 preparation of configuration files
application.properties:
# mysql 5 drives different com mysql. jdbc. Driver # mysql 8 drives different com mysql. cj. jdbc. Driver, need to add time zone configuration serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # Configuration log mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl # Configure logical deletion mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
2.4 automatic code generator
package com.yixin; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; 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 org.junit.platform.commons.util.StringUtils; import java.util.ArrayList; import java.util.Scanner; public class CodeGenerator { 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)) { return ipt; } } throw new MybatisPlusException("Please enter the correct" + tip + "!"); } public static void main(String[] args) { // Code generator AutoGenerator mpg = new AutoGenerator(); // Global configuration GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java");//Set code generation path gc.setFileOverride(true);//Overwrite previous file gc.setOpen(false);//Open build directory gc.setAuthor("yixin");//Set project author name gc.setIdType(IdType.AUTO);//Set primary key policy gc.setBaseResultMap(true);//Generate basic ResultMap gc.setBaseColumnList(true);//Generate basic ColumnList gc.setServiceName("%sService");//Remove service default prefix gc.setDateType(DateType.ONLY_DATE);//Set time type mpg.setGlobalConfig(gc); // Data source configuration DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // Package configuration PackageConfig pc = new PackageConfig(); pc.setParent("com.yixin"); pc.setMapper("mapper"); pc.setXml("mapper.xml"); pc.setEntity("pojo"); pc.setService("service"); pc.setServiceImpl("service.impl"); pc.setController("controller"); mpg.setPackageInfo(pc); // Policy configuration StrategyConfig sc = new StrategyConfig(); sc.setNaming(NamingStrategy.underline_to_camel); sc.setColumnNaming(NamingStrategy.underline_to_camel); sc.setEntityLombokModel(true);//Automatic lombok sc.setRestControllerStyle(true); sc.setControllerMappingHyphenStyle(true); sc.setLogicDeleteFieldName("deleted");//Set logical deletion //Set auto fill configuration TableFill gmt_create = new TableFill("create_time", FieldFill.INSERT); TableFill gmt_modified = new TableFill("update_time", FieldFill.INSERT_UPDATE); ArrayList<TableFill> tableFills=new ArrayList<>(); tableFills.add(gmt_create); tableFills.add(gmt_modified); sc.setTableFillList(tableFills); //Optimistic lock sc.setVersionFieldName("version"); sc.setRestControllerStyle(true);//Hump naming // sc.setTablePrefix("tbl_"); Set table name prefix sc.setInclude(scanner("Table name, separated by multiple English commas").split(",")); mpg.setStrategy(sc); // Generate code mpg.execute(); } }
2.5 start and run code generator class
Enter our table name in the console: user
Then it's done!
See the effect:
For all packages under java, we didn't write them ourselves, but the code generator automatically built them for us!
2.6 writing auto fill processor
On the basis of the code generator, we just need to write the automatically populated processor class as before.
package com.yixin.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 processor to the IOC container! public class MyMetaObjectHandler implements MetaObjectHandler { // Population policy at insertion @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); } // Population policy when updating @Override public void updateFill(MetaObject metaObject) { log.info("start update fill....."); this.setFieldValByName("updateTime",new Date(),metaObject); } }
2.7 optimistic lock and logical deletion configuration
package com.yixin.config; import com.baomidou.mybatisplus.core.injector.ISqlInjector; import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; // Scan our mapper folder @MapperScan("com.yixin.mapper") @EnableTransactionManagement @Configuration // Configuration class public class MyBatisPlusConfig { // Register optimistic lock plug-in @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } // Delete components logically! @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); } }
That's it! Let's write a test class to test it.
2.8 test
(1) Test add data
package com.yixin; import com.yixin.pojo.User; import com.yixin.service.UserService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class AutoApplicationTests { @Autowired private UserService userService; @Test void test1() { User user=new User(); user.setName("yixin"); user.setAge(18); boolean flag=userService.save(user); System.out.println(flag); } }
Output:
It can be found that a piece of data was successfully inserted.
(2) Test the controller layer to get data
package com.yixin.controller; import com.yixin.pojo.User; import com.yixin.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * <p> * Front end controller * </p> * * @author yixin * @since 2022-01-17 */ @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @ResponseBody @RequestMapping("/all") public List<User> get(){ return userService.list(null); } }
Start main startup class:
package com.yixin; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.yixin.mapper") public class AutoApplication { public static void main(String[] args) { SpringApplication.run(AutoApplication.class, args); } }
Enter in the browser: http://localhost:8080/user/all
We have successfully obtained our data.
3, CRUD in Service
3.1} insertion operation
SaveΒ
// Insert a record (select field, policy insert) boolean save(T entity); // Insert (batch) boolean saveBatch(Collection<T> entityList);
Parameter description
type | Parameter name | describe |
---|---|---|
T | entity | Entity object |
Collection<T> | entityList | Entity object collection |
use
(1) Insert a piece of data
@Test void contextLoads() { User user=new User(); user.setName("yixin"); user.setAge(18); boolean flag=userService.save(user); System.out.println(flag); }
(2) Batch insert data
@Test void test3() { List<User> userList=new ArrayList<>(); User user=new User(); user.setName("zhangsan"); user.setAge(26); User user2=new User(); user2.setName("lisi"); user2.setAge(27); userList.add(user); userList.add(user2); boolean flag=userService.saveBatch(userList); System.out.println(flag); }
3.2} insert or update operation
SaveOrUpdate
// Update record exists in TableId annotation. Insert a record boolean saveOrUpdate(T entity); // If the updateWrapper attempts to update, do you want to continue with the saveOrUpdate(T) method boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper); // Batch modify insert boolean saveOrUpdateBatch(Collection<T> entityList);
Parameter description
type | Parameter name | describe |
---|---|---|
T | entity | Entity object |
Wrapper<T> | updateWrapper | Entity object encapsulation operation class UpdateWrapper |
Collection<T> | entityList | Entity object collection |
use
Requirement: insert a piece of data. If the data exists in the database, update it. If it does not exist, insert it.
@Test void test5() { User user=new User(); user.setName("wangwu"); user.setAge(18); boolean flag=userService.saveOrUpdate(user); System.out.println(flag); }
3.3 delete
Remove
// Delete the record according to the entity condition boolean remove(Wrapper<T> queryWrapper); // Delete by ID boolean removeById(Serializable id); // Delete the record according to the columnMap condition boolean removeByMap(Map<String, Object> columnMap); // Delete (batch delete according to ID) boolean removeByIds(Collection<? extends Serializable> idList);
Parameter description
type | Parameter name | describe |
---|---|---|
Wrapper<T> | queryWrapper | Entity wrapper class QueryWrapper |
Serializable | id | Primary key ID |
Map<String, Object> | columnMap | Table field map object |
Collection<? extends Serializable> | idList | List of primary key ID S |
use
Requirement: delete all user information with name "lisi".
@Test void test6() { QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.like("name","lisi"); boolean flag=userService.remove(wrapper); System.out.println(flag); }
3.4 update operation
UpdateΒ
// According to the UpdateWrapper condition, sqlset needs to be set for updating records boolean update(Wrapper<T> updateWrapper); // Update the record according to the whereWrapper condition boolean update(T updateEntity, Wrapper<T> whereWrapper); // Select modify according to ID boolean updateById(T entity); // Batch update by ID boolean updateBatchById(Collection<T> entityList);
Parameter description
type | Parameter name | describe |
---|---|---|
Wrapper<T> | updateWrapper | Entity object encapsulation operation class UpdateWrapper |
T | entity | Entity object |
Collection<T> | entityList | Entity object collection |
use
Requirement: change the user whose user name is "yixin" to "one student".
@Test void test7() { QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.eq("name","yixin"); User user =userService.getOne(wrapper); user.setName("One heart classmate"); boolean flag=userService.updateById(user); System.out.println(flag); }
3.5 query operation
3.5.1} single query
Get
// Query by ID T getById(Serializable id); // Query a record according to the Wrapper. If there are more than one result set, exceptions will be thrown. Take one randomly and add the limiting condition Wrapper last("LIMIT 1") T getOne(Wrapper<T> queryWrapper); // Query a record according to the Wrapper T getOne(Wrapper<T> queryWrapper, boolean throwEx); // Query a record according to the Wrapper Map<String, Object> getMap(Wrapper<T> queryWrapper);
Parameter description
type | Parameter name | describe |
---|---|---|
Serializable | id | Primary key ID |
Wrapper<T> | queryWrapper | The entity object encapsulates the operation class QueryWrapper |
boolean | throwEx | If there are multiple result s, do you throw an exception |
T | entity | Entity object |
use
Requirements: query a user whose name is "one heart". Remember, only one user.
@Test void test8() { QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.like("name","Wholeheartedly").last("LiMIT 1"); User user=userService.getOne(wrapper); System.out.println(user); }
3.5.2 batch query
ListΒ
// Query all List<T> list(); // Query list List<T> list(Wrapper<T> queryWrapper); // Query (batch query by ID) Collection<T> listByIds(Collection<? extends Serializable> idList); // Query (based on columnMap criteria) Collection<T> listByMap(Map<String, Object> columnMap); // Query all lists List<Map<String, Object>> listMaps(); // Query list List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper); // Query all records List<Object> listObjs(); // Query all records according to Wrapper conditions List<Object> listObjs(Wrapper<T> queryWrapper);
Parameter description
type | Parameter name | describe |
---|---|---|
Wrapper<T> | queryWrapper | The entity object encapsulates the operation class QueryWrapper |
Collection<? extends Serializable> | idList | List of primary key ID S |
Map<?String, Object> | columnMap | Table field map object |
use
Requirement: query all user information with name "one heart"
@Test void test9() { QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.like("name","Wholeheartedly"); List<User> userList=userService.list(wrapper); System.out.println(userList); }
3.5.3 query quantity
CountΒ
// Total records queried int count(); // Query the total number of records according to Wrapper conditions int count(Wrapper<T> queryWrapper);
Parameter description
type | Parameter name | describe |
---|---|---|
Wrapper<T> | queryWrapper | The entity object encapsulates the operation class QueryWrapper |
use
Demand: query the number of users aged 18.
@Test void test10() { QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.eq("age",18); int count=userService.count(wrapper); System.out.println(count); }
Summary
The above is how to build an automatic code generator and CRUD operation in the Service layer sorted out by [one student]. I believe you can feel the [high efficiency] of mybatis plus more and more. It can really save us a lot of effort in our development!
If this [article] is helpful to you, I hope I can praise [one heart classmate] ποΌ It's not easy to create. Compared with the official statement, I prefer to explain every knowledge point in [easy to understand] style. If there are cute kids who are interested in [back-end technology], they are also welcome to pay attention β€ οΈ β€ οΈ β€ [one student] β€ οΈ β€ οΈ β€ Finally, I will bring you great [harvest and surprise] ππ!