这个有两种配置方式。一种是映射一个也是复合主键一部分的外键列,通过一般的<many-to-one>元素,并用insert="false" update="false"禁用该列的任何Hibernate插入或者更新。另一种方式是<key-many-to-one>。下面分别说明两种方式的配置方法。
1、many-to-one方式
假设有两个表USER和DEPARTMENT表。两个表的结构创建SQL语句如下:
create table DEPARTMENT ( DEPARTMENT_ID varchar(255) not null, DEPARTMENT_NAME varchar(255), DEPARTMENT_ADDRESS varchar(255), primary key (DEPARTMENT_ID) ); create table USER ( USERNAME varchar(255) not null, DEPARTMENT_ID varchar(255) not null, FIRSTNAME varchar(255), LASTNAME varchar(255), primary key (USERNAME, DEPARTMENT_ID) ); alter table USER add constraint FK27E3CBF9776336 foreign key (DEPARTMENT_ID) references DEPARTMENT;
根据表结构生成的Java类如下:
首先需要构建一个联合主键类UserId.java
package hello; import java.io.Serializable; /** * Created by orz on 16-2-28. */ public class UserId implements Serializable { private String username; private String departmentId; public UserId() { } public UserId(String username, String departmentId) { this.username = username; this.departmentId = departmentId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getDepartmentId() { return departmentId; } public void setDepartmentId(String departmentId) { this.departmentId = departmentId; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UserId userId = (UserId) o; if (username != null ? !username.equals(userId.username) : userId.username != null) return false; return departmentId != null ? departmentId.equals(userId.departmentId) : userId.departmentId == null; } @Override public int hashCode() { int result = username != null ? username.hashCode() : 0; result = 31 * result + (departmentId != null ? departmentId.hashCode() : 0); return result; } }
package hello; /** * Created by orz on 16-2-28. */ public class User { private UserId userId; private String firstName; private String lastName; private Department department; public UserId getUserId() { return userId; } public void setUserId(UserId userId) { this.userId = userId; } 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 Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
Department.java 如下:
package hello; /** * Created by orz on 16-2-28. */ public class Department { private String departmentId; private String departmentName; private String address; public String getDepartmentId() { return departmentId; } public void setDepartmentId(String departmentId) { this.departmentId = departmentId; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
Department.hbm.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hello.Department" table="DEPARTMENT"> <id name="departmentId" column="DEPARTMENT_ID"> <generator class="assigned" /> </id> <property name="departmentName" column = "DEPARTMENT_NAME" /> <property name="address" column = "DEPARTMENT_ADDRESS" /> </class> </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hello.User" table="USER"> <composite-id name="userId" class="hello.UserId"> <key-property name="username" column="USERNAME" /> <key-property name="departmentId" column="DEPARTMENT_ID" /> </composite-id> <property name="firstName" column = "FIRSTNAME" /> <property name="lastName" column = "LASTNAME" /> <many-to-one name="department" class="hello.Department" column="DEPARTMENT_ID" insert="false" update="false" /> </class> </hibernate-mapping>
package hello; import org.hibernate.Session; import org.hibernate.Transaction; import persistence.HibernateUtil; import java.util.Iterator; import java.util.List; /** * Created by orz on 16-2-21. */ public class HelloWorld { public static void main(String[] args) { Session departmentSession = HibernateUtil.getSessionFactory().openSession(); Transaction departmentTa = departmentSession.beginTransaction(); Department department = new Department(); department.setDepartmentId("1"); department.setDepartmentName("university"); department.setAddress("xi'an"); departmentSession.save(department); departmentTa.commit(); departmentSession.close(); Session userSession1 = HibernateUtil.getSessionFactory().openSession(); Transaction userTa1 = userSession1.beginTransaction(); UserId userId = new UserId("zxwei",department.getDepartmentId()); User user = new User(); user.setUserId(userId); user.setFirstName("zx"); user.setLastName("wei"); user.setDepartment(department); userSession1.saveOrUpdate(user); userTa1.commit(); userSession1.close(); Session userSession2 = HibernateUtil.getSessionFactory().openSession(); Transaction userTa2 = userSession2.beginTransaction(); List users = userSession2.createQuery("from User u").list(); System.out.println(users.size() + " user(s) found"); for (Iterator iter = users.iterator(); iter.hasNext();) { User iuser = (User) iter.next(); System.out.println("User: " + iuser.getUserId().getUsername() + ", " + iuser.getUserId().getDepartmentId() + ", " + iuser.getFirstName() + ", " + iuser.getLastName() +", department: " + iuser.getDepartment().getDepartmentName() + ", " + iuser.getDepartment().getAddress()); } userTa2.commit(); userSession2.close(); //Shutting down the application HibernateUtil.shutdown(); } }
2、key-many-to-one方式
大致的配置如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hello.User" table="USER"> <composite-id name="userId" class="hello.UserId"> <key-property name="username" column="USERNAME" /> <key-many-to-one name="department" class="hello.Department" column="DEPARTMENT_ID" /> </composite-id> <property name="firstName" column = "FIRSTNAME" /> <property name="lastName" column = "LASTNAME" /> </class> </hibernate-mapping>