hibernate单向多对多

本文详细介绍了使用Hibernate实现学生与课程之间的单向多对多关联关系,包括实体类、数据库表设计、映射文件及示例代码,展示了如何通过设置cascade属性简化数据操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hibernate单向多对多关联。如:一个学生对应多门课程,一门课程也对应多名学生。本例单向关联,只考虑学生到课程的一对多关联。
1、概述
a.实体类
public class Student{
......
private Set<Course> courses;
......
}

public class Course{
......
}

b.数据库表
Student与Course各对应一张数据库表,再建一张关联表student_course (studentid,courseid),保存多对多关联。其中,student_course表的主键为studentid与courseid的联合。

c.配置文件
Student.hbm.xml:
......
<set name="courses" table="student_course" cascade="all">
<key column="studentid" />
<many-to-many column="courseid" class="wintys.hibernate.manytomany.Course"/>
</set>
......

Course.hbm.xml:
......

2、实体类:
Student.java:

package wintys.hibernate.manytomany;

import java.util.Set;

/**
* @version 2009-06-19
* @author Winty (wintys@gmail.com)
*
*/
public class Student {
private Integer id;
private String name;
private Set<Course> courses;

public Student(){
}

public Student(String name){
this.name = name;
}

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
}


Course.java:

package wintys.hibernate.manytomany;

import java.util.Set;

/**
* @version 2009-06-19
* @author Winty (wintys@gmail.com)
*
*/
public class Course {
private Integer id;
private String name;

public Course(){
}

public Course(String name){
this.name = name;
}

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


3、数据库表:
db.sql:


CREATE TABLE student(
id int(4) NOT NULL UNIQUE,
name varchar(100),
PRIMARY KEY(id)
);

CREATE TABLE course(
id int(4) NOT NULL UNIQUE,
name varchar(100),
PRIMARY KEY(id)
);

-- 关联表
CREATE TABLE student_course(
studentid int(4) NOT NULL,
courseid int(4) NOT NULL,
PRIMARY KEY(studentid,courseid),
CONSTRAINT FK_studentid FOREIGN KEY(studentid) REFERENCES student(id),
CONSTRAINT FK_courseid FOREIGN KEY(courseid) REFERENCES course(id)
);


4、映射文件:
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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
<class name="wintys.hibernate.manytomany.Student" table="student" catalog="db">
<id name="id" type="int">
<column name="id" not-null="true"/>
<generator class="increment" />
</id>
<property name="name" />

<set name="courses" table="student_course" cascade="all">
<key column="studentid" />
<many-to-many column="courseid" class="wintys.hibernate.manytomany.Course"/>
</set>
</class>
</hibernate-mapping>


Course.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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
<class name="wintys.hibernate.manytomany.Course" table="course" catalog="db">
<id name="id" type="int">
<column name="id" not-null="true"/>
<generator class="increment" />
</id>
<property name="name" />
</class>
</hibernate-mapping>


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">

<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

<session-factory>
<property name="connection.username">root</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf-8
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="myeclipse.connection.profile">MySQLDriver</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="show_sql">true</property>
<mapping resource="wintys/hibernate/manytomany/Student.hbm.xml" />
<mapping resource="wintys/hibernate/manytomany/Course.hbm.xml" />

</session-factory>

</hibernate-configuration>


4、使用测试:
DAO.java:

package wintys.hibernate.manytomany;

import java.util.List;

public interface DAO {
public void insert();
public <T> List<T> selectAll(String hql);
}


DAOBean.java:

package wintys.hibernate.manytomany;

import java.util.List;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
* @version 2009-06-19
* @author Winty (wintys@gmail.com)
*
*/
public class DAOBean implements DAO {

public void insert() {
Transaction tc = null;
try{
Course c1,c2,c3;
Student s1,s2;
Set<Course> cs1 , cs2;

c1 = new Course("Course 1");
c2 = new Course("Course 2");
c3 = new Course("Course 3");
s1 = new Student("Student 1");
s2 = new Student("Student 2");
cs1 = new HashSet<Course>();
cs2 = new HashSet<Course>();

//c2为两个集合共有
cs1.add(c1);
cs1.add(c2);
cs2.add(c2);
cs2.add(c3);

s1.setCourses(cs1);
s2.setCourses(cs2);

Session session = HibernateUtil.getSession();
tc = session.beginTransaction();

/*
在Student.hbm.xml中设置了cascade="all",就不需要手动保存c1/c2/c3
session.save(c1);
session.save(c2);
session.save(c3);
*/
session.save(s1);
session.save(s2);

tc.commit();
}catch(HibernateException e){
try{
if(tc != null)
tc.rollback();
}catch(Exception ex){
System.err.println(ex.getMessage());
}
System.err.println(e.getMessage());
}finally{
HibernateUtil.closeSession();
}
}

@SuppressWarnings("unchecked")
public <T> List<T> selectAll(String hql) {
List<T> items = null;
Transaction tc = null;
try{
Session session = HibernateUtil.getSession();
tc = session.beginTransaction();

Query query = session.createQuery(hql);
items = query.list();

tc.commit();
}catch(HibernateException e){
try{
if(tc != null){
tc.rollback();
items = null;
}
}catch(Exception ex){
System.err.println(ex.getMessage());
}
System.err.println(e.getMessage());
}finally{
//HibernateUtil.closeSession();
}

return items;
}
}


HibernateUtil.java:

package wintys.hibernate.manytomany;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
* Hibernate Session管理
* @author Winty
*/
public class HibernateUtil {
private static SessionFactory factory = null;
private static ThreadLocal<Session> threadLocal;

static {
try{
factory = new Configuration()
.configure()
.buildSessionFactory();
}catch(HibernateException e){
System.err.println(e.getMessage());
}

threadLocal = new ThreadLocal<Session>();
}

private HibernateUtil(){
}

public static Session getSession()throws HibernateException{
Session session = threadLocal.get();
if(session == null){
session = factory.openSession();
threadLocal.set(session);
}

return session;
}

public static void closeSession()throws HibernateException{
Session session = threadLocal.get();
if(session != null){
session.close();
}
threadLocal.set(null);
}
}


index.jsp:查询Student及其课程列表

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ page import="wintys.hibernate.manytomany.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>

<body>
<%
List<Student> students = null;
DAO dao = new DAOBean();
dao.insert();
students = dao.selectAll("from Student");

Iterator<Student> it = students.iterator();
while(it.hasNext()){
Student student = it.next();
int id = student.getId();
String name = student.getName();
out.println("id:" + id + "<br />");
out.println("name:" + name + "<br />");
out.println("courses:<br />");

Set<Course> cards = student.getCourses();
Iterator<Course> itc = cards.iterator();
while(itc.hasNext()){
Course course = itc.next();
int courseId = course.getId();
String courseName = course.getName();
out.println("    id:" + courseId + "<br />");
out.println("    name:" + courseName + "<br />");
}
out.println("<hr/>");
}
%>

</body>
</html>


5、运行结果
控制台显示:

......
Hibernate: insert into db.course (name, id) values (?, ?)
Hibernate: insert into db.course (name, id) values (?, ?)
Hibernate: insert into db.course (name, id) values (?, ?)
Hibernate: insert into db.student (name, id) values (?, ?)
Hibernate: insert into db.student (name, id) values (?, ?)
Hibernate: insert into student_course (studentid, courseid) values (?, ?)
Hibernate: insert into student_course (studentid, courseid) values (?, ?)
Hibernate: insert into student_course (studentid, courseid) values (?, ?)
Hibernate: insert into student_course (studentid, courseid) values (?, ?)
......


Web页面显示:
id:1
name:Student 1
courses:
id:1
name:Course 1
id:2
name:Course 2
--------------------------------------------------------------------------------
id:2
name:Student 2
courses:
id:3
name:Course 3
id:2
name:Course 2
--------------------------------------------------------------------------------

[参考资料]:
Hibernate 多对多单向关联-熔岩 : http://lavasoft.blog.51cto.com/62575/39324
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值