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 |
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();
}
}
}