java 联合主键怎么插入数据 jpa联合主键注解

您所在的位置:网站首页 jpa设置联合主键 java 联合主键怎么插入数据 jpa联合主键注解

java 联合主键怎么插入数据 jpa联合主键注解

2024-05-15 15:58| 来源: 网络整理| 查看: 265

一、JPA和复合主键的简介       JPA全称Java Persistence API,是一组用于将数据存入数据库的类和方法的集合。JPA通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。JPA的目标是为了整合第三方ORM框架,建立一套标准的API。目前JPA的提供商包括ORacle,Redhat,Eclipse等,提供的产品包括Hiberate, Eclipselink, Toplink, Spring Data JPA等。         复合主键也就是说需要多个字段才能确定数据库记录中的唯一一行。这样就需要多个字段一起,组成主键,也叫联合主键。比如将PC中所有应用的网络信息保存到一个数据表中,可以将IP和端口设置为复合主键。        二、SpringData JPA复合主键 的使用1、复合主键 和 联合主键

复合主键 : 一张表中 , 两个字段 确定一条唯一数据 ;

联合主键 : 表A , 表 B 两张表 , 通过中间表 , 确定两张表的对应关系 ; (中间表三个字段 : id , 表A_id, 表B_id) ; 此时中间表的id 称为 联合主键 ;

CREATE TABLE adm_info( sys_id varchar(20), shop_name varchar(20), donate_money decimal(15,2), PRIMARY KEY (sys_id,shop_name) ) 2、spring jpa 复合主键 的使用 方式一   采用 @IdClass 来注解复合主键   配置联合主键

由于表中是两个主键的存在,接下来改造一下我们的实体类:

@Entity @Data @IdClass(IcAdmInfoPk.class) @Table(name = "sys_info") public class IcFilmInfo implements Serializable { private static final long serialVersionUID = 9121531612760132363L; @Id @Column(name = "SysId") private String sId; /** * 商品名 */ @Id @Column(name = "ShopName") private String shopName; }

在两个主键映射的字段上都标注@Id注解 同时新建一个 IcAdmInfoPk 类:

@Data public class IcAdmInfoPk implements Serializable { private static final long serialVersionUID = -1570834456846591727L; private String sysId; private String shopName; }

在实体类上加上@IdClass(IcAdmInfoPk .class)注解

@Query(value = "select * from t_info where SysId = ?1",nativeQuery = true) List findBySysIdSQL(String sysId);方式二   自定义接收类  (推荐)

新建一个IcAdmInfoVO类:

@AllArgsConstructor @Data public class IcAdmInfoVO { private String sysId; /** * 商品名 */ private String shopName; }注意要添加 全参构造方法注解@AllArgsConstructorJAP代码 @Query(value = "select new sys.vo.IcAdmInfoVO(t.sysId,t.shopName) from IcAdmInfo t where t.sysId = ?1") List findBySysId(String sysId);注意,这个时候这里的 @Query 注解里面是没有加 nativeQuery = true方式三  通过复合主键对象+@Embeddable,和实体对象+@Embedded注解//主键类 @Embeddable @Data public class PrimaryKey implements Serializable{ private String sysId; /** * 商品名 */ private String shopName; } //实体类 @Entity @Table(name="A") public class A{ @EmbeddedId private PrimaryKey idCLass; public PrimaryKey getIdCLass() { return idCLass; } public void setIdCLass(PrimaryKey idCLass) { this.idCLass = idCLass; } private String shopName; public String getShopName() { return shopName; } public void setShopName(String ShopName) { this.shopName= shopName; } }

注意:  

  1) 实现Serializable接口(否则会报错,错误会直接显示); 

  2)在复合主键的类上,使用注解@Embeddable

  3) 有默认的public无参数的构造方法(在我这个实例中,我没有添加有参构造方法,所以采用默认的构造方法)

  如果你在实体类里有有参构造方法,那么一定要有一个无参构造方法,否则运行的时候会报错

 org.hibernate.InstantiationException: No default constructor for entity:  : com.my.model.People

这个就是没有默认的构造方法造成的,所以要在实体类中加入默认的无参构造方法。

  4) 重写equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。hashCode方法返回当前对象的哈希码(我验证EntityManger,不重写也没事。);

三、复合主键的增删改查3.1 增加操作 带有复合主键的数据库的保存操作,和只有单个主键的保存操作相同,如下:

保存一个实体,repository.save(T entity) 保存多个实体,repository.save(Iterable< T> entities) 保存并立即刷新一个实体,repository.saveAndFlush(T entity)

3.2 查询操作 带有复合主键的数据库的查询操作,可以用复合主键作为整体进行查询

PrimaryKey primaryKey = new PrimaryKey(); primaryKey.setA_id(1); primaryKey.setB_id(2); repository.findOne(primaryKey);

3.3 更新操作 更新操作的参考代码如下:

    @Transactional     @Modifying     public void update(A a) {             A finda = repository.findOne(a.getIdCLass());   //这里的repository是继承于JpaRepository的接口             finda.set(secondlevelEntity.getName());     }

3.4 删除操作 删除操作的参考代码如下:

 @Transactional     @Modifying     public void update(A a) {             A finda = repository.findOne(a.getIdCLass());   //这里的repository是继承于JpaRepository的接口             repository.delete(finda);     }

总结:

针对上面两种方法,貌似都可以解决我们的问题,但是推荐第一种,因为第一种是最贴合数据库的,使用了联合主键的注解,数据库中也是多主键,但是第二种方式可以很好的解决我们在使用JPA去查询的时候接口其他非数据库字段的信息,例如统计等方面。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3