11、haibernate映射map

来源:互联网 发布:领流量软件 编辑:程序博客网 时间:2024/06/05 22:44

haibernate映射map

对于对象属性中有Map类型的对象的映射,一个类如下含有Map类型:

1、map中为简单数据类型的:

import java.util.HashMap;import java.util.Map;public class Team{private String id;private String teamName;private Map students = new HashMap();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 Map getStudents(){return students;}public void setStudents(Map 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><map name="students" table="student"><key column="team_id"></key><index column="name" type="java.lang.String"></index><!-- 指定Map中的key值 --><element column="description" type="java.lang.String"></element><!-- 指定Map中的value值 --></map> </class></hibernate-mapping>
对于此例子,成员变量Map为简单数据类型的,在映射文件中增加一个map标签,name属性仍然是成员变量名,多了一个table属性,指出此Map所要对应的表,也就是在数据库中要有一张表来存储Map的信息。map标签中要有一个key子标签,来指明Map类型的成员变量属于哪一个team,就是要在map所对应的表中有一列来标明team的标识,所以有个column属性,这里设定为team_id,对于Map映射,必须还要有一个index子标签,指出Map的key值,这里是name,还要有一个element子标签指出Map的value值,这里是description。element子标签只能有一个。对应关系图:


运行产生表的程序,结果:

create table student (team_id varchar(255) not null, description varchar(255), name varchar(255) not null, primary key (team_id, name))
create table team (id varchar(255) not null, teamname varchar(255), primary key (id))

可以看到student表的主键是team_id和name的联合主键,因为光是一个team_id或name无法具体确定一个map中的值。

一个save的测试:

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 2");Map map = team.getStudents();map.put("lisi", "hello");map.put("zhangsan", "world");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, description) values (?, ?, ?)
Hibernate: insert into student (team_id, name, description) values (?, ?, ?)

2、对于map的值(value)为实体类型的

如果map的value为Student类型的,Student定义如下:

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

编写相应的映射文件: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"><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>

对于Student.hbm.xml,学生与team是多对一的关系,所以使用了many-to-one

创建表:

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))
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 2");Map map = team.getStudents();Student student1 = new Student();student1.setAge(20);student1.setName("zhang1111");student1.setTeam(team);Student student2 = new Student();student2.setAge(20);student2.setName("zhang222");student2.setTeam(team);Student student3 = new Student();student3.setAge(20);student3.setName("zhang333");student3.setTeam(team);session.save(team);map.put("111", student1);map.put("222", student2);map.put("333", student3);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 (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=?, card_id=? where id=?
Hibernate: update student set team_id=?, card_id=? where id=?
Hibernate: update student set team_id=?, card_id=? where id=?

这里要注意的是出现了三条update语句

通过程序,我们并没有设置student的cardId值,这个值是由Team来维护的,因为我们没在team中声明控制反转,所以Student在插入时没办法获得cardId值,由team在student插入后更新,就是update语句的由来。

修改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><map name="students" table="student" cascade="all" inverse="true"><key column="team_id"></key><index column="card_id" type="java.lang.String"></index><!-- 指定Map中的key值 --><one-to-many class="com.cdtax.hibernate.Student"/></map> </class></hibernate-mapping>

增加了inverse=true,执行结果

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 (?, ?, ?, ?, ?)

只有四条插入语句,没有了更新语句,但是我们到数据库中查看student表,发现结果:

402881c0423151660142315166d10002nullzhang22220402881c0423151660142315166c20001402881c0423151660142315166d10003nullzhang111120402881c0423151660142315166c20001402881c0423151660142315166d10004nullzhang33320402881c0423151660142315166c20001cardid列没有添加上去,为null值。

这时可以在程序中student中在进行set,就是:

Student student1 = new Student();student1.setAge(20);student1.setName("zhang1111");student1.setCardId("1111");student1.setTeam(team);

但是这样做以后,我们保存的就是使用student.setCardId()设进去的值了,而

map.put("111", student1);map.put("222", student2);map.put("333", student3);
这些语句的key就不起作用了,也就是说,如果我的student1.setCardId(‘“11111”),而我map.put(“aaaa”,student1),则保存的是1111,aaaa就没有用了,当然可以使用如下方法使其保持一致,就是:map.put(student1.getCardId(),student1);这样过于啰嗦,所以还是使用team维护关系,就是去掉inverse=true,虽然多了几条update语句。


原创粉丝点击