hibernate 2 一对多、多对一 双向映射

多对一或一对多中,在多的一方维护关系效率高

一:java实体类

1、Classes.java

 package cn.gs.ly.school.entity;

 import java.util.Set;

 public class Classes {
private int cid;
private String cname;
private String cdescription;
private Set<Student> students;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getCdescription() {
return cdescription;
}
public void setCdescription(String cdescription) {
this.cdescription = cdescription;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
} }

2、Student.java

 package cn.gs.ly.school.entity;

 public class Student {
private int sid;
private String sname;
private String sdescription;
private Classes classes; public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSdescription() {
return sdescription;
}
public void setSdescription(String sdescription) {
this.sdescription = sdescription;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
} }

二:配置映射信息,建立表与类之间关系

1、Classes.hbm.xml

 <?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="cn.gs.ly.school.entity.Classes" >
<id name="cid" column="cid" type="java.lang.Integer">
<generator class="assigned"></generator>
</id>
<property name="cname" column="cname" type="java.lang.String"></property>
<property name="cdescription" column="cdescription" type="java.lang.String"></property> <!--
cascade="save-update" 级联操作
当保存班级的时候对学生进行什么操作
inverse="false" 是否维护关系
true不维护关系、false维护关系
-->
<set name="students" cascade="save-update" inverse="false"> <!-- 级联 -->
<!--
key 用来描述外键
set元素对用classes类中的set集合
通过key是 通过外键的形式将两张表建立联系
通过one-to-many让两个类建立关联
-->
<key>
<column name="cid"></column>
</key>
<one-to-many class="cn.gs.ly.school.entity.Student"/>
</set>
</class> </hibernate-mapping>

2、Student.hbm.xml

 <?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="cn.gs.ly.school.entity.Student" >
<id name="sid" column="sid" type="java.lang.Integer">
<generator class="assigned"></generator>
</id>
<property name="sname" column="sname" type="java.lang.String"></property>
<property name="sdescription" column="sdescription" type="java.lang.String"></property>
<!-- 多对一column 描述外键 -->
<many-to-one name="classes" class="cn.gs.ly.school.entity.Classes" column="cid" cascade="save-update"></many-to-one>
</class> </hibernate-mapping>

3、编写配置文件,连接数据库,引入映射信息文件

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只能链接一个数据库 -->
<session-factory>
<!--
进行数据库连接
driver:驱动
url:地址
username:数据库连接用户名
password:数据库连接密码
数据库方言
不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
sql99标准: DDL 定义语言 库表的增删改查
DCL 控制语言 事务 权限
DML 操纵语言 增删改查
注意: MYSQL在选择方言时,请选择最短的方言.
-->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost::orcl</property>
<property name="connection.username">liuyang</property>
<property name="connection.password">orcl</property>
<!--
自动建表
auto schema export 自动导出表结构. 自动建表
hibernate.hbm2ddl.auto create 自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
hibernate.hbm2ddl.auto validate 校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
-->
<!-- <property name="hbm2ddl.auto">update</property> -->
<property name="hbm2ddl.auto">update</property> <!-- 将hibernate生成的sql语句打印到控制台 -->
<property name="show_sql">true</property>
<!-- 添加映射文件 -->
<mapping resource="cn/gs/ly/entity/Person.hbm.xml"></mapping>
<mapping resource="cn/gs/ly/school/entity/Student.hbm.xml"></mapping>
<mapping resource="cn/gs/ly/school/entity/Classes.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>

三:测试类

oneToManyTest.java

 package cn.gs.ly.school.test;

 import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set; import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import cn.gs.ly.school.entity.Classes;
import cn.gs.ly.school.entity.Student;
import sun.util.calendar.CalendarSystem; /** Hibernate执行流程:
* Configuration:读取并解析配置文件(hibernate.cfg.xml)
* 一个Configuration实例代表hibernate所有的java类到SQL数据库映射的集合
* SessionFactory:读取并解析映射信息(***.hbm.xml)
* 将Configuration对象中的所有配置信息拷贝到SessionFactory的缓存中
* 打开Session,让SessionFactory提供连接。
* SessionFactory factory = con.buildSessionFactory();
* Transaction:开启事务。
* Transaction tr = se.beginTransaction();
* 数据库操作(get,delete,update,save)完成:提交事务、关闭Session
* tr.commit();
* se.close();
*
* Hibernate对象三种状态
* save():将对象由瞬时态转变为持久态
* liad()/get():获得的对象的状态处于持久态
* find():获得的List集合中的对象的状态处于持久态
* upload()/saveOrUpload()/lock():可将托管状态对象转变为持久态
* close():调用后,Session的缓存会被清空,缓存中所有持久态对象状态都转变为托管态
* 处于托管状态的对象称为游离对象,当游离对象不再被引用时,将被JVM垃圾回收机制清除
* evict():可将Session缓存中一个指定的持久态对象删除,使其转变为托管态对象
* 当缓存中保存了大量持久态对象时,为了节省内存空间,可以调用此方法删除一些持久态对象
*
* */ public class OneToManySingleTest {
SessionFactory factory =null;
Session se = null;
Transaction tr = null; //@Before:读取并解析配置文件、映射信息、打开Session、开启事务
@Before
public void test1(){
//读取配置文件 //1 创建,调用空参构造
Configuration con = new Configuration();
//2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件
con.configure();
//创建一个session工厂 //4 根据配置信息,创建 SessionFactory对象
factory = con.buildSessionFactory();
//5 获得session 打开一个新的session对象
se = factory.openSession();
//开启事务 //开启事务并获得操作事务的tr对象(建议使用)
tr = se.beginTransaction();
}
//@After:提交事务、关闭Session
@After
public void afterClose(){
//提交事务
tr.commit();
//关闭session
se.close();
} //1.新建一个班级
@Test
public void testCreateClasses(){
Classes classes = new Classes();
classes.setCid();
classes.setCname("gs01");
classes.setCdescription("一群大老爷们");
se.save(classes);
} //2.新建一个学生
@Test
public void testCreateStudent(){
Student student = new Student();
student.setSid();
student.setSname("张涛");
student.setSdescription("诸城一爷们");
se.save(student);
} //3.新建一个班级的同时新建一个学生
@Test
public void testCreateStudentClasses(){
Student student = new Student();
student.setSid();
student.setSname("刘超");
student.setSdescription("中华小题库"); Classes classes = new Classes();
classes.setCid();
classes.setCname("gs02");
classes.setCdescription("一群学霸"); Set<Student> stus = new HashSet<Student>();
stus.add(student);
classes.setStudents(stus);
se.save(classes);
} //4.已经存在一个班级,新建一个学生。建立联系:inverse(true不维护关系,false不维护关系)
@Test
public void testUpdateClass_Inverse_createStudent(){
Classes classes = (Classes)se.get(Classes.class, ); //id为1 的班级即gs01 Student student = new Student();
student.setSid();
student.setSname("萌萌");
student.setSdescription("一个光头的男人"); classes.getStudents().add(student);
//se.update(classes);
} //5.已经存在一个学生,新建一个班级
@Test
public void testCreateClassLinkStudent(){
Classes classes = new Classes();
classes.setCid();
classes.setCname("gs03");
classes.setCdescription("一个新的班级"); Student student = (Student)se.get(Student.class, ); Set<Student> stus = new HashSet<Student>();
stus.add(student);
classes.setStudents(stus);
se.save(classes);
} //6.把一个学生从一个班级转到另一个班级
@Test
public void testMoveStudent(){
Student student = (Student)se.get(Student.class, ); //获得要转班的学生
Classes classes = (Classes)se.get(Classes.class, ); //获得要转到的那个班级
//Classes classes1 = (Classes)se.get(Classes.class, 3);//原来的班级
//classes1.getStudents().remove(student); //把这个学生从原来班级删除
classes.getStudents().add(student); //把这个学生添加到要转去的那个新班级
} //7.解除一个班级和一个学生的关系
@Test
public void test7(){
Student student = (Student)se.get(Student.class, ); //获得要转班的那个学生
Classes classes = (Classes)se.get(Classes.class, ); //获得这个学生原来所在的班级
classes.getStudents().remove(student); //把这个学生从原来班级删除
} //8.解除一个班级和一些学生的关系
@Test
public void test8(){
Classes classes = (Classes)se.get(Classes.class, ); //解除关系的班级
Set<Student> students = classes.getStudents(); //此班级里所有学生,返回set集合
//set无下标,只查看集合不修改集合,所以用list集合进行修改 ,Set转List
List<Student> list = new ArrayList<Student>(students);
for (int i=;i<list.size();i++) {
if(list.get(i).getSid()==||list.get(i).getSid()==){ //id为4和6的学生
list.remove(i);//移除后,集合大小动态改变,集合大小-1
i--; //集合变小,i也需要变化
}
}
//List转Set集合,
students = new HashSet<Student>(list);
classes.setStudents(students);
} //9.解除一个班级和所有学生的关系
@Test
public void test9(){
Classes classes = (Classes)se.get(Classes.class, ); //获得一个班级
// Set<Student> students = classes.getStudents();
// students.clear();
classes.setStudents(null);
} //10.已经存在了一个班级,也存在一个学生 建立班级与学生的关系
@Test
public void test10(){
Classes classes = (Classes)se.get(Classes.class, ); // id 为1 的班级即gs01
Student student = (Student)se.get(Student.class, );
classes.getStudents().add(student);
} @Test //11.已经存在了一个班级,也存在许多学生 建立班级与学生的关系
public void test11(){ //未完成 =====================
// Classes classes = (Classes)se.get(Classes.class, 3);
// Set<Student> students = classes.getStudents();
// //set无下标,只查看集合不修改集合,所以用list集合 ,set转list
// List<Student> list = new ArrayList<Student>(students);
// for (int i=0;i<list.size();i++) {
// if(list.get(i).getSid()==4||list.get(i).getSid()==5||list.get(i).getSid()==6){
//
// }else{
// list.remove(i);
// }
// }
// //list转set集合
// students = new HashSet<Student>(list);
// classes.setStudents(students);
} //12.删除学生
@Test
public void test12(){
Student student = (Student)se.get(Student.class, );
se.delete(student);
} // 13.删除班级(需先解除关系)
// 1.在删除班级前,解除班级与学生之间的关系: inverse="false" 维护关系 删除班级解除关系
// 2.在删除班级的时候同时删除学生: 级联操作 cascade="all" 或 cascade="delete"
@Test
public void test13(){
Classes classes = (Classes)se.get(Classes.class, );
//classes.setStudents(null); //解除关系 inverse="true"时需此操作来解除关系
se.delete(classes);
} }

ManyToOneTest.java

 package cn.gs.ly.school.test;

 import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set; import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import cn.gs.ly.school.entity.Classes;
import cn.gs.ly.school.entity.Student;
import sun.util.calendar.CalendarSystem; public class ManyToOneSingleTest2 { SessionFactory factory =null;
Session se = null;
Transaction tr = null;
@Before
public void test1(){
//读取配置文件 //1 创建,调用空参构造
Configuration con = new Configuration();
//2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件
con.configure();
//创建一个session工厂 //4 根据配置信息,创建 SessionFactory对象
factory = con.buildSessionFactory();
//5 获得session 打开一个新的session对象
se = factory.openSession();
//开启事务 //开启事务并获得操作事务的tr对象(建议使用)
tr = se.beginTransaction();
}
@After
public void afterClose(){
//提交事务
tr.commit();
//关闭session
se.close();
} // 一对多双向
/**
* 多对一或一对多中,在多的一方维护关系效率高 student角度
*
* */ @Test //1.新建一个班级
public void testCreateClasses(){
Classes classes = new Classes();
classes.setCid();
classes.setCname("gs010");
classes.setCdescription("一群大老爷们");
se.save(classes);
} @Test //2.新建一个学生
public void testCreateStudent(){
Student student = new Student();
student.setSid();
student.setSname("张涛");
student.setSdescription("诸城一爷们");
se.save(student);
} @Test //3.新建一个班级的同时新建一个学生
public void testCreateStudentClasses(){
Student student = new Student();
student.setSid();
student.setSname("刘杨");
student.setSdescription("学霸"); Classes classes = new Classes();
classes.setCid();
classes.setCname("gs021");
classes.setCdescription("一群学霸"); student.setClasses(classes);
se.save(student); } @Test //4.已经存在一个班级,新建一个学生 建立联系 inverse(true不维护false维护)
public void testUpdateClass_Inverse_createStudent(){
Classes classes = (Classes)se.get(Classes.class, ); // id 为1 的班级即gs01
Student student = new Student();
student.setSid();
student.setSname("萌萌");
student.setSdescription("一个光头的男人"); student.setClasses(classes);
se.save(student);
} // @Test //5.已经存在一个学生,新建一个班级
// public void testCreateClassLinkStudent(){
// Classes classes = new Classes();
// classes.setCid(3);
// classes.setCname("gs03");
// classes.setCdescription("一个新的班级");
//
// Student student = (Student)se.get(Student.class, 1);
//
// Set<Student> stus = new HashSet<Student>();
// stus.add(student);
// classes.setStudents(stus);
// se.save(classes);
// }
//
// @Test //6.把一个学生从一个班级转到另一个班级
// public void testMoveStudent(){
// Student student = (Student)se.get(Student.class, 1); //获得要转班的那个学生
// Classes classes = (Classes)se.get(Classes.class, 2); //获得要转到的那个班级
// //Classes classes1 = (Classes)se.get(Classes.class, 3);//原来的班级
// //classes1.getStudents().remove(student); //把这个学生从原来班级删除
// classes.getStudents().add(student); //把这个学生添加到要转去的那个新班级
// }
//
// @Test //7.解除一个班级和一个学生的关系
// public void test7(){
// Student student = (Student)se.get(Student.class, 4); //获得要转班的那个学生
// Classes classes = (Classes)se.get(Classes.class, 3); //获得这个学生原来所在的班级
// classes.getStudents().remove(student); //把这个学生从原来班级删除
// } @Test //8.解除一个班级和一些学生的关系
public void test8(){
//Classes classes = (Classes)se.get(Classes.class, 21);
Student s1 = (Student)se.get(Student.class, );
Student s2 = (Student)se.get(Student.class, );
s1.setClasses(null);
s2.setClasses(null);
} @Test //9.解除一个班级和所有学生的关系
public void test9(){
Classes classes = (Classes)se.get(Classes.class, );
// Set<Student> students = classes.getStudents();
// students.clear();
classes.setStudents(null);
} @Test //10.已经存在了一个班级,也存在一个学生 建立班级与学生的关系
public void test10(){
Classes classes = (Classes)se.get(Classes.class, ); // id 为1 的班级即gs01
Student student = (Student)se.get(Student.class, );
classes.getStudents().add(student);
} @Test //11.已经存在了一个班级,也存在许多学生 建立班级与学生的关系
public void test11(){
Classes classes = (Classes)se.get(Classes.class, );
Set<Student> students = classes.getStudents();
//set无下标,只查看集合不修改集合,所以用list集合 ,set转list
List<Student> list = new ArrayList<Student>(students);
for (int i=;i<list.size();i++) {
if(list.get(i).getSid()==||list.get(i).getSid()==||list.get(i).getSid()==){ }else{
list.remove(i);
}
}
//list转set集合
students = new HashSet<Student>(list);
classes.setStudents(students);
} @Test //12.删除学生
public void test12(){
Student student = (Student)se.get(Student.class, );
se.delete(student);
} @Test // 13.删除班级 (解除关系)
// 1.在删除班级前,解除班级与学生之间的关系: inverse="false" 维护关系 删除班级解除关系
// 2.在删除班级的时候同时删除学生: cascade="all" 或 cascade="delete"
public void test13(){
Classes classes = (Classes)se.get(Classes.class, );
//classes.setStudents(null); //解除关系 inverse="true"时需此操作
se.delete(classes);
} }
上一篇:ajaxFileUpload - Post file and data together


下一篇:python使用tesseract-ocr完成验证码识别(模型训练和使用部分)