• 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 package com.shore.entity;
     2 
     3 import java.io.Serializable;
     4 
     5 import javax.persistence.Entity;
     6 
     7 /**
     8  * @author DSHORE/2019-9-16
     9  * 
    10  */
    11 
    12 @Entity
    13 public class StudentPK implements Serializable {
    14     private static final long serialVersionUID = -2060041603022800114L; //序列化
    15     
    16     // name+address作为联合主键
    17     private String name;
    18     private String address;
    19     
    20     public StudentPK() {
    21         super();
    22     }
    23     public StudentPK(String name, String address) {
    24         super();
    25         this.name = name;
    26         this.address = address;
    27     }
    28 
    29     public String getName() {
    30         return name;
    31     }
    32     public void setName(String name) {
    33         this.name = name;
    34     }
    35 
    36     public String getAddress() {
    37         return address;
    38     }
    39     public void setAddress(String address) {
    40         this.address = address;
    41     }
    42     
    43     //联合主键类序列化,重写equals和hashCode方法
    44     @Override
    45     public boolean equals(Object object) {
    46         // instanceof——判断左边对象是否为右边对象的实例
    47         if (object instanceof StudentPK) {
    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     @Override
    58     public int hashCode() {
    59         return this.name.hashCode();
    60     }
    61 }

    Student 实体类:

     1 package com.shore.entity;
     2 
     3 import java.io.Serializable;
     4 
     5 import javax.persistence.EmbeddedId;
     6 import javax.persistence.Entity;
     7 
     8 import org.hibernate.annotations.Type;
     9 
    10 /**
    11  * @author DSHORE/2019-9-16
    12  *
    13  */
    14 
    15 @Entity
    16 public class Student implements Serializable {
    17     //对应的Student对象类建议也要序列化,但是可以不重写equals和hashCode方法
    18     private static final long serialVersionUID = -2924879320015689901L;
    19     
    20     private StudentPK keys;//联合主键 别名
    21     private Boolean sex;
    22     private String hobby;
    23     
    24     public Student() {
    25         super();
    26     }
    27     public Student(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     public StudentPK getKeys() {
    36         return keys;
    37     }
    38     public void setKeys(StudentPK keys) {
    39         this.keys = keys;
    40     }
    41     
    42     @Type(type = "yes_no")  //数据库中,会以Y/N的形式插入到sex字段中
    43     public Boolean getSex() {
    44         return sex;
    45     }
    46     public void setSex(Boolean sex) {
    47         this.sex = sex;
    48     }
    49     
    50     public String getHobby() {
    51         return hobby;
    52     }
    53     public void setHobby(String hobby) {
    54         this.hobby = hobby;
    55     }
    56 }

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

     1 <?xml version='1.0' encoding='utf-8'?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5 
     6 <hibernate-configuration>
     7     <session-factory>
     8         <!-- Database connection settings -->
     9         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    10         <property name="connection.url">jdbc:mysql://localhost:3306/school</property>
    11         <property name="connection.username">root</property>
    12         <property name="connection.password">123456</property>
    13 
    14         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    15         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    16         <property name="show_sql">true</property>
    17         <property name="hbm2ddl.auto">create</property>
    18 
    19         <!-- <mapping resource="com/shore/entity/Student.hbm.xml"/> -->
    20         <mapping class="com.shore.entity.Student" />
    21     </session-factory>
    22 </hibernate-configuration>

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

    1 CREATE TABLE student(
    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 package com.shore.test;
     2 
     3 import org.hibernate.Session;
     4 import org.hibernate.SessionFactory;
     5 import org.hibernate.Transaction;
     6 import org.hibernate.cfg.AnnotationConfiguration;
     7 import org.junit.AfterClass;
     8 import org.junit.BeforeClass;
     9 import org.junit.Test;
    10 
    11 import com.shore.entity.Student;
    12 import com.shore.entity.StudentPK;
    13 
    14 /**
    15  * @author DSHORE/2019-9-16
    16  *
    17  */
    18 public class CompositeKeyTest {
    19     public static SessionFactory sessionFactory = null;
    20     public static Session session = null;
    21     
    22     @BeforeClass
    23     public static void buildSessionFactory() {
    24                         //联合主键之Annotation实现,用的是AnnotationConfiguration方法
    25         sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
    26     }
    27     
    28     @AfterClass
    29     public static void close() {
    30         session.close();
    31         sessionFactory.close();
    32     }
    33     
    34     @Test
    35     public void test() {
    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、测试结果图:

           

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

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

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

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

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC
     3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     5         
     6 <hibernate-mapping package="com.shore.entity">
     7     <class name="Student">  
     8         <composite-id name="keys">
     9             <key-property name="name"/>
    10             <key-property name="address"/>
    11         </composite-id>
    12         <property name="sex" type="java.lang.Boolean"/>
    13         <property name="hobby" type="java.lang.String"/> 
    14     </class>
    15 </hibernate-mapping>

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

     1 <?xml version='1.0' encoding='utf-8'?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5 
     6 <hibernate-configuration>
     7     <session-factory>
     8         <!-- Database connection settings -->
     9         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    10         <property name="connection.url">jdbc:mysql://localhost:3306/school</property>
    11         <property name="connection.username">root</property>
    12         <property name="connection.password">123456</property>
    13 
    14         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    15         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    16         <property name="show_sql">true</property>
    17         <property name="hbm2ddl.auto">create</property>
    18 
    19         <mapping resource="com/shore/entity/Student.hbm.xml"/>
    20         <!-- <mapping class="com.shore.entity.Student" /> -->
    21     </session-factory>
    22 </hibernate-configuration>

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

     1 package com.shore.test;
     2 
     3 import org.hibernate.Session;
     4 import org.hibernate.SessionFactory;
     5 import org.hibernate.Transaction;
     6 import org.hibernate.cfg.AnnotationConfiguration;
     7 import org.junit.AfterClass;
     8 import org.junit.BeforeClass;
     9 import org.junit.Test;
    10 
    11 import com.shore.entity.Student;
    12 import com.shore.entity.StudentPK;
    13 
    14 /**
    15  * @author DSHORE/2019-9-16
    16  *
    17  */
    18 public class CompositeKeyTest2 {
    19     public static SessionFactory sessionFactory = null;
    20     public static Session session = null;
    21     
    22     @BeforeClass
    23     public static void buildSessionFactory() {
    24                         //联合主键之xml实现,用的是Configuration()方法
    25         sessionFactory = new Configuration().configure().buildSessionFactory(); //之前用的是:AnnotationConfiguration()
    26     }
    27     
    28     @AfterClass
    29     public static void close() {
    30         session.close();
    31         sessionFactory.close();
    32     }
    33     
    34     @Test
    35     public void test() {
    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 }

    原创作者:DSHORE

    作者主页:http://www.cnblogs.com/dshore123/

    原文出自:https://www.cnblogs.com/dshore123/p/11528059.html

    欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

  • 相关阅读:
    347. 前 K 个高频元素(桶排序、堆排序)
    322. 零钱兑换 && 416. 分割等和子集(0-1背包问题)
    739. 每日温度 && 503. 下一个更大元素 II (单调栈)
    1110. 删点成林
    个人纪录
    pub get failed (server unavailable) -- attempting retry 1 in 1 second?
    python 遍历文件夹重命名
    flutter vscode 连接iphone失败
    部署以太坊合约
    Web漏洞扫描工具AppScan10介绍
  • 原文地址:https://www.cnblogs.com/dshore123/p/11528059.html
Copyright © 2020-2023  润新知