spring-data-jpa Spring Data JPA,添加记录(插入数据)作为“外键id”,而不是作为“实体”,有区别吗?

neekobn8  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(231)

我找不到我问题的答案,希望这不是一个重复的问题。下面是一个虚构的例子。

数据库模型

数据表“用户”:

+--+--------+
|id|username|
+--+--------+
|1 |someUser|
+--+--------+

我想知道什么时候有什么不同:
1.实体(联系人)以“userId”Map为外键值(例如1)的方式保存到数据库
1.实体(联系人)保存到数据库中的方式是使用“userId”从数据库中检索相应的用户实体,并设置为联系人。

控制器

@RestController
public class ContactController {
    // to keep is short, all action is here in controller
    @Resource
    private ContactMapper contactMapper;

    @Resource
    private ContactRepository contactRepository;

    @Resource
    private UserRepository userRepository;

    @PostMapping("/as-foreign-key")
    public void addContactWithUserIdForeignKey(@RequestBody ContactDto dto) {
        Contact contact = contactMapper.contactDtoToContact(dto);
        contactRepository.save(contact);
    }

    @PostMapping("/as-entity")
    public void addContactWithUserEntity(@RequestBody ContactDto dto) {
        User user = userRepository.findById(dto.getUserId()).get();

        Contact contact = contactMapper.contactDtoToContact(dto);
        contact.setUser(user);
        contactRepository.save(contact);
    }

}

DTO

@Data
public class ContactDto implements Serializable {
    private final String firstName;
    private final String lastName;
    private final Integer userId;
}

MapStructMap器

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public interface ContactMapper {

    @Mapping(source = "userId", target = "user.id")
    Contact contactDtoToContact(ContactDto contactDto);

}

实体

第一个

正在执行两个请求:

第一个

结果
数据表“联系人”:

+--+----------+---------+-------+
|id|first_name|last_name|user_id|
+--+----------+---------+-------+
|1 |John      |Doe      |1      |
|2 |Jane      |Done     |1      |
+--+----------+---------+-------+

两种方法产生相同的结果。
从控制台上看,我可以看到下面的hibSQL语句。

Hibernate: select user_.id, user_.username as username2_1_ from "user" user_ where user_.id=?
Hibernate: insert into contact (first_name, last_name, user_id) values (?, ?, ?)

Hibernate: select user0_.id as id1_1_0_, user0_.username as username2_1_0_ from "user" user0_ where user0_.id=?
Hibernate: insert into contact (first_name, last_name, user_id) values (?, ?, ?)

到目前为止我一直认为正确的方法是第二种方法:首先,找到实体(用户),使用setter,然后保存。
这两种方法在技术上有什么区别吗?我可以安全地走第一种方法吗?还是有什么我应该考虑的?
任何关于这个主题的信息都非常感谢。

yqlxgs2m

yqlxgs2m1#

实际上,我很惊讶1)能起作用,因为您正在使用一个分离的实体对象来进行关联。除非您的Map器或存储库实现以某种方式神奇地调用EntityManager.find(User.class, dto.userId),否则我认为您应该选择3),即根本不加载用户,而是通过userRepository.getOne(dto.getUserId())获取一个托管代理。

相关问题