在数据库中,表表之间是通过外键关联的,在程序中是要转化为持久化类也就是(JAVA Bean)来实例的。
但在Hibernater中持久化的之间的映射关系,不是通外键建立关联,而是通过属性.主要有以下几种
关联方向:
班级表,和学生表,学生生通过班级表中的,班级编号为外键
- --班级表
- create table grade
- (
- gid number primary key, --班级ID
- gname varchar2(50), --班级名称
- gdesc varchar2(50) --班级介绍
- );
- --学生表
- create table student
- (
- sid number primary key, --主键ID学生ID
- sname varchar2(20), --学生姓名
- sex varchar2(20), --学生性别
- gid number references grade(gid) ---外键班级ID
- );
班级和学生类
- package entity;
- import java.util.HashSet;
- import java.util.Set;
- /*
- * 班级类
- */
- public class Grade implements java.io.Serializable {
- // Fields
- private static final long serialVersionUID = 1L;
- private int gid;
- private String gname;
- private String gdesc;
- private Set<Student> students = new HashSet<Student> ();
- // Constructors
- /** default constructor */
- public Grade() {
- }
- /** minimal constructor */
- public Grade(int gid) {
- this.gid = gid;
- }
- /** full constructor */
- public Grade(int gid, String gname, String gdesc, Set<Student> students) {
- this.gid = gid;
- this.gname = gname;
- this.gdesc = gdesc;
- this.students = students;
- }
- // Property accessors
- public int getGid() {
- return this.gid;
- }
- public void setGid(int gid) {
- this.gid = gid;
- }
- public String getGname() {
- return this.gname;
- }
- public void setGname(String gname) {
- this.gname = gname;
- }
- public String getGdesc() {
- return this.gdesc;
- }
- public void setGdesc(String gdesc) {
- this.gdesc = gdesc;
- }
- public Set<Student> getStudents() {
- return this.students;
- }
- public void setStudents(Set<Student> students) {
- this.students = students;
- }
- }
学生类
- package entity;
- /*
- * 学生类
- */
- public class Student implements java.io.Serializable {
- // Fields
- private static final long serialVersionUID = 1L;
- private int sid;
- private String sname;
- private String sex;
- // Constructors
- /** default constructor */
- public Student() {
- }
- /** minimal constructor */
- public Student(int sid) {
- this.sid = sid;
- }
- /** full constructor */
- public Student(int sid, String sname, String sex ) {
- this.sid = sid;
- this.sname = sname;
- this.sex = sex;
- }
- // Property accessors
- public int getSid() {
- return this.sid;
- }
- public void setSid(int sid) {
- this.sid = sid;
- }
- public String getSname() {
- return this.sname;
- }
- public void setSname(String sname) {
- this.sname = sname;
- }
- public String getSex() {
- return this.sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- }
hibernate.cf.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.Oracle9Dialect
- </property>
- <property name="connection.url">
- jdbc:oracle:thin:@localhost:1521:orcl
- </property>
- <property name="connection.username">root</property>
- <property name="connection.password">root</property>
- <property name="connection.driver_class">
- oracle.jdbc.OracleDriver
- </property>
- <property name="show_sql">true</property>
- <property name="format_sql">true</property>
- <mapping resource="entity/Grade.hbm.xml" />
- <mapping resource="entity/Student.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
持久类配置先来学生类
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Student" table="STUDENT" schema="ROOT">
- <id name="sid" type="java.lang.Integer">
- <column name="SID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="sname" type="java.lang.String">
- <column name="SNAME" length="20" />
- </property>
- <property name="sex" type="java.lang.String">
- <column name="SEX" length="20" />
- </property>
- </class>
- </hibernate-mapping>
班级类配置
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Grade" table="GRADE" schema="ROOT">
- <id name="gid" type="java.lang.Integer">
- <column name="GID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="gname" type="java.lang.String">
- <column name="GNAME" length="50" />
- </property>
- <property name="gdesc" type="java.lang.String">
- <column name="GDESC" length="50" />
- </property>
- <!--建立set属性,也可以建立list和持久化类中一致就行 -->
- <set name="students">
- <key>
- <!--这里的列是指学生表中的班级编号 -->
- <column name="GID" precision="22" scale="0" />
- </key>
- <!-- 通过class属性指定set的属性 -->
- <one-to-many class="entity.Student" />
- </set>
- </class>
- </hibernate-mapping>
测试类
- package Test;
- import java.util.Set;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import entity.Grade;
- import entity.Student;
- public class Demo1 {
- /**
- * 测试类
- */
- public static void main(String[] args) {
- save();
- find();
- update();
- }
- public static void save() {
- // 声明班级对象,并赋值
- Grade grade = new Grade();
- grade.setGid(201504);
- grade.setGname("Java一班");
- grade.setGdesc("刚开始学习JAVA");
- // 声明2个学生对象
- Student stu1 = new Student();
- stu1.setSid(201504012);
- stu1.setSname("张三");
- stu1.setSex("男");
- Student stu2 = new Student();
- stu2.setSid(201504013);
- stu2.setSname("李四");
- stu2.setSex("女");
- // 将学生添加到班级
- grade.getStudents().add(stu1);
- grade.getStudents().add(stu2);
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- // 保存班级
- session.save(grade);
- // 保存学生
- session.save(stu1);
- session.save(stu2);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- /*
- * 将基中一个学生更改为别一个班级
- */
- public static void update() {
- // 声明班级对象,并赋值
- Grade grade = new Grade();
- grade.setGid(201506);
- grade.setGname("Java二班");
- grade.setGdesc("学习JAVA二年级");
- // 获取一个学生的信息
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- Student stu1=(Student) session.get(Student.class, 201504013);
- //将学生添加到这个新的班级
- grade.getStudents().add(stu1);
- // 保存班级
- session.save(grade);
- // 保存学生
- session.save(stu1);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- // 查询班级
- public static void find() {
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- Grade g = (Grade) session.get(Grade.class, 201504);
- System.out.println("班级信息:" + g.getGid() + "\t" + g.getGname()
- + g.getGdesc());
- // 通过班级获取这个班级的学生信息
- System.out.println("201504班的学生信息如下:");
- Set<Student> set = g.getStudents();
- for (Student stu : set) {
- System.out.println(stu.getSid() + "\t" + stu.getSname() + "\t"
- + stu.getSex());
- }
- }
- }
以上只上单向关联,一般都会有双向关联
同样要在学生类中添加Grade 属性
在学生类的配置文件中配置关联字段
- package entity;
- /*
- * 学生类
- */
- public class Student implements java.io.Serializable {
- // Fields
- private static final long serialVersionUID = 1L;
- private int sid;
- private String sname;
- private String sex;
- //增加班级属性
- private Grade grade;
- // Constructors
- /** default constructor */
- public Student() {
- }
- /** minimal constructor */
- public Student(int sid) {
- this.sid = sid;
- }
- /** full constructor */
- public Student(int sid, String sname, String sex ) {
- this.sid = sid;
- this.sname = sname;
- this.sex = sex;
- }
- // Property accessors
- public int getSid() {
- return this.sid;
- }
- public void setSid(int sid) {
- this.sid = sid;
- }
- public String getSname() {
- return this.sname;
- }
- public void setSname(String sname) {
- this.sname = sname;
- }
- public String getSex() {
- return this.sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- public Grade getGrade() {
- return grade;
- }
- public void setGrade(Grade grade) {
- this.grade = grade;
- }
- }
配置文件
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Student" table="STUDENT" schema="ROOT">
- <id name="sid" type="java.lang.Integer">
- <column name="SID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="sname" type="java.lang.String">
- <column name="SNAME" length="20" />
- </property>
- <property name="sex" type="java.lang.String">
- <column name="SEX" length="20" />
- </property>
- <!--配置grade属性 -->
- <many-to-one name="grade" class="entity.Grade">
- <!--指定学生表中的外键 -->
- <column name="GID" />
- </many-to-one>
- </class>
- </hibernate-mapping>
建立双向关联后,就可以通过学生来获取班级信息
清空数据表中的数据
- package Test;
- import org.hibernate.Session;
- import org.hibernate.cfg.Configuration;
- import entity.Student;
- public class Demo2 {
- /**
- * 测试类
- */
- public static void main(String[] args) {
- save();
- findByStu();
- }
- public static void findByStu(){
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- //获取一个学生的信息 get方法为通过主键查询
- Student stu=(Student) session.get(Student.class, 201504013);
- System.out.println("学生信息:\t"+stu.getSid()+"\t"+stu.getSname()+"\t"+stu.getSex());
- //通过学生信息得到班级信息
- System.out.println("这个学生的班级信息:"+stu.getGrade().getGid()+"\t"+stu.getGrade().getGname()+"\t"+stu.getGrade().getGdesc());
- }
- }
- public static void save() {
- // 声明班级对象,并赋值
- Grade grade = new Grade();
- grade.setGid(201504);
- grade.setGname("Java一班");
- grade.setGdesc("刚开始学习JAVA");
- // 声明2个学生对象
- Student stu1 = new Student();
- stu1.setSid(201504012);
- stu1.setSname("张三");
- stu1.setSex("男");
- stu1.setGrade(grade);
- Student stu2 = new Student();
- stu2.setSid(201504013);
- stu2.setSname("李四");
- stu2.setSex("女");
- stu2.setGrade(grade);
- // 将学生添加到班级
- /*grade.getStudents().add(stu1);
- grade.getStudents().add(stu2);*/
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- // 保存班级
- session.save(grade);
- // 保存学生
- session.save(stu1);
- session.save(stu2);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- 能不能只保存学生时,同时保存班级呢,或者保存班级时,同时保存学生呢
保存班级时,同时保存学生信息
修改班级配置,在set标签中添加cascade属性,设置为save-update
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Grade" table="GRADE" schema="ROOT">
- <id name="gid" type="java.lang.Integer">
- <column name="GID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="gname" type="java.lang.String">
- <column name="GNAME" length="50" />
- </property>
- <property name="gdesc" type="java.lang.String">
- <column name="GDESC" length="50" />
- </property>
- <!--建立set属性,也可以建立list和持久化类中一致就行 -->
- <set name="students" cascade="save-update">
- <key>
- <!--这里的列是指学生表中的班级编号 -->
- <column name="GID" precision="22" scale="0" />
- </key>
- <!-- 通过class属性指定set的属性 -->
- <one-to-many class="entity.Student" />
- </set>
- </class>
- </hibernate-mapping>
测试类
- package Test;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import entity.Grade;
- import entity.Student;
- public class Demo3 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- save();
- }
- public static void save() {
- // 声明班级对象,并赋值
- Grade grade = new Grade();
- grade.setGid(201504);
- grade.setGname("Java一班");
- grade.setGdesc("刚开始学习JAVA");
- // 声明2个学生对象
- Student stu1 = new Student();
- stu1.setSid(201504012);
- stu1.setSname("张三");
- stu1.setSex("男");
- stu1.setGrade(grade);
- Student stu2 = new Student();
- stu2.setSid(201504013);
- stu2.setSname("李四");
- stu2.setSex("女");
- stu2.setGrade(grade);
- // 将学生添加到班级
- grade.getStudents().add(stu1);
- grade.getStudents().add(stu2);
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- // 保存班级
- session.save(grade);
- // 保存学生
- //session.save(stu1);
- //session.save(stu2);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- }
反之,在学生类的配置文件one-many中添加cascade属性设置为save-update
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Student" table="STUDENT" schema="ROOT">
- <id name="sid" type="java.lang.Integer">
- <column name="SID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="sname" type="java.lang.String">
- <column name="SNAME" length="20" />
- </property>
- <property name="sex" type="java.lang.String">
- <column name="SEX" length="20" />
- </property>
- <!--配置grade属性 -->
- <many-to-one name="grade" class="entity.Grade" cascade="save-update">
- <!--指定学生表中的外键 -->
- <column name="GID" />
- </many-to-one>
- </class>
- </hibernate-mapping>
- package Test;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import entity.Grade;
- import entity.Student;
- public class Demo3 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- save();
- }
- public static void save() {
- // 声明班级对象,并赋值
- Grade grade = new Grade();
- grade.setGid(201504);
- grade.setGname("Java一班");
- grade.setGdesc("刚开始学习JAVA");
- // 声明2个学生对象
- Student stu1 = new Student();
- stu1.setSid(201504012);
- stu1.setSname("张三");
- stu1.setSex("男");
- stu1.setGrade(grade);
- Student stu2 = new Student();
- stu2.setSid(201504013);
- stu2.setSname("李四");
- stu2.setSex("女");
- stu2.setGrade(grade);
- // 将学生添加到班级
- grade.getStudents().add(stu1);
- grade.getStudents().add(stu2);
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- // 保存班级
- //session.save(grade);
- // 保存学生
- session.save(stu1);
- session.save(stu2);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- }
首先在班级类中设置invers属性为false时,删除班级
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Grade" table="GRADE" schema="ROOT">
- <id name="gid" type="java.lang.Integer">
- <column name="GID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="gname" type="java.lang.String">
- <column name="GNAME" length="50" />
- </property>
- <property name="gdesc" type="java.lang.String">
- <column name="GDESC" length="50" />
- </property>
- <!--建立set属性,也可以建立list和持久化类中一致就行 -->
- <set name="students" cascade="save-update" inverse="false">
- <key>
- <!--这里的列是指学生表中的班级编号 -->
- <column name="GID" precision="22" scale="0" />
- </key>
- <!-- 通过class属性指定set的属性 -->
- <one-to-many class="entity.Student" />
- </set>
- </class>
- </hibernate-mapping>
测试类
- package Test;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import entity.Grade;
- import entity.Student;
- public class Demo4 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- delete() ;
- }
- public static void delete() {
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- // 保存班级
- Grade grade=(Grade) session.get(Grade.class, 201504);
- // 保存学生
- session.delete(grade);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- }
结果:发现班级表中的班级已经删除,而学生表中数据没有删除,只是GID字段为NULL
下面将inverse设置为true时,添加新学生,和新的班级
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="entity.Grade" table="GRADE" schema="ROOT">
- <id name="gid" type="java.lang.Integer">
- <column name="GID" precision="22" scale="0" />
- <generator class="assigned" />
- </id>
- <property name="gname" type="java.lang.String">
- <column name="GNAME" length="50" />
- </property>
- <property name="gdesc" type="java.lang.String">
- <column name="GDESC" length="50" />
- </property>
- <!--建立set属性,也可以建立list和持久化类中一致就行 -->
- <set name="students" cascade="save-update" inverse="true">
- <key>
- <!--这里的列是指学生表中的班级编号 -->
- <column name="GID" precision="22" scale="0" />
- </key>
- <!-- 通过class属性指定set的属性 -->
- <one-to-many class="entity.Student" />
- </set>
- </class>
- </hibernate-mapping>
测试类
- package Test;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import entity.Grade;
- import entity.Student;
- public class Demo4 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- delete() ;
- }
- public static void delete() {
- // 声明班级对象,并赋值
- Grade grade = new Grade();
- grade.setGid(201509);
- grade.setGname("Java三班");
- grade.setGdesc("ASP.NET");
- // 声明2个学生对象
- Student stu1 = new Student();
- stu1.setSid(201509009);
- stu1.setSname("王五");
- stu1.setSex("女");
- stu1.setGrade(grade);
- Student stu2 = new Student();
- stu2.setSid(201509045);
- stu2.setSname("赵六");
- stu2.setSex("女");
- stu2.setGrade(grade);
- // 建立session
- Session session = new Configuration().configure().buildSessionFactory()
- .openSession();
- // 开始事务
- Transaction transaction = session.beginTransaction();
- // 保存学生
- session.save(stu1);
- session.save(stu2);
- // 提交事务
- transaction.commit();
- // 关闭session
- session.close();
- }
- }
结果发现,我并没有用班级添加学生,也没有保存班级,只是保存了学生,班级信息一起保存了