单边的对多对指两个实体之间是多对多关系,但是只有一个实体中有另一个实体的集合。本例引用一本书山的demo(论坛文章和文章标签)实现单边的多对多关系。
demo实例:
文章和文章标签关系,一个文章可以有多个标签,每个标签下可以有多篇文章。标签实体类为tag,文章的实体类为post,其中post中有tag的一个集合用于存储该文章属于哪些标签,而标签中没有post的集合。他们的关系将被保存在一个中间表(tb_tag_post)中。
1、建立java工程
2、导入hibernate和MySql相关类库。
详见之前的博客hibernate单边一对多关系中的配置。
3、建立实体类
实体类tag为标签类,文件Tag.java代码和注解配置如下:
package com.arvinfei.hibernate.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "tb_tag")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String 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;
}
}
文章实体类Post,Post.java的代码和注解配置如下:
package com.arvinfei.hibernate.bean;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name = "tb_post")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST })
@JoinTable(name = "tb_tag_post", joinColumns = @JoinColumn(name = "post_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id"))
private Set<Tag> tags = new HashSet<Tag>();
private String title;
@Column(columnDefinition = "text")
private String content;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<Tag> getTags() {
return tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
主键id配置为自增长型;
content使用@Column(columnDefinition = "text")注解,表示该属性在数据库中使用text大文本类型。
@ManyToMany制定该列为多对多属性;
@fetch指定加载方式;
多对多属性必须使用@joinTable指定中间表的配置,其中name制定中间表的表名;joinColumns指定该表与中间表的对应关系,inverseJoinColumns指定另一端中、与中间表的对应关系。
4、在hibernate的配置文件中添加实体类映射关系
<?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="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/Many2Many?characterEncoding=UTF-8
</property>
<property name="connection.username">root</property>
<property name="connection.password">admin</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping class="com.arvinfei.hibernate.bean.Post" />
<mapping class="com.arvinfei.hibernate.bean.Tag" />
</session-factory>
</hibernate-configuration>
本例中使用的是Mysql数据库,本例子的数据库为Many2Many数据库。配置了两个实体类Post和Tag。
5、新建测试代码
新建Many2Manyjava文件用于测试。代码如下:
package com.arvinfei.hibernate.test;
import java.util.List;
import org.hibernate.Session;
import com.arvinfei.hibernate.bean.Post;
import com.arvinfei.hibernate.bean.Tag;
import com.arvinfei.hiernate.util.HibernateSessionFactory;
public class Many2Many {
@SuppressWarnings("all")
public static void main(String[] args) throws Exception {
Tag tag = new Tag();
tag.setName("幽默");
Tag tag2 = new Tag();
tag2.setName("浪漫");
Post post = new Post();
post.setTitle("推荐一个好玩的广告,很有浪漫气息哦");
post.setContent("见视频。自己看吧");
post.getTags().add(tag);
post.getTags().add(tag2);
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
// 保存进数据库
session.persist(post);
List<Post> list = session
.createQuery(
" select p from Post p left join fetch p.tags t "
+ " where t.name = :name ")
.setParameter("name", "幽默").list();
System.out.println("与标签“幽默”相关的帖子:");
for (Post p : list) {
// session.refresh(p);
System.out.println("标题:" + p.getTitle());
System.out.print("所属标签:");
for (Tag t : p.getTags()) {
System.out.print(t.getName() + ", ");
}
System.out.println();
}
session.refresh(tag);
session.getTransaction().commit();
session.close();
}
}
6、修改HibernateSessionFactory
修改HibernateSessionFactory中的sessionFactory配置方式,默认为xml配置方式,demo中使用注解进行配置,所以需要进行简单修改。
7、运行测试
(1)、打开并连接到mysql数据库;
(2)、在mysql中创建Many2Many数据库
create database Many2Many character set 'utf8';
(3)、运行本测试工程,查看log输出。