JPA中关系印射注意事项

 
一对一不用多说.
一对多:
       一A对多B.单向: (tb_a,tb_b)
       代码省略必须的但和主题的内容如@Entity等标记,Setter,Getter等
       class A{
       private int id;
       ………………..其它字段
      
       @OneToMany(cascade = CascadeType.ALL)
       private List<B> bs = new ArrayList<B>();
}
       class B{
              private int id;
              …………………其它字段
}
       只在A这一端加上@OneToMany就行了.B这一端不用任何标记,这时JPA一定要求另外一个辅助表.表名为:tb_a_tb_b即两表用_连结,其中保存两个表的ID关系.字段名称为:
      
       a_id,B在A中引用的字段+”_ID”;即 bs_id; 如果是自动生成表,这个关联表也会自动生成.
       在单向一对多时的操作时也是只需单向设置即可,ID对应关系由关联表自动维护:
      
       B b = new B();
       //不用b.setId(xxx);
       A a = new A();
       a.getBs().add(b);
       em.persist(a);
 
    A对多B.双向(tb_a,tb_b)
    如果不想用中间关联表,只能用双向关系:
    class A{
       private int id;
       ………………..其它字段
      
       @OneToMany(cascade = CascadeType.ALL,mappedBy="a")
       private List<B> bs = new ArrayList<B>();
}
       class B{
              private int id;
              …………………其它字段
              @ManyToOne(cascade = CascadeType.ALL)
              @JoinColumn(name = "a_id")
              private A a;
}
 
此时tb_b中需a_id字段.
操作时需要双向设置,否则a_id为null,关系丢失:
B b = new B();
       //其它set.
       A a = new A();
       b.setA(a);
       a.getBs().add(b);
       em.persist(a);
       这样才能正确保存完整的数据格式
      B A.双向(tb_a,tb_b)
当然,你可以从B中利用外健默认单向关联ManyToOne,但这样的单向关系在绝大多数场合没有意义.
如一个班级没有获取学生的集合,却在学生实体中获取班级,虽然可能,但没有多少人不把它做成双向关系的:
       这里需要在tb_b中设置a_id为外键关联到tb_a中的id.
    class A{
       private int id;
       ………………..其它字
}
       class B{
              private int id;
              …………………其它字段
              @ManyToOne(cascade = CascadeType.ALL) //默认多对一,只此一行设置
              private A a;
}
         而且这里的操作应该是:
        A a = new A();
        B b = new B();
        b.setA(a);
        em.persist(b);
### MyBatis 和 JPA 共用时的注意事项及最佳实践 在实际开发中,MyBatis 和 JPA 的共用场景并不常见,但有时为了满足特定需求或历史原因,可能会同时使用这两种技术。以下是在 MyBatis 和 JPA 共用时需要注意的事项以及最佳实践: #### 1. **事务管理** MyBatis 和 JPA 使用不同的事务管理机制。如果两者在一个项目中共存,必须确保事务的一致性。通常可以通过 Spring 的 `@Transactional` 注解来统一管理事务。例如: ```java @Transactional public void performOperation() { // 调用 MyBatis 操作 myBatisService.performAction(); // 调用 JPA 操作 jpaService.performAction(); } ``` 确保两者的操作都在同一个事务上下文中执行[^3]。 #### 2. **数据一致性** 由于 MyBatis 和 JPA 的持久化机制不同,可能会导致数据不一致的问题。例如,JPA 的持久化上下文(Persistence Context)会缓存实体对象,而 MyBatis 直接操作数据库。为避免问题,可以考虑以下方法: - 在需要严格一致性的场景下,禁用 JPA 的二级缓存。 - 确保 MyBatis 和 JPA 的 SQL 操作不会冲突,尤其是在更新同一张表时[^4]。 #### 3. **性能优化** 当 MyBatis 和 JPA 共用时,性能优化尤为重要。以下是一些优化建议: - **合理使用缓存**:对于频繁查询的数据,可以使用 MyBatis 的一级或二级缓存,或者 JPA 的二级缓存[^3]。 - **索引优化**:确保数据库表上有适当的索引,以提高查询效率。 - **减少循环操作**:避免在循环中多次调用数据库操作,尽量将批量操作合并为单次执行。 #### 4. **SQL 调优** MyBatis 提供了灵活的 SQL 配置能力,而 JPA 则依赖于 HQL 或 JPQL。在共用时,可能需要对两者的 SQL 进行调优。例如: - 对于复杂的查询,优先使用 MyBatis 的 XML 配置或注解方式编写高效的 SQL[^1]。 - 对于简单的 CRUD 操作,可以继续使用 JPA 的内置功能[^2]。 #### 5. **代码分离与模块化** 为了避免代码混乱,建议将 MyBatis 和 JPA 的逻辑分别封装在不同的模块中。例如: - 创建一个专门的 `mybatis-repository` 包用于存放 MyBatis 的 Mapper 接口和 XML 文件。 - 创建一个 `jpa-repository` 包用于存放 JPA 的 Repository 接口。 #### 6. **日志监控** 在 MyBatis 和 JPA 共用时,日志监控尤为重要。可以通过以下方式捕获 SQL 执行情况: - 配置 MyBatis 的日志级别为 `DEBUG`,查看生成的 SQL 语句。 - 使用 Spring Data JPA 的 `show-sql` 属性开启 SQL 输出。 --- ### 示例代码 以下是一个结合 MyBatis 和 JPA 的示例: #### MyBatis Mapper ```java @Mapper public interface MyBatisMapper { @Select("SELECT * FROM users WHERE id = #{id}") User findUserById(int id); } ``` #### JPA Repository ```java @Repository public interface JpaUserRepository extends JpaRepository<User, Integer> { @Query("FROM User u WHERE u.id = :id") Optional<User> findById(@Param("id") int id); } ``` #### 统一服务层 ```java @Service public class UserService { @Autowired private MyBatisMapper myBatisMapper; @Autowired private JpaUserRepository jpaUserRepository; public User getUserById(int id) { // 使用 MyBatis 查询用户 User userFromMyBatis = myBatisMapper.findUserById(id); // 使用 JPA 查询用户 Optional<User> userFromJpa = jpaUserRepository.findById(id); // 合并结果或处理逻辑 return userFromJpa.orElse(userFromMyBatis); } } ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值