现在的位置: 首页 > 综合 > 正文

12、Hibernate映射set与List

2017年11月30日 ⁄ 综合 ⁄ 共 10692字 ⁄ 字号 评论关闭

1、对于set类型,如果集合中的元素是简单地类型,如字符串型,set使用另外一种映射方式:

team类:

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

public class Team
{
	private String id;
	
	private String teamName;
	
	private Set students = new HashSet();

	public String getId()
	{
		return id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getTeamName()
	{
		return teamName;
	}

	public void setTeamName(String teamName)
	{
		this.teamName = teamName;
	}

	public Set getStudents()
	{
		return students;
	}

	public void setStudents(Set students)
	{
		this.students = students;
	}
}

映射文件Team.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="com.cdtax.hibernate.Team" table="team">
		
		<id name="id" column="id" type="string">
			<generator class="uuid">
			</generator>
		</id>
			
		<property name="teamName" column="teamname" type="string"></property>
		
		<set name="students" table="student">
			<key column="team_id"></key>
			<element column="name" type="string"></element>
		</set>	 
	</class>
	
</hibernate-mapping>

使用set标签,一般要对应另外一张表,对于set元素是简单类型的,使用element子标签。

表的创建:

create table student (team_id varchar(255) not null, name varchar(255))
create table team (id varchar(255) not null, teamname varchar(255), primary key (id))
alter table student add index FK8FFE823BB04F9E7 (team_id), add constraint FK8FFE823BB04F9E7 foreign key (team_id) references team (id)

测试类:

import java.util.Map;

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

public class HibernateTest
{
	private static SessionFactory sessionFactory;
	
	static
	{
		try
		{
			sessionFactory = new Configuration().configure().buildSessionFactory();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public static void main(String[] args)
	{
				
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		
		try
		{
			tx = session.beginTransaction();
			
			Team team = new Team();
			team.setTeamName("team");
			
			team.getStudents().add("zhangsan");
			team.getStudents().add("lisi");
			team.getStudents().add("wangwu");
			
			session.save(team);
			
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
			{
				tx.rollback();
			}
			ex.printStackTrace();
		}
		finally
		{
			session.close();
		}
	}
}

运行结果:

Hibernate: insert into team (teamname, id) values (?, ?)
Hibernate: insert into student (team_id, name) values (?, ?)
Hibernate: insert into student (team_id, name) values (?, ?)
Hibernate: insert into student (team_id, name) values (?, ?)

map与set标签中的element子标签映射的是原子类型(String,date,int,long。。。),即能够直接映射到数据库表字段上的类型,而one-to-many映射的则是实体类型,指的是无法映射到表的某个字段,而是要映射到整张表的类型。

2、List的映射,list元素可以重复,而且是有顺序的。
举例:

import java.util.ArrayList;
import java.util.List;

public class Team
{
	private String id;
	
	private String teamName;
	
	private List students = new ArrayList();

	public String getId()
	{
		return id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getTeamName()
	{
		return teamName;
	}

	public void setTeamName(String teamName)
	{
		this.teamName = teamName;
	}

	public List getStudents()
	{
		return students;
	}

	public void setStudents(List students)
	{
		this.students = students;
	}
	
}

public class Student
{
	private String id;
	
	private String cardId;
	
	private String name;
	
	private int age;
	
	private Team team;

	public String getId()
	{
		return id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getCardId()
	{
		return cardId;
	}

	public void setCardId(String cardId)
	{
		this.cardId = cardId;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public int getAge()
	{
		return age;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public Team getTeam()
	{
		return team;
	}

	public void setTeam(Team team)
	{
		this.team = team;
	}
	
}

对应的映射文件:

<?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="com.cdtax.hibernate.Team" table="team">
		
		<id name="id" column="id" type="string">
			<generator class="uuid">
			</generator>
		</id>
			
		<property name="teamName" column="teamname" type="string"></property>
		
		<list name="students" table="student" cascade="all">
			<key column="team_id"></key>
			<index column="index_"></index>
			<one-to-many class="com.cdtax.hibernate.Student"/>
		</list>
	</class>
	
</hibernate-mapping>

对于Team,多了一个list标签,其中的子标签index来指出数据库表中的一列来维护list的顺序,因为list是有序的,而数据库中表是没有顺序的,只能用一个字段来维护。

<?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="com.cdtax.hibernate.Student" table="student">
		
		<id name="id" column="id" type="string">
			<generator class="uuid">
			</generator>
		</id>
		<property name="cardId" column="card_id" type="string"></property>
		<property name="name" column="name" type="string"></property>
		<property name="age" column="age" type="integer"></property>
		
		<many-to-one name="team" column="team_id" class="com.cdtax.hibernate.Team" cascade="none" fetch="join"></many-to-one>	 
	</class>
</hibernate-mapping>

产生表的语句:

create table student (id varchar(255) not null, card_id varchar(255), name varchar(255), age integer, team_id varchar(255),
index_ integer, primary key (id))
create table team (id varchar(255) not null, teamname varchar(255), primary key (id))

重点关注index_这一字段。

测试类:

import java.util.Map;

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

public class HibernateTest
{
	private static SessionFactory sessionFactory;
	
	static
	{
		try
		{
			sessionFactory = new Configuration().configure().buildSessionFactory();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public static void main(String[] args)
	{
				
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		
		try
		{
			tx = session.beginTransaction();
			
			Team team = new Team();
			team.setTeamName("team1");
			
			Team team2= new Team();
			team2.setTeamName("team2");
			
			Student s1 = new Student();
			Student s2 = new Student();
			Student s3 = new Student();
			Student s4 = new Student();
			Student s5 = new Student();
			Student s6 = new Student();
			
			s1.setName("zhangsan");
			s2.setName("lisi");
			s3.setName("wangwu");
			s4.setName("zhaoliu");
			s5.setName("5zhaoliu");
			s6.setName("6zhaoliu");
			
			team.getStudents().add(s1);
			team.getStudents().add(s2);
			
			team2.getStudents().add(s3);
			team2.getStudents().add(s4);
			team2.getStudents().add(s5);
			team2.getStudents().add(s6);
			
			session.save(team);
			session.save(team2);
			
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
			{
				tx.rollback();
			}
			ex.printStackTrace();
		}
		finally
		{
			session.close();
		}
	}
}

Hibernate: insert into team (teamname, id) values (?, ?)

Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into team (teamname, id) values (?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: update student set team_id=?, index_=? where id=?
Hibernate: update student set team_id=?, index_=? where id=?
Hibernate: update student set team_id=?, index_=? where id=?
Hibernate: update student set team_id=?, index_=? where id=?
Hibernate: update student set team_id=?, index_=? where id=?
Hibernate: update student set team_id=?, index_=? where id=?

插入表的结果:

id card_id name age team_id index_
402881c0423568450142356846c20002   zhangsan 0 402881c0423568450142356846b20001 0
402881c0423568450142356846c20003   lisi 0 402881c0423568450142356846b20001 1
402881c0423568450142356846c20005   wangwu 0 402881c0423568450142356846c20004 0
402881c0423568450142356846c20006   zhaoliu 0 402881c0423568450142356846c20004 1
402881c0423568450142356846c20007   5zhaoliu 0 402881c0423568450142356846c20004 2
402881c0423568450142356846c20008   6zhaoliu 0 402881c0423568450142356846c20004 3

如果我们将list的inverse设为true,执行结果

<list name="students" table="student" cascade="all" inverse="true">
			<key column="team_id"></key>
			<index column="index_"></index>
			<one-to-many class="com.cdtax.hibernate.Student"/>
		</list>

执行:

Hibernate: insert into team (teamname, id) values (?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into team (teamname, id) values (?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)
Hibernate: insert into student (card_id, name, age, team_id, id) values (?, ?, ?, ?, ?)

少了update语句,看看表的插入情况:

id card_id name age team_id index_
402881c042358df10142358df29e0002   zhangsan 0    
402881c042358df10142358df29e0003   lisi 0    
402881c042358df10142358df29e0005   wangwu 0    
402881c042358df10142358df29e0006   zhaoliu 0    
402881c042358df10142358df29e0007   5zhaoliu 0    
402881c042358df10142358df29e0008   6zhaoliu 0    

我们看到,team_id和index_没有插入数据。结果不正确。

3、集合的映射除了set,map,list,hibernate还提供了Bag(结合了List与Set),可以重复且没有顺序的一种集合

使用上面的例子,所有的bean代码不变,使用List来模拟Bag,只需要修改Team.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="com.cdtax.hibernate.Team" table="team">
		
		<id name="id" column="id" type="string">
			<generator class="uuid">
			</generator>
		</id>
			
		<property name="teamName" column="teamname" type="string"></property>
		
		<bag name="students" table="student" cascade="all" inverse="true">
			<key column="team_id"></key>
			<one-to-many class="com.cdtax.hibernate.Student"/>
		</bag>
	</class>
	
</hibernate-mapping>

创建表:
create table student (id varchar(255) not null, card_id varchar(255), name varchar(255), age integer, team_id varchar(255), primary key (id))
create table team (id varchar(255) not null, teamname varchar(255), primary key (id))

修改了set为bag,同时inverse设为true,这时如果不修改HibernateTest测试文件,在插入表时team_id字段将不能填充上,因为我们设置了bag的inverse为true,由多的一方即student来维护关联关系,而student是不知道team_id的,这时需要修改测试程序,如下:

import java.util.Map;

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

public class HibernateTest
{
	private static SessionFactory sessionFactory;
	
	static
	{
		try
		{
			sessionFactory = new Configuration().configure().buildSessionFactory();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public static void main(String[] args)
	{
				
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		
		try
		{
			tx = session.beginTransaction();
			
			Team team = new Team();
			team.setTeamName("team1");
			
			Team team2= new Team();
			team2.setTeamName("team2");
			
			Student s1 = new Student();
			Student s2 = new Student();
			Student s3 = new Student();
			Student s4 = new Student();
			Student s5 = new Student();
			Student s6 = new Student();
			
			s1.setName("zhangsan");
			s2.setName("lisi");
			s3.setName("wangwu");
			s4.setName("zhaoliu");
			s5.setName("5zhaoliu");
			s6.setName("6zhaoliu");
			
			s1.setTeam(team);
			s2.setTeam(team);
			
			s3.setTeam(team2);
			s4.setTeam(team2);
			s5.setTeam(team2);
			s6.setTeam(team2);
			
			team.getStudents().add(s1);
			team.getStudents().add(s2);
			
			team2.getStudents().add(s3);
			team2.getStudents().add(s4);
			team2.getStudents().add(s5);
			team2.getStudents().add(s6);
			
			session.save(team);
			session.save(team2);
			
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
			{
				tx.rollback();
			}
			ex.printStackTrace();
		}
		finally
		{
			session.close();
		}
	}
}

抱歉!评论已关闭.