hibernate之7.one2many双向
表结构
实体类关系
实体类源码
Student
package com.demo.model; import java.io.UnsupportedEncodingException; import java.util.Set; /**学生信息 * @author wobendiankun *2014-10-19 下午08:54:29 */ public class Student { private int studentId ; private String studentName ; private int age; private Set<Certificate> certificates ; public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { String str=""; if(studentName!=null){ try { str=new String(studentName.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return "Student [studentId=" + studentId + ", studentName=" + str + ", age=" + age + "]"; } public Set<Certificate> getCertificates() { return certificates; } public void setCertificates(Set<Certificate> certificates) { this.certificates = certificates; } }
Certificate
package com.demo.model; /**从业资格证书 * @author wobendiankun *2014-10-25 上午11:43:21 */ public class Certificate { /** * 证书id */ private int certificateId ; /** * 证书名称 */ private String certificateName; /** *证书编号 */ private String certificateNo ; private Student student ; public int getCertificateId() { return certificateId; } public void setCertificateId(int certificateId) { this.certificateId = certificateId; } public String getCertificateName() { return certificateName; } public void setCertificateName(String certificateName) { this.certificateName = certificateName; } public String getCertificateNo() { return certificateNo; } public void setCertificateNo(String certificateNo) { this.certificateNo = certificateNo; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } }
xml配置:
Student.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.demo.model.Student" table="t_student"> <id name="studentId" column="student_id"> <generator class="sequence"> <param name="sequence">SEQ_T_STUDENT</param> </generator> </id> <property name="studentName" column="student_name" /> <property name="age" /> <set name="certificates" lazy="extra"><!-- lazy="extra" --> <key column="student_id"></key> <one-to-many class="com.demo.model.Certificate"/> </set> </class> </hibernate-mapping>
Certificate.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.demo.model.Certificate" table="t_certificate"> <id name="certificateId" column="certificate_id"> <generator class="sequence"><param name="sequence">SEQ_T_CERTIFICATE</param></generator> </id> <property name="certificateName" column="certificate_name"/> <property name="certificateNo" column="certificate_no"/> <many-to-one name="student" column="student_id"></many-to-one> </class> </hibernate-mapping>
CRUD:
add:
@Test public void addTest(){ Set<Certificate> certificates=new HashSet<Certificate>(); Student student = new Student(); student.setStudentName("王五"); student.setAge(35); Certificate certificate1 = new Certificate(); certificate1.setCertificateName("aa"); certificate1.setCertificateNo("3a10001"); certificate1.setStudent(student); Certificate certificate2 = new Certificate(); certificate2.setCertificateName("bb"); certificate2.setCertificateNo("3a10002"); certificate2.setStudent(student); Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); // 先保存one,再保存many session.save(student); session.save(certificate1); session.save(certificate2); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(session); } }
发出的SQL:
Hibernate: insert into t_student (student_name, age, student_id) values (?, ?, ?) Hibernate: insert into t_certificate (certificate_name, certificate_no, student_id, certificate_id) values (?, ?, ?, ?) Hibernate: insert into t_certificate (certificate_name, certificate_no, student_id, certificate_id) values (?, ?, ?, ?)
update:
@Test public void updateStudentTest(){ Student student=new Student(); student.setStudentId(63); student.setStudentName("李九"); Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); session.update(student); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(session); } }
发出的SQL:
Hibernate: update t_student set student_name=?, age=? where student_id=? Hibernate: update t_certificate set student_id=null where student_id=?由于Student为one的一方,默认发维护关联字段,会多发送一条更新语句,解决方式为加入配置 inverse="true" (Student.hbm.xml的set元素中,添加属性),
inverse="true" 代表由:many的一方来维护关联字段
Student.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.demo.model.Student" table="t_student"> <id name="studentId" column="student_id"> <generator class="sequence"> <param name="sequence">SEQ_T_STUDENT</param> </generator> </id> <property name="studentName" column="student_name" /> <property name="age" /> <set name="certificates" lazy="extra" inverse="true"> <key column="student_id"></key> <one-to-many class="com.demo.model.Certificate"/> </set> </class> </hibernate-mapping>
updateInverse
@Test public void updateStudentWithInverseTest(){ Student student=new Student(); student.setStudentId(63); student.setStudentName("李九"); Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); session.update(student); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(session); } }
发出的SQL:
Hibernate: update t_student set student_name=?, age=? where student_id=?
维护关联字段的update语句不出现了
loadCertificate:
@Test public void loadCertificateTest(){ Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Certificate certificate=(Certificate)session.load(Certificate.class, 65); Certificate certificate2=(Certificate)session.load(Certificate.class, 66); System.out.println("编号:"+certificate.getCertificateNo()); System.out.println("姓名:"+certificate.getStudent().getStudentName()); System.out.println("---------------------------"); System.out.println("编号:"+certificate2.getCertificateNo()); System.out.println("姓名:"+certificate2.getStudent().getStudentName()); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(session); } }
发出的SQL:
Hibernate: select certificat0_.certificate_id as certific1_1_0_, certificat0_.certificate_name as certific2_1_0_, certificat0_.certificate_no as certific3_1_0_, certificat0_.student_id as student4_1_0_ from t_certificate certificat0_ where certificat0_.certificate_id=? 编号:3a10001 Hibernate: select student0_.student_id as student1_0_0_, student0_.student_name as student2_0_0_, student0_.age as age0_0_ from t_student student0_ where student0_.student_id=? 姓名:李九 --------------------------- Hibernate: select certificat0_.certificate_id as certific1_1_0_, certificat0_.certificate_name as certific2_1_0_, certificat0_.certificate_no as certific3_1_0_, certificat0_.student_id as student4_1_0_ from t_certificate certificat0_ where certificat0_.certificate_id=? 编号:3a10002 姓名:李九
共三条查询语句,查询id为66的记录时,由于id为63的Student对象已经变化在session中,所以不会再发出查询id为63的语句
loadStudent:
@Test public void loadStudentTest(){ Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Student student=(Student)session.load(Student.class, 63); System.out.println("姓名:"+student.getStudentName()); for(Certificate c:student.getCertificates()){ System.out.println("\t编号:"+c.getCertificateNo()); } System.out.println("-------------------"); Certificate c1=(Certificate)session.get(Certificate.class, 65); System.out.println("编号:"+c1.getCertificateNo()); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(session); } }
发出的SQL
Hibernate: select student0_.student_id as student1_0_0_, student0_.student_name as student2_0_0_, student0_.age as age0_0_ from t_student student0_ where student0_.student_id=? 姓名:李九 Hibernate: select certificat0_.student_id as student4_0_1_, certificat0_.certificate_id as certific1_1_, certificat0_.certificate_id as certific1_1_0_, certificat0_.certificate_name as certific2_1_0_, certificat0_.certificate_no as certific3_1_0_, certificat0_.student_id as student4_1_0_ from t_certificate certificat0_ where certificat0_.student_id=? 编号:3a10001 编号:3a10002 ------------------- 编号:3a10001
id为65的Certificate对象,已经存在session中,所以session.get(Certificate.class, 65);不会发送查询语句
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。