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);不会发送查询语句

时间: 2024-12-30 03:33:13

hibernate之7.one2many双向的相关文章

8、one2many 双向

one2many双向 1.配置文件的写法 1.1 在1的一方的hbm.xml的配置 <!-- 使用了lazy=extra之后会稍微智能一些,会根据去的值的不同来判断是调用count和获取投影 --> <set name="stus" lazy="extra" inverse="true"> <key column="cid" /> <!-- key用来指定在对方的外键的名称 -->

Hibernate映射多对多双向关联关系(小案例)

多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 private Integer pid; //名称 private String pname; //定义集合类型的Emp属性 private Set<Emp> emps=new HashSet<Emp>(); public Integer getPid() { return pid; }

Hibernate 建立一对多双向关联关系

以下内容整理自<精通Hibernate>第二版 注:既然是双向关联,"一对多双向关联"和"多对一双向关联"是同一回事. 对象位于内存中,在内存中从一个对象导航到另一个对象显然比到数据库中查询数据的速度快多了.但是复杂的关联关联也会给编程带来麻烦,因此类与类之间是建立单向关联还是双向关联要由业务需求决定. 如果软件应用有大量这样的需求: 1.根据给定的客户,查询该客户的所有订单. 2.根据给定的订单,查询发出订单的客户. 根据以上需求,不妨为Custome

hibernate之 11.many2many双向

表结构: 类图: CRUD: User package com.demo.model; import java.util.Set; /**用户信息 * @author wobendiankun *2014-10-29 下午11:05:26 */ public class User { /** *用户Id */ private int userId; /** * 用户名 */ private String userName; /** * 密码 */ private String password;

[原创]java WEB学习笔记83:Hibernate学习之路---双向 1-n介绍,关键点解释,代码实现,set属性介绍(inverse,cascade ,order-by )

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

hibernate它 11.many2many双向

表结构: 类图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29iZW5kaWFua3Vu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > CRUD: User package com.demo.model; import java.util.Set; /**用户信息 * @author wobendiankun *2014-10-29 下

精通Hibernate——映射一对多双向自身关联关系

首先我们来看下图: 每种商品类别代表一个Category对象,每一个Category可以和父列表关联,同时也可以和子类别关联,为了表达这种一对多的双向自身关联关系可以在Category类中定义两个属性: parentCategory:引用父类别对象 childCategories:引用一组子类别对象 下面看看Category的源代码: public class Category implements Serializable{ private Lang id; private String na

Hibernate四 关联关系之双向关联

双向关联 一 双向1--N关联 1.无连接表的双向1--N关联 N的一端需要使用@ManyToOne注解来修饰代表关联实体的属性,1的一端需要使用@OneToMany注解来修饰代表关联实体的属性. 双向关联应该由N的一端来控制关联关系,因此在使用@OneToMany注解时指定mappedBy属性.一旦为@OneToMany,@ManyToMany指定了该属性,则表明当前实体不能控制关联关系,一旦当前实体放弃控制关联关系后,hibernate就不允许使用@JoinColumn或@JoinTable

hibernate 之 9.one2one双向

在培训系统中,我们经常会为每一个学员,分配一个所属登录帐号,对应的表结构设计如下: 图1:培训系统表结构 t_student: 学员信息表,存储学员的基本信息,如:姓名.年龄.身份证号.地址等等 t_user: 用户表,储系统用户信息,如:登录帐号.密码等 从图1中,知道 它通过student_id来关联 t_studnet 面向对象类关系 CRUD: 配置: User类 package com.demo.model; /**用户信息 * @author wobendiankun *2014-1