`

Hibernate中多对多的annotation的写法(中间表可以有多个字段)

阅读更多

一般情况下,多对多的关联关系是需要中间表的;

情况一:如果中间表仅仅是做关联用的,它里面仅有2个外键做联合主键,则使用ManyToMany(不用写中间表的Model,只需要写出两张主表的model即可)

学生表

@Entity
@Table(name = "T_STUDENT")
@SequenceGenerator(name = "SEQ_STUDENT", sequenceName = "SEQ_STUDENT")
public class Student implements Serializable {
private static final long serialVersionUID = 2524659555729848644L;
private Long id;
private String name;
private Date birthday;
private int sex;
private String address;
private Set<Teacher> teacherList;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STUDENT")
@Column(name = "ID", nullable = false, precision = 22, scale = 0)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Temporal(TemporalType.DATE)
@Column(name = "BIRTHDAY")
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Column(name = "sex")
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Column(name = "address")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "T_TEACHER_STUDENT",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "teacher_id"))
public Set<Teacher> getTeacherList() {
return teacherList;
}
public void setTeacherList(Set<Teacher> teacherList) {
this.teacherList = teacherList;
}
}

教师表

@Entity
@Table(name = "T_TEACHER")
@SequenceGenerator(name = "SEQ_TEACHER", sequenceName = "SEQ_TEACHER")
public class Teacher implements Serializable {
private static final long serialVersionUID = 2297316923535111793L;
private Long id;
private String name;
private int sex;
private Set<Student> studentList;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_TEACHER")
@Column(name = "ID", nullable = false, precision = 22, scale = 0)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "sex")
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@ManyToMany(mappedBy = "teacherList", cascade = CascadeType.ALL)
public Set<Student> getStudentList() {
return studentList;
}
public void setStudentList(Set<Student> studentList) {
this.studentList = studentList;
}
}

hibernate.cfg.xml配置2个class类

<mapping class="com.dvn.li.model.Student"/>
<mapping class="com.dvn.li.model.Teacher"/>

测试:

SessionFactory sessionFactory = null;
Session session = null;
try {
sessionFactory = HibernateUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
session.beginTransaction();
Student s = new Student();
s.setName("小猪");
Teacher t = new Teacher();
t.setName("小李");
Set<Teacher> t_set = new HashSet<Teacher>();
t_set.add(t);
s.setTeacherList(t_set);
session.save(s);

} catch (Exception e) {
if (session != null) {
session.getTransaction().rollback();
}
}

测试通过!!!

很简单吧!注意HibernateUtil.getSessionFactory()的实现如下:

public class HibernateUtil {
private static final SessionFactory sessionFactory;

static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

如果自己做测试,可以通过SchemaExport导入表结构

SchemaExport export = new SchemaExport(new AnnotationConfiguration()
.configure());
export.create(true, true);

 

情况二:如果中间表不仅仅是做关联用的,它里面包含了其他字段信息,仅仅靠多对多的关系是搞不定的。

解决方案:多对多的关系拆分为两个一对多!这时候三张表的Model都需要写。

我们知道,一对多的关系,一般都是在多的一方做配置。具体代码如下:

学生表

@Entity
@Table(name = "T_STUDENT")
@SequenceGenerator(name = "SEQ_STUDENT", sequenceName = "SEQ_STUDENT")
public class Student2 implements Serializable {
private static final long serialVersionUID = 2524659555729848644L;
private Long id;
private String name;
private Date birthday;
private int sex;
private String address;
private Set<TeacherStudent> teacherStudentList;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STUDENT")
@Column(name = "ID", nullable = false, precision = 22, scale = 0)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Temporal(TemporalType.DATE)
@Column(name = "BIRTHDAY")
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Column(name = "sex")
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Column(name = "address")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@OneToMany(mappedBy="student",cascade=CascadeType.ALL)
public Set<TeacherStudent> getTeacherStudentList() {
return teacherStudentList;
}
public void setTeacherStudentList(Set<TeacherStudent> teacherStudentList) {
this.teacherStudentList = teacherStudentList;
}
}

教师表

@Entity
@Table(name = "T_TEACHER")
@SequenceGenerator(name = "SEQ_TEACHER", sequenceName = "SEQ_TEACHER")
public class Teacher2 implements Serializable {
private static final long serialVersionUID = 2297316923535111793L;
private Long id;
private String name;
private int sex;
private Set<TeacherStudent> teacherStudentList;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_TEACHER")
@Column(name = "ID", nullable = false, precision = 22, scale = 0)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "sex")
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@OneToMany(mappedBy = "teacher",cascade=CascadeType.ALL)
public Set<TeacherStudent> getTeacherStudentList() {
return teacherStudentList;
}
public void setTeacherStudentList(Set<TeacherStudent> teacherStudentList) {
this.teacherStudentList = teacherStudentList;
}
}

中间表

@Entity
@Table(name = "T_TEACHERSTUDENT")
@SequenceGenerator(name = "SEQ_TEACHERSTUDENT", sequenceName = "SEQ_TEACHERSTUDENT")
public class TeacherStudent implements Serializable {
private Long id;
private Student2 student;
private Teacher2 teacher;
private String note1;
private String note2;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_TEACHERSTUDENT")
@Column(name = "ID", nullable = false, precision = 22, scale = 0)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "note1")
public String getNote1() {
return note1;
}
public void setNote1(String note1) {
this.note1 = note1;
}
@Column(name = "note2")
public String getNote2() {
return note2;
}
public void setNote2(String note2) {
this.note2 = note2;
}
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "student_id", unique = true)
public Student2 getStudent() {
return student;
}
public void setStudent(Student2 student) {
this.student = student;
}
@ManyToOne
@JoinColumn(name = "teacher_id", unique = true)
public Teacher2 getTeacher() {
return teacher;
}
public void setTeacher(Teacher2 teacher) {
this.teacher = teacher;
}
}

hibernate.cfg.xml 引入对象

 

<mapping class="com.dvn.li.model.Student2"/>
<mapping class="com.dvn.li.model.Teacher2"/>
<mapping class="com.dvn.li.model.TeacherStudent"/>

测试:

SessionFactory sessionFactory = null;
Session session = null;
try {
sessionFactory = HibernateUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
session.beginTransaction();
Student2 s = new Student2();
s.setName("小猪");
Teacher2 t = new Teacher2();
t.setName("小李");
TeacherStudent ts=new TeacherStudent();
ts.setStudent(s);
ts.setTeacher(t);
ts.setNote1("以呀呀!!!");
session.save(s);
session.save(t);
session.save(ts);
session.getTransaction().commit();
} catch (Exception e) {
if (session != null) {
session.getTransaction().rollback();
}
}

测试通过!

分享到:
评论

相关推荐

    Hibernate-HQL语句多对多写法

    "Hibernate-HQL语句多对多写法" Hibernate 是一个流行的 Java 持久层框架,它提供了强大的对象关系映射(ORM)功能,使得开发者可以方便地与数据库交互。但是,在使用 Hibernate 时,我们经常会遇到多对多关系的...

    hibernate配置文件以及类映射文件常用写法1

    `hibernate.hbm2ddl.auto`控制了数据库表的自动创建或更新,如设为`update`,会在启动时更新已有表结构。 类映射文件是将Java类与数据库表进行关联的关键。例如,`Cat.hbm.xml`映射文件会描述`Cat`类与数据库中某...

    Hibernate中,利用Criteria查询容器实现sql的写法

    同时,很多IDE如Eclipse和IntelliJ IDEA提供了对Hibernate的支持,可以自动生成Criteria查询,简化开发过程。 在进行团队协作时,文件管理也非常重要,"java集成svn"可能指的是项目中使用了Subversion(SVN)作为...

    Hibernate3教程

    - 用户可以根据需求选择数据库中的一个或多个表进行反向工程。 - **2.3.3 对被选中的表使用Hibernate反向(逆向)工程** - 反向工程是指从现有数据库表结构自动生成对应的Java POJO类及其Hibernate映射文件的过程...

    Java相关课程系列笔记之十四Hibernate学习笔记

    - 联合主键:支持多个字段作为主键。 - 聚集函数:HQL支持SUM、COUNT、AVG等聚合操作。 - 分页查询:通过设置firstResult和maxResults实现分页。 - 异构查询:支持不同类型的对象混合查询。 通过深入学习和实践,...

    HQL的几钟常见写法

    这种多表关联查询通常用于需要从多个实体获取信息的场景。 #### 5. 复杂的多表关联查询 **示例:** ```hql select p.id from Project p left join p.currentProjectDetail pd left join p.regionType left join pd....

    JDBC通用DAO CRUD(不是Hibernate)

    自己写的一个JDBC通用DAO ...因为没有用xml来映射表结构确定哪一个为该表的主键(因为一对多的情况下会有2个ID),所以id取名遵循 RUBY ON RAILS 的原则 "约定大于配置" 下一个版本会支持数据库表字段_写法:user_id

    Java相关课程系列笔记之十四Hibernate学习笔记.doc

    - 支持多对一、一对多、多对多等各种关联关系。 - 支持级联操作:可以一次处理整个对象树,避免了手动处理关联关系。 - 异步操作:可通过Future或Callback接口实现非阻塞式数据库操作。 - 支持CGLIB和JPA规范,兼容...

    ssh2(struts2+spring2.5+hibernate3.3)自动生成模版

    2.定制了自己的数据库规范, 该插件对数据库表进行了限制,如:数据库表名不能带有_(下划线),字段名也不能带有,这点我是最受不了的,不想多说了,从这点,我也就没有继续往下试了. rapid-framework 经过再三的筛选,...

    Hibbernate应用练习

    3. **多对一(ManyToOne)**: 多个实体对应数据库表中的唯一一条记录,一个实体对应多条记录。 4. **多对多(ManyToMany)**: 多个实体对应数据库表中的多条记录,另一个实体也是。 **五、性能优化** 1. **缓存...

    图书管理系统(最原始的serlvet写法)

    图书管理系统是IT领域中的一个典型应用,它涉及到数据库设计、用户交互以及数据操作等多个方面。在这个项目中,我们采用最原始的Servlet技术进行开发,结合JDBC来实现与数据库的连接。下面将详细阐述这个系统的主要...

    1000道互联网Java架构师面试题

    * ResultMap 可以将表中的字段名映射到实体类中的属性名。 * MyBatis 还支持多种映射形式,包括一对一、一对多、多对多等。 如何执行批量插入? 批量插入可以使用 MyBatis 的 foreach 标签: * 使用 foreach 标签...

    MyBatis的27道面试题

    在Mapper中传递多个参数时,可以使用@Param注解来标注参数,或者使用map进行封装。Mybatis动态SQL非常有用,可以通过多种动态SQL标签如if、choose、when、otherwise等来实现SQL条件逻辑,使SQL更加灵活。MyBatis的...

    基于java web学生管理系统数据库mysql基本没有css样式,很基础的写法

    6. **删除学生信息功能**:用户可以选中一个或多个学生进行删除,服务器接收到请求后,执行相应的删除操作,并返回操作结果。 7. **源代码**:源代码可能包含以下几个部分: - **Servlet**或**Controller**:处理...

    支持多数据库的ORM框架ef-orm.zip

    表结构元数据的API也向用户开放,同时支持在使用过程中,灵活调整映射关系,因此用户可以用API动态的创建表结构的模型,从而实现各种动态类型和表的映射(例如POJO中包含一个Map,用于映射各种动态扩展的字段)企业...

    Spring JPA学习

    - 使用`@ManyToMany`注解,并通常通过一个中间关联表来实现。 **2.8.4 继承映射** **2.8.4.1 单表继承策略** - 所有的实体类都映射到同一个表中,通过`@DiscriminatorColumn`区分不同实体。 **2.8.4.2 Joined策略...

    自己将项目的mongo 换成mysql 学习.zip

    - 可能需要将嵌套的文档拆分为多个关联表,或者将数组字段转化为多对一或一对多关系。 3. **数据迁移**: - 使用MongoDB的导出工具(如`mongoexport`)将数据导出为JSON或CSV格式,然后通过MySQL的导入工具(如`...

    java题库java题库java题库

    根据给出的文件信息,我们可以了解到Java互联网工程师面试题包含了多个技术栈的知识点,下面我会详细地介绍这些技术栈的面试题内容以及知识点。 首先是MyBatis相关的面试题,MyBatis是一个优秀的持久层框架,它支持...

Global site tag (gtag.js) - Google Analytics