Mybatis useGeneratedKeys in simple terms

Mybatis useGeneratedKeys in simple terms

For single data insert (or update), useGeneratedKeys
batch operation uses ON DUPLICATE KEY, which is not explained here



1. Doubts about useGeneratedKeys

I wrote this record mainly when I was reviewing Mybatis, and when I wrote a section of CRUD, I was surprised by the results of my written business, which was not quite the same as what I remembered, so I wrote this article as a record. The questions are as follows :
Order.java

public class Order {
	private Long id;
	private String serial;
}

orderMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" 
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vic.mybatis.dao.OrderDao">
	<insert id="createOrder" useGeneratedKeys="true" keyProperty="id">
		insert into t_order(serial) values (#{serial})
	</insert>
</mapper>

OrderDao.java

@Mapper
public interface OrderDao {
    public int createOrder(Order order);
}

OrderServiceImpl.java

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderDao orderDao;

    @Override
    public int createOrder(Order order) {
    	// 这个result是否就是插入数据成功后返回的主键ID?
    	int id = orderDao.createOrder(order);
    	log.info(" *****插入数据后返回的id: " + id + " *****");
    	log.info(" *****插入数据后返回的id: " + order.getId() + " *****");
        return result;
    }
}

For the business I wrote above, among the two lines of information output in OrderServiceImpl.java , the first line is always 1 (because a piece of data was inserted into the database after I inserted it, here it is considered that the inserted data was successful, because it still fails , let’s not talk about it here)
But when I inserted the fifth piece of data and returned 1, I found that I was a little bit confused, because I was confused. Does the createOrder method return the status of executing sql, or should it return Is the primary key ID of this data? Because I set it useGeneratedKeys="true", isn't its definition the convention to generate the primary key and return it?
With my doubts, I started some coquettish operations, checked the documentation, looked at the source code, just like seeing useGeneratedKeyswhat the hell this parameter is.
As follows, 啰嗦务怪, the technology is not enough, let me make up nonsense, try to understand next time I read this article:


2. What is the official definition of useGeneratedKeys?

  1. First of all, let's look at the official website description of mybatis's description of useGeneratedKey in mapper

(insert and update only) This tells MyBatis to use the JDBC getGeneratedKeys method to retrieve keys generated internally by the database (e.g. auto increment fields in RDBMS like MySQL or SQL Server). Default: false.

It is obtained by using the getGeneratedKeys method of JDBC, and only insertand updateare valid. But pay attention, what I wrote in the subtitle above is in the mapper, why, because there are also configuration and Mapper interface mapping annotations

  1. Let's take a look at the official website description of mybatis's description of useGeneratedKey in Configuration

Allows JDBC support for generated keys. A compatible driver is required. This setting forces generated keys to be used if set to true, as some drivers deny compatibility but still work (e.g. Derby). Default: false.

Allows JDBC support for automatic generation of primary keys. A compatible driver is required. If set to true, this setting will force the use of generated primary keys, because some drivers refuse compatibility, but it still works (such as Derby), and when it appears in the setting, it will take effect globally.

  1. Let's take a look at mybatis's description of useGeneratedKey in annotation mapping Official website description

@Options This annotation provides access to the wide range of switches and configuration options that are normally present on the mapped statement as attributes

The @Options annotation provides access to a wide range of switches and configuration options. These switches and configuration options usually appear in the mapping statement as attributes, which means that after this configuration, it will directly appear in the mapping statement as an attribute and will override The configuration in the above Configuration (setting)

3. useGeneratedKeys in Mybatis?

useGeneratedKeysI won't delve into its working process or principle here .


3.1. For useGeneratedKey in Configuration (setting)

<settings>
	<setting name="useGeneratedKeys" value="true" />
</settings>

After the execution insertis successful, you can get the primary key ID automatically generated by the database, because setting useGeneratedKeys in the settings element is globally effective, but actually it will only affect the interface mapper (without @Options annotation configured at the same time) and xml The mapper does not work.

3.2. For useGeneratedKey in mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" 
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vic.mybatis.dao.OrderDao">
	<insert id="createOrder" useGeneratedKeys="true" keyProperty="id">
		insert into t_order(serial) values (#{serial})
	</insert>
</mapper>

The useGeneratedKeys attribute configured in mapper (xml) will only affect the current mapper (xml mapper), and the global useGeneratedKeys parameter value set in the settings element has no effect on mapper (xml mapper).

3.3. For useGeneratedKey in annotation mapping

@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into t_order(serial) values(#{serial})")
Integer createOrder(Order order);

At the same time, the useGeneratedKeys property is added to both Configuration(setting) and the interface mapper. Regardless of whether the property values ​​are the same, the priority of the interface mapper will be higher than that of Configuration(setting); that is, no matter you are in Configuration
( setting) set useGeneratedKeys to true or false, as long as you set @Options(useGeneratedKeys = true) in the interface mapper, then the primary key ID will be returned, if @Options(useGeneratedKeys = false), then the primary key ID will not be returned

4. Based on the previous questions?

When useGeneratedKeys = true is set, after insert (or update) is executed, the primary key ID will be returned, so I output two information in OrderServiceImpl.java above in the question , the first output is the execution status, and the second is the primary key ID.
So what exactly is returned after the createOrder method is executed?
The bug executes the insert operation and finally goes to
As shown in the figure above, after we executed the insert operation, we finally came here. You read it right, it is the update method, which returns the ps.getUpdateCount()result. This method is very familiar. When we simply used JDBC to operate the data, was there any image? ? I'll post a picture
result set

Retrieves the current result as an update count;

There are also -1cases, in human terms, the number of lines affected.


Alright, let’s stop here, come on ~ Sao Nian, work hard, uncle.

The next article looks at the insert process and the primary key generation process

如果写错或者不妥善地方, 欢迎大佬留言指正,不喜勿碰,感谢各位大佬

If there is an afterlife, I will be a tree, standing forever, without joy or sorrow, half in the dust, half flying in the wind; half in the shade, half in the sun, very silent and very proud. Never rely on, never seek.
If there is an afterlife, I will turn into a gust of wind, and even an instant can become eternity. No sentimental feelings, no sentimental eyes. Half of it is free and easy in the rain, half of it is traveling in the spring; lonely, go on a long journey alone, take away all the faint thoughts, never miss, never love. ------ Sanmao

Guess you like

Origin blog.csdn.net/H1101370034/article/details/121231207