Hibernate映射联合主键
数据库建表语句为:
CREATE TABLE `T_PERSON` ( `firstname` VARCHAR(10) NOT NULL, `lastname` VARCHAR(10) NOT NULL, `address` VARCHAR(20), `phone` int(10) unsigned, PRIMARY KEY (`firstname`,`lastname`) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
方式一:基于实体类属性
对于实体的PO类,有2个要求:
1,必须继承Serializable接口
2,必须重写equals()方法和hashcode()方法(个人认为不是必须重写,只要其默认hascode能唯一的确定任何一个Person类即可,当然使用联合主键字段firstname和lastname重写equals()方法和hashcode()方法后,即可通过firstname和lastname唯一确定一个Person类,更符合数据库中firstname和lastname做为联合主键的设计)
public class Person implements Serializable{ private static final long serialVersionUID = 1L; private String firstname; private String lastname; private String address; private Integer phone; public Person(){} public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getPhone() { return phone; } public void setPhone(Integer phone) { this.phone = phone; } public int hashCode() { return getFirstname().hashCode()*11 + getLastname().hashCode(); } public boolean equals(Object obj) { if(null == obj){ return false; } if(this == obj){ return true; } if(obj.getClass() == Person.class){ Person p = (Person)obj; if(p.getFirstname().equals(getFirstname()) && p.getLastname().equals(getLastname())){ return true; } } return false; } }
PO类配置文件Person.hbm.xml:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping> <class name="com.po.Person" table="T_PERSON"> <composite-id> <key-property name="firstname" column="firstname" type="string"/> <key-property name="lastname" column="lastname" type="string"/> </composite-id> <property name="address" column="address" type="string"/> <property name="phone" column="phone" type="integer"/> </class> </hibernate-mapping>
Hibernate配置文件hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/mydb</property> <property name="connection.username">root</property> <property name="connection.password">196428</property> <property name="hibernate.jdbc.batch_size">50</property> <mapping resource="com/po/Person.hbm.xml" /> </session-factory> </hibernate-configuration>
测试类:
public class Test { public static void main(String[] args) { Configuration conf = new Configuration(); SessionFactory sessionFactory = conf.configure().buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tr = session.beginTransaction(); Person p1 = new Person(); p1.setFirstname("sean"); p1.setLastname("zou"); p1.setAddress("address"); p1.setPhone(123); session.save(p1); System.out.println("save successfully!"); Person p2 = new Person(); p2.setFirstname("sean"); p2.setLastname("zou"); p2 = (Person)session.get(Person.class,p2); p2.setFirstname("angel"); p2.setLastname("baby"); p2.setAddress("address2"); p2.setPhone(123); session.merge(p2); System.out.println("merge successfully!"); tr.commit(); session.close(); } }
运行结果为:
save successfully! merge successfully!
最终数据库里只有一条数据:
firstname |
lastname |
address |
phone |
angel |
baby |
address2 |
123 |
方式二:基于主键类
public class PersonPK implements Serializable{ private static final long serialVersionUID = 1L; private String firstname; private String lastname; public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public int hashCode() { return getFirstname().hashCode()*11 + getLastname().hashCode(); } public boolean equals(Object obj) { if(null == obj){ return false; } if(this == obj){ return true; } if(obj.getClass() == PersonPK.class){ PersonPK pk = (PersonPK)obj; if(pk.getFirstname().equals(getFirstname()) && pk.getLastname().equals(getLastname())){ return true; } } return false; } }
public class Person implements Serializable{ private static final long serialVersionUID = 1L; private PersonPK personPK; private String address; private Integer phone; public Person(){} public PersonPK getPersonPK() { return personPK; } public void setPersonPK(PersonPK personPK) { this.personPK = personPK; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getPhone() { return phone; } public void setPhone(Integer phone) { this.phone = phone; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping> <class name="com.po.Person" table="T_PERSON"> <composite-id name="personPK" class="com.po.PersonPK"> <key-property name="firstname" column="firstname" type="string"/> <key-property name="lastname" column="lastname" type="string"/> </composite-id> <property name="address" column="address" type="string"/> <property name="phone" column="phone" type="integer"/> </class> </hibernate-mapping>
public class Test { public static void main(String[] args) { Configuration conf = new Configuration(); SessionFactory sessionFactory = conf.configure().buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tr = session.beginTransaction(); PersonPK pk = new PersonPK(); pk.setFirstname("sean"); pk.setLastname("zou"); Person p1 = new Person(); p1.setPersonPK(pk); p1.setAddress("address"); p1.setPhone(123); session.save(p1); System.out.println("save successfully!"); Person p2 = (Person)session.get(Person.class,pk); p2.setAddress("address2"); p2.setPhone(123); session.merge(p2); System.out.println("merge successfully!"); tr.commit(); session.close(); } }
运行结果为:
save successfully! merge successfully!
最终数据库里只有一条数据:
firstname |
lastname |
address |
phone |
sean |
zou |
address2 |
123 |