关于一些jpa和hibernate的一些常见问题:
// ① jpa顾名思义就是Java PersPersistence Api 【Java持久化接口】旨在规范,简化Java对象的的持久化工作 使用jpa持久化对象,并不依赖与一个ORM【Object Relation Mapping】对象关系映射
// 如果抛jpa直接使用hibernate的注解来定义model,会出现问题:
// 一些重要的注解如:Colomun OneToMany等,hibernate并没有提供 这说明jpa的注解已经是深入到hibernate的核心了,hibernate只是提供了一些补充,并不是两套注解,
// 以下是网友们在Stack Overflow上面对jpa和hibernate提出的问题
// 问题1: 如果用hibernate的注解,是不是一定会用到jpa注解,网友的回答是:是的。如果hibernate认为jpa的注解够用,就直接用,否则自己会补充一些出来
// 问题2: jpa和hibernate都提供了Entity,我们该用哪个?还是一一起用?网友的回答是:hibernate的Entity集成了jpa的,所以如果觉得jpa的不够用,直接用hibernate的即可。
// 关于jpa懒加载和急加载eager的认识:
// 在数据库实体字段中是使用懒加载的字段 表明在加载一个实体时候,定义了懒加载的属性不会直接从数据库中查找加载该属性
// 急加载表明在加载一个实体时候,定义急加载属性的字段会直接从数据库中加载。
// 例如: 用户登录某个网站,一个User的实体类,用户的username定义成急加载,age,sex定义为懒加载,当用户登录成功后,能直接看到用户的姓名XXX已经登录但是用户的基础信息不需要
Employee实体:
// ① jpa顾名思义就是Java PersPersistence Api 【Java持久化接口】旨在规范,简化Java对象的的持久化工作 使用jpa持久化对象,并不依赖与一个ORM【Object Relation Mapping】对象关系映射
// 如果抛jpa直接使用hibernate的注解来定义model,会出现问题:
// 一些重要的注解如:Colomun OneToMany等,hibernate并没有提供 这说明jpa的注解已经是深入到hibernate的核心了,hibernate只是提供了一些补充,并不是两套注解,
// 以下是网友们在Stack Overflow上面对jpa和hibernate提出的问题
// 问题1: 如果用hibernate的注解,是不是一定会用到jpa注解,网友的回答是:是的。如果hibernate认为jpa的注解够用,就直接用,否则自己会补充一些出来
// 问题2: jpa和hibernate都提供了Entity,我们该用哪个?还是一一起用?网友的回答是:hibernate的Entity集成了jpa的,所以如果觉得jpa的不够用,直接用hibernate的即可。
// 关于jpa懒加载和急加载eager的认识:
// 在数据库实体字段中是使用懒加载的字段 表明在加载一个实体时候,定义了懒加载的属性不会直接从数据库中查找加载该属性
// 急加载表明在加载一个实体时候,定义急加载属性的字段会直接从数据库中加载。
// 例如: 用户登录某个网站,一个User的实体类,用户的username定义成急加载,age,sex定义为懒加载,当用户登录成功后,能直接看到用户的姓名XXX已经登录但是用户的基础信息不需要
// 直接就能看到,所以使用懒加载即可。所以就延伸出来了这两种加载方式。
我们以Department和Employee来说明jpa表关联的实例:
Departtment实体:
@Entity
@Data
@Table(name = "department")
@ToString
public class Department implements Serializable{
@Id
@GeneratedValue
@Column(name = "id")
private Integer Id;
@Column(name = "department_id")
private Integer departmentId;
@Column(name = "department_name")
private String departmentName;
@Column(name = "department_manager")
private String departmentManager;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER) // 级联保存 更新 删除 刷新 延迟加载
// 也就是关联映射了一张新的表 department_employee 默认是通过两张表名称+ “_” 来命名的 其中新表的department_id字段作为一个外键映射到当前表的“id”字段,
// 需要映射的表employee的字段employee_id 也作为一个外键映射到新表的employee_id字段
// @JoinTable(name = "department_employee",joinColumns = {@JoinColumn(name = "department_id",referencedColumnName = "id")},
// inverseJoinColumns = {@JoinColumn(name = "employee_id",referencedColumnName = "employee_id")})
@JoinColumn(name = "department_id") // 外键关联
private Set<Employee> employee = new HashSet<>();
Employee实体:
@Entity
@Data
@Table(name = "employee")
@ToString
public class Employee implements Serializable {
@Id
@GeneratedValue
@Column(name = "employee_id")
private Integer employeeId;
@Column(name = "employee_name")
private String employeeName;
@Column(name = "department_id")
private Integer departmentId;
Dao层:
@Repository
public interface departmentRepository extends JpaRepository<Department,Integer>{
/**此处的By字段后面的名称一定要和entity里面的是一致的不能【注意】*/
Department findBydepartmentId(Integer department_id);
}
表结构:
测试用例如下:
@SpringBootTest
@RunWith(SpringRunner.class)
public class departmentRepositoryTest {
@Autowired private departmentRepository repository;
@Autowired private EntityManager entityManager;
@Test
public void testFindBydepartmentid() throws Exception {
//System.out.println(repository.findBydepartmentId(1));
Department department = entityManager.find(Department.class,1);
System.out.println(department.getEmployee().toString());
}
}