在 MyBatis 中,当你插入一条记录并且想要获取自增主键(通常是数据库自动产生的 ID)时,可以通过使用 <insert>
标签内的 useGeneratedKeys
和 keyProperty
属性来实现。
下面是一个例子,展示如何在 MyBatis 的映射文件中插入一条记录并返回自增主键:
假设你有一个 User
类,其中包含 id
字段作为主键,你希望在插入新用户后能够获取这个自动生成的 ID。
首先,在你的实体类中确保主键字段有对应的 getter 和 setter 方法。(也可以使用注解,不用手动写出来)
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
public User() {
}
public User(Long id, String name, Integer age, String email) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
}
}
在 MyBatis 的映射文件中使用 useGeneratedKeys
和 keyProperty
属性。
假设你的映射文件是 UserMapper.xml
:
<insert id="save" useGeneratedKeys="true" keyProperty="id">
insert into User(name, age, email)
values (#{name}, #{age}, #{email})
</insert>
这里 useGeneratedKeys="true"
表示启用生成主键的功能,而 keyProperty="id"
指定将生成的主键值设置到 User
对象的 id
属性上。
在 Java 代码中调用插入方法。
当你调用这个插入方法时,传入的 User
对象的 id
将会被设置为数据库生成的主键值。
测试类
@SpringBootTest
public class UserServiceTest {
@Resource
private UserService userService;
@Test
public void testAddUser() {
User user = new User();
user.setName("1号用户");
user.setAge(18);
user.setEmail("123465@qq.com");
int result = userService.saveUser(user);
System.out.println(result + "--------" + user.getId());
}
}
service层:
public interface UserService {
List<User> getAllUser();
int saveUser(User user);
}
impl实现类:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public int saveUser(User user) {
return userMapper.save(user);
}
}
mapper层:
public interface UserMapper {
List<User> queryAllUser();
int save(User user);
}
调用 insertUser
方法后,MyBatis 会自动填充 入参对象User
对象的 id
属性。
如果mapper层上的入参使用的是 @Param 注解,给参数去了别名 那在sql中也要带上别名
public interface UserMapper {
List<User> queryAllUser();
int save(@Param("user")User user);
}
<insert id="save" useGeneratedKeys="true" keyProperty="user.id">
insert into User(name, age, email)
values (#{user.name}, #{user.age}, #{user.email})
</insert>
至于,keyProperty
属性中参数所要 指定对应的JavaBean对象中属性要不要也加上相应的别名,目前测试着加不加都行
测试环境是:
我个人选择倾向选择不加,万一报错,还能先考虑到是不是没加别名的原因,排除一个错误可能。
特别注意,返回类型为 int
表示插入操作影响的行数,通常情况下,如果插入成功,这个值会是 1。但如果你不关心影响的行数,也可以将返回类型更改为 void
。
另外还有一点需要注意: Integer、Long 、Boolean都可以作为insert, delete, update的返回值。
在 MyBatis 中,insert
语句本身通常不会返回任何值,因为 SQL 的 INSERT
语句设计上就是用来插入数据并不返回任何结果的。但是,MyBatis 提供了一些机制来处理插入操作后的一些需求,比如获取自动生成的主键。
如果你想要返回除自增主键外的其他值,可能需要使用存储过程或者在插入之后执行另一个查询来获取所需的值。但是,在标准的 SQL 插入语句中,直接返回非自动生成的值是不常见的。
请注意,这种方法依赖于你的数据库支持自增主键功能,比如 MySQL 的 AUTO_INCREMENT
。对于不同的数据库,自增主键的实现可能略有不同,但基本原理是相似的。
另外,如果你使用的是 MyBatis Generator 自动生成的代码,通常这些设置会自动为你处理好。如果你手动编写映射文件,那么遵循上述步骤即可。
在 MyBatis 中,当你在执行插入操作并需要获取由数据库自动生成的键值时,keyColumn
, keyProperty
, 和 useGeneratedKeys
这三个属性就变得非常有用。它们主要用于处理自增主键或者其他类型的自动产生的唯一标识符。下面分别解释这三个属性的含义和使用场景:
useGeneratedKeys
这个属性用于指示 MyBatis 是否应该尝试获取由数据库生成的键。当设置为 true
时,MyBatis 将尝试从数据库中检索生成的键值,并将其设置到映射的对象上。
使用场景:
keyProperty
这个属性指定一个 JavaBean 属性的名字,MyBatis 会在插入操作后将数据库生成的键值设置到该属性上。通常,这会是你的实体类中的一个字段,例如 id
。
使用场景:
keyColumn
这个属性指定了数据库表中生成键所在的列的名称。这在数据库有多个可能的候选键或自增列的情况下尤为重要,确保 MyBatis 知道应该关注哪一列。
使用场景:
假设你有一个 User
类,其中包含一个 id
字段作为主键,并且你在数据库中使用自增主键。
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO user (username, password) VALUES (#{username}, #{password})
</insert>
@Insert("INSERT INTO user (username, password) VALUES (#{username}, #{password})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public int insertUser(User user);
以上配置将确保在插入用户后,User
实体中的 id
字段会被数据库自动生成的键值填充。这样你就可以立即使用这个 ID 进行其他操作,例如立即获取刚插入的用户记录等。
综上所述:
一般情况,只需要有useGeneratedKeys="true" keyProperty="id"
2个属性一起搭配使用就行。
二般情况下,数据库的表有多个可能的候选键或自增列,为确保 MyBatis 知道应该关注哪一列,才需要keyColumn
属性指定数据库表中生成键所在的列的名称。