数据库中数据表之间可能会存在联系,有一对一关系,一对多关系,多对多关系。例如:数据库中有一张教室数据表,一张学生数据表,那么则是一对多关系,一个教室可以容纳多个学生,一个学生则只能在一个教室。以教室和学生为例实现一对多关系处理。
建立数据库,建立实体类,配置XML文件
数据库:
XML文件:
主配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 关于数据库的必要的配置 -->
<!-- 数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库url -->
<property name="hibernate.connection.url">jdbc:mysql:///WEB15</property>
<!-- 数据库用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库密码 -->
<property name="hibernate.connection.password">******</property>
<!-- 数据库方言 不同数据库方言不同 这里使用mysql数据库 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<!-- 是否在控制台打印sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- sql语句是否格式化 -->
<property name="hibernate.format_sql"></property>
<!-- 建表模式 一般天update -->
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>
<!-- 关联的子XML文件路径 -->
<mapping resource="domain/ClassRoom.hbm.xml"/>
<mapping resource="domain/Room.hbm.xml"/>
<mapping resource="domain/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://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="domain">
<class name="Room" table="Room">
<id name="rid" column="rid">
<generator class="native"></generator>
</id>
<property name="roomname" column="roomname"></property>
<set name="set">
<key column="c_to_sid"></key>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="domain">
<class name="Student" table="Student">
<id name="sid" column="sid">
<generator class="native"></generator>
</id>
<property name="studentname" column="studentname"></property>
<many-to-one name="room" column="c_to_sid" class="Room"></many-to-one>
</class>
</hibernate-mapping>
实体类:
public class Room {
private int rid;
private String roomname;
private Set<Student> set=new HashSet<Student>();
public Room() {
super();
// TODO Auto-generated constructor stub
}
public Room(int rid, String roomname) {
super();
this.rid = rid;
this.roomname = roomname;
}
public int getRid() {
return rid;
}
public void setRid(int rid) {
this.rid = rid;
}
public String getRoomname() {
return roomname;
}
public void setRoomname(String roomname) {
this.roomname = roomname;
}
public Set<Student> getSet() {
return set;
}
public void setSet(Set<Student> set) {
this.set = set;
}
@Override
public String toString() {
return "Room [rid=" + rid + ", roomname=" + roomname + ", set=" + set + "]";
}
}
public class Student {
private int sid;
private String studentname;
private Room room;
public Student() {
super();
}
public Student(int sid, String studentname) {
super();
this.sid = sid;
this.studentname = studentname;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
public Room getRoom() {
return room;
}
public void setRoom(Room room) {
this.room = room;
}
@Override
public String toString() {
return "Student [sid=" + sid + ", studentname=" + studentname + ", room=" + room + "]";
}
}
测试程序:
public void test1(){
Configuration configure = new Configuration().configure();
SessionFactory SessionFactory = configure.buildSessionFactory();
Session session = SessionFactory.getCurrentSession();
Transaction Transaction = session.beginTransaction();
Student s1=new Student();
s1.setStudentname("小王");
Student s2=new Student();
s2.setStudentname("小李");
Room room=new Room();
room.setRoomname("1班");
//建立联系
s1.setRoom(room);
s2.setRoom(room);
room.getSet().add(s1);
room.getSet().add(s2);
//执行保存操作
session.save(room);
session.save(s1);
session.save(s2);
Transaction.commit();
}
执行结果:
Hibernate: insert into Room (roomname) values (?)
Hibernate: insert into Student (studentname, c_to_sid) values (?, ?)
Hibernate: insert into Student (studentname, c_to_sid) values (?, ?)
Hibernate: update Student set c_to_sid=? where sid=?
Hibernate: update Student set c_to_sid=? where sid=?
在未配置子配置文件的参数cascade前,建立联系和保存操作student和room都要双向进行,缺一不可,否则程序会出现错误。
参数cascade参数级联实现了数据表关系上的单项关联
添加cascade参数
<set name="set" cascade="all">
<key column="c_to_sid"></key>
<one-to-many class="Student"/>
</set>
public void test2(){
Configuration configure = new Configuration().configure();
SessionFactory SessionFactory = configure.buildSessionFactory();
Session session = SessionFactory.getCurrentSession();
Transaction Transaction = session.beginTransaction();
Student s1=new Student();
s1.setStudentname("小马");
Student s2=new Student();
s2.setStudentname("小吴");
Room room=new Room();
room.setRoomname("2班");
//建立联系
room.getSet().add(s1);
room.getSet().add(s2);
//执行保存操作
session.save(room);
Transaction.commit();
}
这里只是进行了room对象的单向建立联系和保存,结果是room对象和student对象对加入了数据库,程序执行成功
public void test2(){
Configuration configure = new Configuration().configure();
SessionFactory SessionFactory = configure.buildSessionFactory();
Session session = SessionFactory.getCurrentSession();
Transaction Transaction = session.beginTransaction();
Student s1=new Student();
s1.setStudentname("小马");
Student s2=new Student();
s2.setStudentname("小吴");
Room room=new Room();
room.setRoomname("2班");
//建立联系
room.getSet().add(s1);
room.getSet().add(s2);
//执行保存操作
session.save(room);
Transaction.commit();
}
下面这个例子更好的反应了cascade参数的作用:
public void test3(){
Configuration configure = new Configuration().configure();
SessionFactory SessionFactory = configure.buildSessionFactory();
Session session = SessionFactory.getCurrentSession();
Transaction Transaction = session.beginTransaction();
Student s1=new Student();
s1.setStudentname("小马");
Student s2=new Student();
s2.setStudentname("小吴");
Student s3=new Student();
s1.setStudentname("小赵");
Student s4=new Student();
s2.setStudentname("小钱");
Room room=new Room();
room.setRoomname("3班");
//建立联系
room.getSet().add(s1);
room.getSet().add(s2);
s3.setRoom(room);
s4.setRoom(room);
//执行保存操作
session.save(s3);
session.save(s4);
Transaction.commit();
}
执行结果:
Hibernate: insert into Room (roomname) values (?)
Hibernate: insert into Student (studentname, c_to_sid) values (?, ?)
Hibernate: insert into Student (studentname, c_to_sid) values (?, ?)
Hibernate: insert into Student (studentname, c_to_sid) values (?, ?)
Hibernate: insert into Student (studentname, c_to_sid) values (?, ?)
Hibernate: update Student set c_to_sid=? where sid=?
Hibernate: update Student set c_to_sid=? where sid=?
四个student对象都加入数据库之中,这是因为s3,s4与room关联,而room又与s1,s2关联,所以在执行保存s3,s4操作时会将所有对象都放入数据库。
下面我们要是实现同学的转班
public void test4(){
Configuration configure = new Configuration().configure();
SessionFactory SessionFactory = configure.buildSessionFactory();
Session session = SessionFactory.getCurrentSession();
Transaction Transaction = session.beginTransaction();
Criteria Cr = session.createCriteria(Student.class);
Criteria add = Cr.add(Restrictions.eq("studentname", "小王"));
Student Result = (Student) add.uniqueResult();
Room room=session.get(Room.class, 5);
Result.setRoom(room);
Transaction.commit();
}
执行结果:
Hibernate: select this_.sid as sid1_2_0_, this_.studentname as studentn2_2_0_, this_.c_to_sid as c_to_sid3_2_0_ from Student this_ where this_.studentname=?
Hibernate: select room0_.rid as rid1_1_0_, room0_.roomname as roomname2_1_0_ from Room room0_ where room0_.rid=?
Hibernate: select set0_.c_to_sid as c_to_sid3_2_0_, set0_.sid as sid1_2_0_, set0_.sid as sid1_2_1_, set0_.studentname as studentn2_2_1_, set0_.c_to_sid as c_to_sid3_2_1_ from Student set0_ where set0_.c_to_sid=?
Hibernate: update Student set studentname=?, c_to_sid=? where sid=?
Hibernate: update Student set c_to_sid=? where sid=?