Chapter 2 MybatisPlus general CRUD
1. Overview
Recall that if we have a User table and have created the corresponding entity class, what do we need to do to implement the CRUD operation of the User table?
Steps for Mybatis universal CRUD
First, we need to write the UserMapper mapping interface and manually define the CRUD method in the UserMapper interface
Then we need to create usermapper XML Mapping file, and manually write the SQL statement corresponding to each method
Steps for MybatisPlus universal CRUD
Just create the UserMapper interface and inherit the BaseMapper interface. This is all the operations that need to be completed to use MP. We can make the Mapper interface we create have the most basic CRUD method without even creating an SQL mapping file
2. Insert operation
0,Insert API
// Insert a record int insert(T entity);
Parameter description
type | Parameter name | describe |
---|---|---|
T | entity | Entity object |
1. Insert: insert a record (int);
@Test public void insert() { User userOneby = new User(); userOneby.setName("Oneby"); userOneby.setAge(21); userOneby.setEmail("Oneby@baomidou.com"); int result = userMapper.insert(userOneby); System.out.println("Number of affected rows:" + result); System.out.println(userOneby); User userHeygo = new User(); userHeygo.setName("Heygo"); userHeygo.setAge(21); userHeygo.setEmail(null); result = userMapper.insert(userHeygo); System.out.println("Number of affected rows:" + result); System.out.println(userHeygo); }
When inserting data, the insert() method will make non empty judgment according to each attribute of the entity class, and only the field corresponding to the non empty attribute will appear in the SQL statement
The id field of the printout user object is not null, which indicates that the primary key is automatically backfilled by default. However, there is a problem: the primary key does not seem to be self incremented. Please refer to the @ TableId annotation to solve this problem, which will be discussed later
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51e0301d] was not registered for synchronization because synchronization is not active 2021-04-22 21:45:52.571 INFO 8228 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:45:52.696 INFO 8228 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@2097614581 wrapping com.mysql.cj.jdbc.ConnectionImpl@7a55f148] will not be managed by Spring ==> Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) ==> Parameters: 1385228362414358529(Long), Oneby(String), 21(Integer), Oneby@baomidou.com(String) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51e0301d] Number of affected rows: 1 User(id=1385228362414358529, name=Oneby, age=21, email=Oneby@baomidou.com) Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@bd1111a] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@501650218 wrapping com.mysql.cj.jdbc.ConnectionImpl@7a55f148] will not be managed by Spring ==> Preparing: INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? ) ==> Parameters: 1385228363135778818(Long), Heygo(String), 21(Integer) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@bd1111a] Number of affected rows: 1 User(id=1385228363135778818, name=Heygo, age=21, email=null)
3. Update operation
0,Update API
// Update the record according to the whereWrapper condition int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper); // Modify according to ID int updateById(@Param(Constants.ENTITY) T entity);
Parameter description
type | Parameter name | describe |
---|---|---|
T | entity | Entity object (set condition value, nullable) |
Wrapper | updateWrapper | Entity object encapsulates operation class (null able, and entity in it is used to generate where statement) |
1. Modify according to the primary key: int updateById(@Param(Constants.ENTITY) T entity);
@Test public void updateById() { User user = new User(); user.setId(1L); user.setName("Heygo"); user.setAge(21); user.setEmail(null); int result = userMapper.updateById(user); System.out.println("Number of affected rows:" + result); User retUser = userMapper.selectById(1); System.out.println(retUser); }
When updateById() method updates data, the update condition of SQL statement is WHERE id =?, Non null judgment will be made according to each attribute of the entity class, and only the field corresponding to the non null attribute will appear in the SQL statement
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5f303ecd] was not registered for synchronization because synchronization is not active 2021-04-22 21:46:10.286 INFO 18636 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:46:10.411 INFO 18636 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1066656936 wrapping com.mysql.cj.jdbc.ConnectionImpl@12b5454f] will not be managed by Spring ==> Preparing: UPDATE user SET name=?, age=? WHERE id=? ==> Parameters: Heygo(String), 21(Integer), 1(Long) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5f303ecd] Number of affected rows: 1 Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5d01ea21] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@596905862 wrapping com.mysql.cj.jdbc.ConnectionImpl@12b5454f] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email <== Row: 1, Heygo, 21, test1@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5d01ea21] User(id=1, name=Heygo, age=21, email=test1@baomidou.com)
2. Modify according to the condition constructor: int update (@ param (constants. Entity) t entity, @ param (constants. Wrapper) wrapper < T > updatewrapper);
@Test public void update() { User user = new User(); user.setName("NiuNiu"); user.setAge(18); user.setEmail(null); QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("id", 2); wrapper.eq("age", 20); int result = userMapper.update(user, wrapper); System.out.println("Number of affected rows:" + result); User retUser = userMapper.selectById(2); System.out.println(retUser); }
When updating data, the update() method will dynamically splice the conditions of the WHERE clause in the SQL statement according to the wrapper object, and make non empty judgment according to each attribute of the entity class. Only the fields corresponding to non empty attributes will appear in the SQL statement
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3b08f438] was not registered for synchronization because synchronization is not active 2021-04-22 21:46:25.325 INFO 20524 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:46:25.450 INFO 20524 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@203401172 wrapping com.mysql.cj.jdbc.ConnectionImpl@7a93b263] will not be managed by Spring ==> Preparing: UPDATE user SET name=?, age=? WHERE (id = ? AND age = ?) ==> Parameters: NiuNiu(String), 18(Integer), 2(Integer), 20(Integer) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3b08f438] Number of affected rows: 1 Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6d5037a9] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@1412612727 wrapping com.mysql.cj.jdbc.ConnectionImpl@7a93b263] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE id=? ==> Parameters: 2(Integer) <== Columns: id, name, age, email <== Row: 2, NiuNiu, 18, test2@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6d5037a9] User(id=2, name=NiuNiu, age=18, email=test2@baomidou.com)
4. Query operation
0,Select API
// Query by ID T selectById(Serializable id); // Query a record according to the entity condition T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query (batch query by ID) List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // Query all records according to the entity condition List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query (based on columnMap criteria) List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // Query all records according to Wrapper conditions List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records according to Wrapper conditions. Note: only the value of the first field is returned List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records (and turn the page) according to the entity condition IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query all records (and turn pages) according to Wrapper conditions IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // Query the total number of records according to Wrapper conditions Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Parameter description
type | Parameter name | describe |
---|---|---|
Serializable | id | Primary key ID |
Wrapper | queryWrapper | Entity object encapsulates operation class (null able) |
Collection<? extends Serializable> | idList | List of primary key ID S (cannot be null and empty) |
Map<String, Object> | columnMap | Table field map object |
IPage | page | Paging query criteria (can be rowboundaries. Default) |
1. Query a record according to the primary key: T selectById(Serializable id);
@Test public void selectById() { User user = userMapper.selectById(1); System.out.println(user); }
The selectById() method will query all fields in the table. The filter condition of the SQL statement is WHERE id =?
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@62e6a3ec] was not registered for synchronization because synchronization is not active 2021-04-22 21:46:38.630 INFO 20528 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:46:38.763 INFO 20528 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1289834245 wrapping com.mysql.cj.jdbc.ConnectionImpl@71dfcf21] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email <== Row: 1, Heygo, 21, test1@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@62e6a3ec] User(id=1, name=Heygo, age=21, email=test1@baomidou.com)
2. Batch query according to the primary key list: List < T > selectbatchids (@ param (constants. Collection) collection <? extends Serializable> idList);
@Test public void selectBatchIds() { List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2)); users.forEach(System.out::println); }
The selectBatchIds() method will query all fields in the table. The filter criteria of the SQL statement is WHERE id IN (?,?)
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3be4f71] was not registered for synchronization because synchronization is not active 2021-04-22 21:46:51.438 INFO 8972 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:46:51.563 INFO 8972 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@338765435 wrapping com.mysql.cj.jdbc.ConnectionImpl@342726f1] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE id IN ( ? , ? ) ==> Parameters: 1(Integer), 2(Integer) <== Columns: id, name, age, email <== Row: 1, Heygo, 21, test1@baomidou.com <== Row: 2, NiuNiu, 18, test2@baomidou.com <== Total: 2 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3be4f71] User(id=1, name=Heygo, age=21, email=test1@baomidou.com) User(id=2, name=NiuNiu, age=18, email=test2@baomidou.com)
3. Batch query according to columnMap conditions: List < T > selectbymap (@ param (constants. Column_map) map < string, Object > columnMap);
@Test public void selectByMap() { Map<String, Object> params = new HashMap<>() ; params.put("name", "NiuNiu"); params.put("age", 18); List<User> users = userMapper.selectByMap(params); users.forEach(System.out::println); }
All fields in the query table will be queried by the select method; The filter conditions of WHERE clause in SQL statement will be spliced dynamically according to the Map object
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3be4f71] was not registered for synchronization because synchronization is not active 2021-04-22 21:47:26.111 INFO 9296 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:47:26.252 INFO 9296 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1061806694 wrapping com.mysql.cj.jdbc.ConnectionImpl@5f18f9d2] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE name = ? AND age = ? ==> Parameters: NiuNiu(String), 18(Integer) <== Columns: id, name, age, email <== Row: 2, NiuNiu, 18, test2@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3be4f71] User(id=2, name=NiuNiu, age=18, email=test2@baomidou.com)
4. Query a record according to the condition constructor: t selectone (@ param (constants. Wrapper) wrapper < T > querywrapper);
@Test public void selectOne() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("name", "Oneby"); User user = userMapper.selectOne(wrapper); System.out.println(user); wrapper.clear(); wrapper.eq("age", 21); user = userMapper.selectOne(wrapper); System.out.println(user); }
The selectOne() method will query all fields in the table; The filter conditions of WHERE clause in SQL statement will be spliced dynamically according to wrapper object. If more than one result is obtained from the query, TooManyResultsException will be thrown
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7a344b65] was not registered for synchronization because synchronization is not active 2021-04-22 21:47:41.497 INFO 13692 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:47:41.628 INFO 13692 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1689723487 wrapping com.mysql.cj.jdbc.ConnectionImpl@33db72bd] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE (name = ?) ==> Parameters: Oneby(String) <== Columns: id, name, age, email <== Row: 1385228362414358529, Oneby, 21, Oneby@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7a344b65] User(id=1385228362414358529, name=Oneby, age=21, email=Oneby@baomidou.com) Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72d0f2b4] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@1831717330 wrapping com.mysql.cj.jdbc.ConnectionImpl@33db72bd] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE (age = ?) ==> Parameters: 21(Integer) <== Columns: id, name, age, email <== Row: 1, Heygo, 21, test1@baomidou.com <== Row: 4, Sandy, 21, test4@baomidou.com <== Row: 1385228362414358529, Oneby, 21, Oneby@baomidou.com <== Row: 1385228363135778818, Heygo, 21, null <== Total: 4 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72d0f2b4] org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4
5. Query the total number of records according to the condition constructor: integer selectcount (@ param (constants. Wrapper) wrapper < T > querywrapper);
@Test public void selectCount() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("age", 21); Integer count = userMapper.selectCount(wrapper); System.out.println(count); }
The selectCount() method will query all fields in the table; The filter conditions of the WHERE clause in the SQL statement will be spliced dynamically according to the wrapper object
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6b474074] was not registered for synchronization because synchronization is not active 2021-04-22 21:50:12.402 INFO 15376 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:50:12.527 INFO 15376 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@2140322192 wrapping com.mysql.cj.jdbc.ConnectionImpl@31e04b13] will not be managed by Spring ==> Preparing: SELECT COUNT( * ) FROM user WHERE (age = ?) ==> Parameters: 21(Integer) <== Columns: COUNT( * ) <== Row: 4 <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6b474074] 4
6. Query all records according to the condition constructor: List < T > selectlist (@ param (constants. Wrapper) wrapper < T > querywrapper);
@Test public void selectList() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("age", 21); List<User> users = userMapper.selectList(wrapper); users.forEach(System.out::println); }
The selectList() method will query all fields in the table; The filter conditions of the WHERE clause in the SQL statement will be spliced dynamically according to the wrapper object
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@108531c2] was not registered for synchronization because synchronization is not active 2021-04-22 21:50:49.681 INFO 1432 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:50:49.816 INFO 1432 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@870019773 wrapping com.mysql.cj.jdbc.ConnectionImpl@7f92b990] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE (age = ?) ==> Parameters: 21(Integer) <== Columns: id, name, age, email <== Row: 1, Heygo, 21, test1@baomidou.com <== Row: 4, Sandy, 21, test4@baomidou.com <== Row: 1385228362414358529, Oneby, 21, Oneby@baomidou.com <== Row: 1385228363135778818, Heygo, 21, null <== Total: 4 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@108531c2] User(id=1, name=Heygo, age=21, email=test1@baomidou.com) User(id=4, name=Sandy, age=21, email=test4@baomidou.com) User(id=1385228362414358529, name=Oneby, age=21, email=Oneby@baomidou.com) User(id=1385228363135778818, name=Heygo, age=21, email=null)
7. Query records according to paging conditions: < e extensions iPage < T > > e selectpage (e page, @ param (constants. Wrapper) wrapper < T > querywrapper);
@Test public void selectPage() { Page<User> page = new Page<>(); page.setCurrent(1); page.setSize(2); QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("age", 21); Page<User> userPage = userMapper.selectPage(page, wrapper); userPage.getRecords().forEach(System.out::println); }
The selectList() method will query all fields in the table; The filter conditions of WHERE clause in SQL statement will be spliced dynamically according to the wrapper object; The LIMIT OFFSET clause of the SQL statement will be spliced dynamically according to the page object
It can be seen from the log that there is no LIMIT OFFSET clause in the SQL statement, which indicates that the parameters set by the page object do not take effect, because we do not turn on the function of the paging plug-in, which will be described later
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b7b3edb] was not registered for synchronization because synchronization is not active 2021-04-22 21:51:34.960 INFO 13584 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:51:35.069 INFO 13584 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@870019773 wrapping com.mysql.cj.jdbc.ConnectionImpl@7f92b990] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE (age = ?) ==> Parameters: 21(Integer) <== Columns: id, name, age, email <== Row: 1, Heygo, 21, test1@baomidou.com <== Row: 4, Sandy, 21, test4@baomidou.com <== Row: 1385228362414358529, Oneby, 21, Oneby@baomidou.com <== Row: 1385228363135778818, Heygo, 21, null <== Total: 4 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b7b3edb] User(id=1, name=Heygo, age=21, email=test1@baomidou.com) User(id=4, name=Sandy, age=21, email=test4@baomidou.com) User(id=1385228362414358529, name=Oneby, age=21, email=Oneby@baomidou.com) User(id=1385228363135778818, name=Heygo, age=21, email=null)
5. Delete operation
0,Delete API
// Delete the record according to the entity condition int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // Delete (batch delete according to ID) int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // Delete by ID int deleteById(Serializable id); // Delete the record according to the columnMap condition int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Parameter description
type | Parameter name | describe |
---|---|---|
Wrapper | wrapper | Entity object encapsulates operation class (null able) |
Collection<? extends Serializable> | idList | List of primary key ID S (cannot be null and empty) |
Serializable | id | Primary key ID |
Map<String, Object> | columnMap | Table field map object |
1. Delete by primary key: int deleteById(Serializable id);
@Test public void deleteById() { int result = userMapper.deleteById(1); System.out.println("Number of affected rows:" + result); }
When the deleteById() method is executed, the deletion filter condition of the SQL statement is WHERE id =?
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@50d3bf39] was not registered for synchronization because synchronization is not active 2021-04-22 21:59:34.538 INFO 9312 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:59:34.668 INFO 9312 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1289834245 wrapping com.mysql.cj.jdbc.ConnectionImpl@71dfcf21] will not be managed by Spring ==> Preparing: DELETE FROM user WHERE id=? ==> Parameters: 1(Integer) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@50d3bf39] Number of affected rows: 1
2. Batch delete according to the primary key list: int deletebatchids (@ parameter (constants. Collection) collection <? extends Serializable> idList);
@Test public void deleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(2, 3)); System.out.println("Number of affected rows:" + result); }
When the deleteBatchIds() method is executed, the deletion filter condition of the SQL statement is WHERE id IN (?,?)
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@771db12c] was not registered for synchronization because synchronization is not active 2021-04-22 21:59:48.184 INFO 15280 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:59:48.314 INFO 15280 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@253380088 wrapping com.mysql.cj.jdbc.ConnectionImpl@5edf2821] will not be managed by Spring ==> Preparing: DELETE FROM user WHERE id IN ( ? , ? ) ==> Parameters: 2(Integer), 3(Integer) <== Updates: 2 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@771db12c] Number of affected lines: 2
3. Batch deletion according to columnMap conditions: int deletebymap (@ parameter (constants. Column_map) map < string, Object > columnMap);
@Test public void deleteByMap() { Map<String, Object> params = new HashMap<>(); params.put("name", "Billie"); params.put("age", 24); int result = userMapper.deleteByMap(params); System.out.println("Number of affected rows:" + result); }
When the deleteByMap method is executed, it will dynamically splice the filter conditions of the WHERE clause in the SQL statement according to the map object
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1eb6e1c] was not registered for synchronization because synchronization is not active 2021-04-22 22:00:00.418 INFO 15056 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 22:00:00.548 INFO 15056 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1066656936 wrapping com.mysql.cj.jdbc.ConnectionImpl@12b5454f] will not be managed by Spring ==> Preparing: DELETE FROM user WHERE name = ? AND age = ? ==> Parameters: Billie(String), 24(Integer) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1eb6e1c] Number of affected rows: 1
4. Batch deletion by condition constructor: int delete (@ param (constants. Wrapper) wrapper < T > querywrapper);
@Test public void delete() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("age", 21); int result = userMapper.delete(wrapper); System.out.println("Number of affected rows:" + result); }
When the delete method is executed, it will dynamically splice the filter conditions of the WHERE clause in the SQL statement according to the wrapper object
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3104351d] was not registered for synchronization because synchronization is not active 2021-04-22 22:00:13.593 INFO 8676 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 22:00:13.723 INFO 8676 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1077464378 wrapping com.mysql.cj.jdbc.ConnectionImpl@14ac77b9] will not be managed by Spring ==> Preparing: DELETE FROM user WHERE (age = ?) ==> Parameters: 21(Integer) <== Updates: 3 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3104351d] Number of affected lines: 3
6. Full column operation
mapper layer option
The options are located on COM baomidou. mybatisplus. extension. injector. Cooperation is required under the methods package Sql injector use, case See for details Source code comments
The most commonly used option should be AlwaysUpdateSomeColumnById. As mentioned earlier, the API will first judge whether the field is empty. If it is empty, it will not be updated, but AlwaysUpdateSomeColumnById will update the fixed fields according to the ID (but logical deletion is not included)
7. Common notes
@TableName
We change the table name of the database from user to t_user, execute the selectById() method again and find that the program throws an exception: BadSqlGrammarException
The specific information of the exception is: cause: Java sql. SQLSyntaxErrorException: Table 'mybatis_plus.user 'doesn't exist, saying that mybatis cannot be found_ plus. Use this form
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@652ab8d9] was not registered for synchronization because synchronization is not active 2021-04-20 08:22:38.576 INFO 3304 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-20 08:22:38.700 INFO 3304 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@665317128 wrapping com.mysql.cj.jdbc.ConnectionImpl@280e8a1a] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM user WHERE id=? ==> Parameters: 1(Integer) Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@652ab8d9] org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.user' doesn't exist ### The error may exist in com/oneby/mapper/UserMapper.java (best guess) ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### SQL: SELECT id,name,age,email FROM user WHERE id=? ### Cause: java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.user' doesn't exist ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.user' doesn't exist
MybatisPlus will use the class name of the entity class to find the corresponding table in the database by default, but if the class name of the entity class is inconsistent with the database, you need to use the @ TableName annotation to mark the database table name corresponding to the entity class
/** * @Author Oneby * @Date 2021/4/18 17:53 */ @Data @AllArgsConstructor @NoArgsConstructor @TableName("t_user") public class User { private Long id; private String name; private Integer age; private String email; }
We execute the query again, and the table name in the sent SQL statement becomes t_user
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@50d3bf39] was not registered for synchronization because synchronization is not active 2021-04-20 08:25:25.826 INFO 2428 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-20 08:25:25.951 INFO 2428 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1688526221 wrapping com.mysql.cj.jdbc.ConnectionImpl@2dddc1b9] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM t_user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email <== Row: 1, Jone, 18, test1@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@50d3bf39] User(id=1, name=Jone, age=18, email=test1@baomidou.com)
@TableName annotation
/** * Database table correlation * * @author hubin, hanchunlin * @since 2016-01-23 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) public @interface TableName { /** * Table name corresponding to entity */ String value() default ""; /** * schema * <p> * Configuring this value overrides the globally configured schema * * @since 3.1.1 */ String schema() default ""; /** * Whether to keep the value of using global tablePrefix * <p> It only takes effect when both the global tablePrefix and the value of {@ link #value()} above are set</p> * <li> If false, the global tablePrefix will not take effect</li> * * @since 3.1.1 */ boolean keepGlobalPrefix() default false; /** * Entity mapping result set, * method that only takes effect and is automatically injected by mp */ String resultMap() default ""; /** * Whether to automatically build and use the resultMap, * The method that only takes effect and is automatically injected by mp, * If the resultMap is set, the resultMap will not be automatically built and injected, * It is only applicable when typeHandler or JDBC type is set in individual fields * * @since 3.1.2 */ boolean autoResultMap() default false; /** * Attribute name to exclude * * @since 3.3.1 */ String[] excludeProperty() default {}; }
@TableField
We will t_ Change the user column of the user table to username, execute the selectById() method again, and find that the program throws an exception: BadSqlGrammarException
The specific information of the exception is: cause: Java sql. Sqlsyntaxerrorexception: unknown column 'name' in 'field list', which means the column name cannot be found
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5f13be1] was not registered for synchronization because synchronization is not active 2021-04-20 08:26:10.119 INFO 8344 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-20 08:26:10.244 INFO 8344 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1609754699 wrapping com.mysql.cj.jdbc.ConnectionImpl@74abbb] will not be managed by Spring ==> Preparing: SELECT id,name,age,email FROM t_user WHERE id=? ==> Parameters: 1(Integer) Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5f13be1] org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Unknown column 'name' in 'field list' ### The error may exist in com/oneby/mapper/UserMapper.java (best guess) ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### SQL: SELECT id,name,age,email FROM t_user WHERE id=? ### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'name' in 'field list' ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'name' in 'field list'
MybatisPlus will use the field name of the entity class to find the corresponding column in the database table by default (the hump naming rule is enabled by default), but when the class name of the entity class is inconsistent with the database, the @ TableField annotation needs to be used to mark the database table name corresponding to the entity class
/** * @Author Oneby * @Date 2021/4/18 17:53 */ @Data @AllArgsConstructor @NoArgsConstructor @TableName("t_user") public class User { private Long id; @TableField("username") private String name; private Integer age; private String email; }
We execute the query again, and the column name in the sent SQL statement becomes username
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@17814b1c] was not registered for synchronization because synchronization is not active 2021-04-22 22:16:13.980 INFO 19028 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 22:16:14.110 INFO 19028 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1487287849 wrapping com.mysql.cj.jdbc.ConnectionImpl@7de843ef] will not be managed by Spring ==> Preparing: SELECT id,username AS name,age,email FROM t_user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email <== Row: 1, Jone, 18, test1@baomidou.com <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@17814b1c] User(id=1, name=Jone, age=18, email=test1@baomidou.com)
@TableField annotation: if some fields in the entity class are not database fields, set exist = false
/** * Table field ID * * @author hubin sjy tantan * @since 2016-09-09 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) public @interface TableField { /** * Database field value * <p> * When this value does not need to be configured: * <li> When {@ link com.baomidou.mybatisplus.core.MybatisConfiguration#mapUnderscoreToCamelCase} is true, * (mp The default value is. Myfalse in the database replace("_","").toUpperCase() = = entity attribute name toUpperCase() </li> * <li> When {@ link com.baomidou.mybatisplus.core.MybatisConfiguration#mapUnderscoreToCamelCase} is false, * Database field value Touppercase() = = entity attribute name toUpperCase() </li> */ String value() default ""; /** * Is it a database table field * <p> * By default, true exists and false does not exist */ boolean exist() default true; /** * Field where entity query comparison criteria * <p> * Default {sqllink @ SQL} */ String condition() default ""; /** * The field update set is partially injected. This annotation is better than the el annotation * <p> * Example 1: @ tablefield (.., update = "% s + 1") where% s will be filled as a field * The output SQL is: update table set field = field + 1 where * <p> * Example 2: @ tablefield (.., update = "now()") uses database time * The output SQL is: update table set field = now() where */ String update() default ""; /** * Insert of field verification strategy: when the insert operation is performed, the strategy when the field splices the insert statement * <p> * IGNORED: Direct splicing insert into table_a(column) values (#{columnProperty}); * NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>) * NOT_EMPTY: insert into table_a(<if test="columnProperty != null and columnProperty!=''">column</if>) values (<if test="columnProperty != null and columnProperty!=''">#{columnProperty}</if>) * NOT_EMPTY If you are targeting a field of non CharSequence type, the effect is equal to NOT_NULL * * @since 3.1.2 */ FieldStrategy insertStrategy() default FieldStrategy.DEFAULT; /** * update of field validation policy: when updating, the policy when the field splices the set statement * <p> * IGNORED: Direct splicing update table_a set column=#{columnProperty}, null / empty string will be set in * NOT_NULL: update table_a set <if test="columnProperty != null">column=#{columnProperty}</if> * NOT_EMPTY: update table_a set <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> * NOT_EMPTY If you are targeting a field of non CharSequence type, the effect is equal to NOT_NULL * * @since 3.1.2 */ FieldStrategy updateStrategy() default FieldStrategy.DEFAULT; /** * Where of field validation policy: indicates the policy of the field when splicing the where condition * <p> * IGNORED: Direct splicing column=#{columnProperty} * NOT_NULL: <if test="columnProperty != null">column=#{columnProperty}</if> * NOT_EMPTY: <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> * NOT_EMPTY If you are targeting a field of non CharSequence type, the effect is equal to NOT_NULL * * @since 3.1.2 */ FieldStrategy whereStrategy() default FieldStrategy.DEFAULT; /** * Field auto fill policy * <p> * In the corresponding mode, the configuration of insertStrategy or updatestategy will be ignored, which is equal to asserting that this field must have a value */ FieldFill fill() default FieldFill.DEFAULT; /** * select query * <p> * Large fields can be set to false and will not be included in the select query range */ boolean select() default true; /** * Whether to keep the value of using global columnFormat * <p> * It only takes effect when both the global columnFormat and the value of {@ link #value()} above are set * If false, the global columnFormat will not take effect * * @since 3.1.1 */ boolean keepGlobalFormat() default false; /** * JDBC Type (this default value does not mean that it will take effect according to this value), * The method that only takes effect and is automatically injected by mp, * It is recommended to use with {@ link TableName#autoResultMap()} * <p> * {@link ResultMapping#jdbcType} and {@link ParameterMapping#jdbcType} * * @since 3.1.2 */ JdbcType jdbcType() default JdbcType.UNDEFINED; /** * Type processor (this default does not mean that it will take effect according to this value), * The method that only takes effect and is automatically injected by mp, * It is recommended to use with {@ link TableName#autoResultMap()} * <p> * {@link ResultMapping#typeHandler} and {@link ParameterMapping#typeHandler} * * @since 3.1.2 */ Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class; /** * Only when {@ link #typeHandler()} is used, judge whether to append javaType * <p> * Generally, it is not recommended * {@link ParameterMapping#javaType} * * @since 3.4.0 @2020-07-23 */ boolean javaType() default false; /** * Specify the number of digits to keep after the decimal point, * It only applies to method s automatically injected by mp, * It is recommended to use with {@ link TableName#autoResultMap()} * <p> * {@link ParameterMapping#numericScale} * * @since 3.1.2 */ String numericScale() default ""; }
@TableId
When we executed the insert() method before, we found that the primary key value of automatic backfill is not automatically incremented
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51e0301d] was not registered for synchronization because synchronization is not active 2021-04-22 21:45:52.571 INFO 8228 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 21:45:52.696 INFO 8228 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@2097614581 wrapping com.mysql.cj.jdbc.ConnectionImpl@7a55f148] will not be managed by Spring ==> Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) ==> Parameters: 1385228362414358529(Long), Oneby(String), 21(Integer), Oneby@baomidou.com(String) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51e0301d] Number of affected rows: 1 User(id=1385228362414358529, name=Oneby, age=21, email=Oneby@baomidou.com)
When we do not set the primary key type, MybatisPlus will help us register the auto fill plug-in for filling. If you want to set primary key auto increment, you need to use @ TableId(type = IdType.AUTO) annotation to identify the primary key field
/** * @Author Oneby * @Date 2021/4/18 17:53 */ @Data @AllArgsConstructor @NoArgsConstructor @TableName("t_user") public class User { @TableId(type = IdType.AUTO) private Long id; @TableField("name") private String name; private Integer age; private String email; }
When we execute the insert() method again to insert data, we find a magical thing: there is no id field in the issued SQL statement, but the program throws an exception: dataintegrity violationexception
The body information of the exception is: cause: Java sql. Sqlexception: field 'id' doesn't have a default value, which means t_ The id field in the user table does not have a default value
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@58399d82] was not registered for synchronization because synchronization is not active 2021-04-22 22:26:43.141 INFO 2324 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 22:26:43.258 INFO 2324 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1779219567 wrapping com.mysql.cj.jdbc.ConnectionImpl@67110f71] will not be managed by Spring ==> Preparing: INSERT INTO t_user ( username, age, email ) VALUES ( ?, ?, ? ) ==> Parameters: Oneby(String), 21(Integer), Oneby@baomidou.com(String) Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@58399d82] org.springframework.dao.DataIntegrityViolationException: ### Error updating database. Cause: java.sql.SQLException: Field 'id' doesn't have a default value ### The error may exist in com/oneby/mapper/UserMapper.java (best guess) ### The error may involve com.oneby.mapper.UserMapper.insert-Inline ### The error occurred while setting parameters ### SQL: INSERT INTO t_user ( username, age, email ) VALUES ( ?, ?, ? ) ### Cause: java.sql.SQLException: Field 'id' doesn't have a default value ; Field 'id' doesn't have a default value; nested exception is java.sql.SQLException: Field 'id' doesn't have a default value
This is because we did not set the id field to self increment in MySQL database. After setting the id field to self increment, we executed the insert() method again: the SQL statement did not carry the id field and its field value. The data was inserted successfully and the value of the self increment primary key was automatically backfilled
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3c017078] was not registered for synchronization because synchronization is not active 2021-04-22 22:29:24.961 INFO 17588 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-04-22 22:29:25.089 INFO 17588 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@313869647 wrapping com.mysql.cj.jdbc.ConnectionImpl@5445f5ba] will not be managed by Spring ==> Preparing: INSERT INTO t_user ( username, age, email ) VALUES ( ?, ?, ? ) ==> Parameters: Oneby(String), 21(Integer), Oneby@baomidou.com(String) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3c017078] Number of affected rows: 1 User(id=6, name=Oneby, age=21, email=Oneby@baomidou.com)
@TableId annotation
/** * Table primary key ID * * @author hubin * @since 2016-01-23 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) public @interface TableId { /** * Field name (this value can be null) */ String value() default ""; /** * Primary key type * {@link IdType} */ IdType type() default IdType.NONE; }
IdType primary key type
@Getter public enum IdType { /** * Self increment of database ID * <p>For this type, please ensure that the database is set with ID self increment, otherwise it is invalid</p> */ AUTO(0), /** * This type is not set with primary key (in the annotation, it is equal to follow the global, and the global value is equal to INPUT) */ NONE(1), /** * User input ID * <p>This type can be filled by registering the auto fill plug-in</p> */ INPUT(2), /* The following three types are automatically filled only when the inserted object ID is empty. */ /** * Assign ID (the primary key type is number or string), * Default implementation class {@ link com. Baomidou. Mybatisplus. Core. Increment. Defaultidentifier generator} (snowflake algorithm) * * @since 3.3.0 */ ASSIGN_ID(3), /** * Assign UUID (the primary key type is string) * Default implementation class {@ link com. Baomidou. Mybatisplus. Core. Increment. Defaultidentifiergenerator} (UUID. Replace ("-", "")) */ ASSIGN_UUID(4), /** * @deprecated 3.3.0 please use {@link #ASSIGN_ID} */ @Deprecated ID_WORKER(3), /** * @deprecated 3.3.0 please use {@link #ASSIGN_ID} */ @Deprecated ID_WORKER_STR(3), /** * @deprecated 3.3.0 please use {@link #ASSIGN_UUID} */ @Deprecated UUID(4); private final int key; IdType(int key) { this.key = key; } }