java复合主键注解_Java进阶知识06 Hibernate联合主键之Annotation(注解)和XML实现方式...

1、Hibernate联合主键(Annotation实现)

1.1、单列主键

1.1.1、为什么要有主键? //唯一确定一条记录

1.1.2、一个表能否有多个主键?//不能

1.1.3、为什么把id设为主键? //如果有其他的方式可以作为主键,id可以不要

1.1.4、主键生成策略:

identity:自增长,对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。

sequence:自增长,在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。

native:自增长,根据底层数据库的能力选择identity, sequence 或者hilo中的一个。如果是mysql,自动选择identity,如果是oracle,自动选择sequence 。

increment:自增长,只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。

assigned:指定主键生成策略

uuid:随机生成唯一值(String类型)

1.2、联合主键类必须要序列化,并重写equals和hashCode方法

主键类为什么要序列化?如果多个该类对象同时放入内存中,在一个集群系统中,其中一台服务器如果down机了,需要将内存中对象写到其它服务器。同时,如果该服务器内存已满,需要用虚拟内存,这就需要序列化后才能写到硬盘上。

1.3、注解

@Entity

@Table(name=”XXXX”)  //类名和表名一样,可省略不写

@Column(.....)

A.实现方式一:将联合主键类注解为@Embeddable、将对象中联合主键注解为@Id

B.实现方式二:在对象中把联合主键引用注解为@EmbeddedId

C.实现方式三:在对象中包含联合主键的字段、并将其都注解为@Id,并在该对象类上注解@IdClass(联合主键类.class)

1.4、实例

1.4.1、创建一个实体类Student和StudentPK:联合主键类序列化,重写equals和hashCode方法

StudentPK  实体类:

1 packagecom.shore.entity;2

3 importjava.io.Serializable;4

5 importjavax.persistence.Entity;6

7 /**

8 *@authorDSHORE/2019-9-169 *10 */

11

12 @Entity13 public class StudentPK implementsSerializable {14 private static final long serialVersionUID = -2060041603022800114L; //序列化15

16 //name+address作为联合主键

17 privateString name;18 privateString address;19

20 publicStudentPK() {21 super();22 }23 publicStudentPK(String name, String address) {24 super();25 this.name =name;26 this.address =address;27 }28

29 publicString getName() {30 returnname;31 }32 public voidsetName(String name) {33 this.name =name;34 }35

36 publicString getAddress() {37 returnaddress;38 }39 public voidsetAddress(String address) {40 this.address =address;41 }42

43 //联合主键类序列化,重写equals和hashCode方法

44 @Override45 public booleanequals(Object object) {46 //instanceof——判断左边对象是否为右边对象的实例

47 if (object instanceofStudentPK) {48 StudentPK pk =(StudentPK) object;49 if (this.name.equals(pk.getName())50 && this.address.equals(pk.getAddress())) {51 return true;52 }53 }54 return false;55 }56

57 @Override58 public inthashCode() {59 return this.name.hashCode();60 }61 }

Student 实体类:

1 packagecom.shore.entity;2

3 importjava.io.Serializable;4

5 importjavax.persistence.EmbeddedId;6 importjavax.persistence.Entity;7

8 importorg.hibernate.annotations.Type;9

10 /**

11 *@authorDSHORE/2019-9-1612 *13 */

14

15 @Entity16 public class Student implementsSerializable {17 //对应的Student对象类建议也要序列化,但是可以不重写equals和hashCode方法

18 private static final long serialVersionUID = -2924879320015689901L;19

20 private StudentPK keys;//联合主键 别名

21 privateBoolean sex;22 privateString hobby;23

24 publicStudent() {25 super();26 }27 publicStudent(StudentPK keys, Boolean sex, String hobby) {28 super();29 this.keys =keys;30 this.sex =sex;31 this.hobby =hobby;32 }33

34 @EmbeddedId //指定keys为联合主键

35 publicStudentPK getKeys() {36 returnkeys;37 }38 public voidsetKeys(StudentPK keys) {39 this.keys =keys;40 }41

42 @Type(type = "yes_no") //数据库中,会以Y/N的形式插入到sex字段中

43 publicBoolean getSex() {44 returnsex;45 }46 public voidsetSex(Boolean sex) {47 this.sex =sex;48 }49

50 publicString getHobby() {51 returnhobby;52 }53 public voidsetHobby(String hobby) {54 this.hobby =hobby;55 }56 }

1.4.2、创建hibernate.cfg.xml配置文件

1 <?xml version='1.0' encoding='utf-8'?>

2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"4 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

5

6

7

8

9 com.mysql.jdbc.Driver

10 jdbc:mysql://localhost:3306/school

11 root

12 123456

13

14 org.hibernate.dialect.MySQLDialect

15 org.hibernate.cache.NoCacheProvider

16 true

17 create

18

19

20

21

22

联合主键,MySQL数据库的写法:(本文不需要手动创建数据表,是自动创建的,下面的MySQL建表脚本,仅提供参考)

1 CREATE TABLEstudent(2 name VARCHAR(20),3 address VARCHAR(100),4 sex BOOLEAN,5 hobby VARCHAR(60),6 PRIMARY KEY(name,address) --联合主键

7 )

1.4.3、创建测试类CompositeKeyTest ,开始测试:

1 packagecom.shore.test;2

3 importorg.hibernate.Session;4 importorg.hibernate.SessionFactory;5 importorg.hibernate.Transaction;6 importorg.hibernate.cfg.AnnotationConfiguration;7 importorg.junit.AfterClass;8 importorg.junit.BeforeClass;9 importorg.junit.Test;10

11 importcom.shore.entity.Student;12 importcom.shore.entity.StudentPK;13

14 /**

15 *@authorDSHORE/2019-9-1616 *17 */

18 public classCompositeKeyTest {19 public static SessionFactory sessionFactory = null;20 public static Session session = null;21

22 @BeforeClass23 public static voidbuildSessionFactory() {24 //联合主键之Annotation实现,用的是AnnotationConfiguration方法

25 sessionFactory = newAnnotationConfiguration().configure().buildSessionFactory();26 }27

28 @AfterClass29 public static voidclose() {30 session.close();31 sessionFactory.close();32 }33

34 @Test35 public voidtest() {36 session = sessionFactory.openSession();//打开一个session

37 Transaction transaction = session.beginTransaction();//开启事务

38 Student student = new Student(new StudentPK("zhansan", "xxxxxx"), true, "yundong");39 session.save(student);40 transaction.commit();//提交事务

41 }42 }

1.4.4、测试结果图:

10ed9e9d8b4014b5774dbdd2168e09de.png

4aa169dce5f00c77308464f7af160588.png      

970edf3595c108c29cf3b0ce97e4d43e.png

2、Hibernate联合主键(XML实现)

代码和上面的全部一样,不一样的地方如下所示:

2.1、首先,注解得全部去掉。

2.2、多了一个配置文件:student.hbm.xml

1 <?xml version="1.0"?>

2 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

5

6

7

8

9

10

11

12

13

14

15

2.3、最后在hibernate.cfg.xml配置文件中引入“student.hbm.xml”文件即可

1 <?xml version='1.0' encoding='utf-8'?>2/p>

3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

4 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">5

6789com.mysql.jdbc.Driver10jdbc:mysql://localhost:3306/school11root1212345613

14org.hibernate.dialect.MySQLDialect15org.hibernate.cache.NoCacheProvider16true17create18

19202122

2.4、还有sessionFactory创建方式不一样:

1 packagecom.shore.test;2

3 importorg.hibernate.Session;4 importorg.hibernate.SessionFactory;5 importorg.hibernate.Transaction;6 importorg.hibernate.cfg.AnnotationConfiguration;7 importorg.junit.AfterClass;8 importorg.junit.BeforeClass;9 importorg.junit.Test;10

11 importcom.shore.entity.Student;12 importcom.shore.entity.StudentPK;13

14 /**

15 *@authorDSHORE/2019-9-1616 *17 */

18 public classCompositeKeyTest2 {19 public static SessionFactory sessionFactory = null;20 public static Session session = null;21

22 @BeforeClass23 public static voidbuildSessionFactory() {24 //联合主键之xml实现,用的是Configuration()方法

25 sessionFactory = new Configuration().configure().buildSessionFactory(); //之前用的是:AnnotationConfiguration()

26 }27

28 @AfterClass29 public static voidclose() {30 session.close();31 sessionFactory.close();32 }33

34 @Test35 public voidtest() {36 session = sessionFactory.openSession();//打开一个session

37 Transaction transaction = session.beginTransaction();//开启事务

38 Student student = new Student(new StudentPK("zhansan", "xxxxxx"), true, "yundong");39 session.save(student);40 transaction.commit();//提交事务

41 }42 }

5229115459115c77b84bc3affdf006b2.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值