1.继续上一篇的问题,学些这几个花了不少时间,确实很有用对我们平常的项目,因为我们做的项目再设计实体类的时候,这2个实体之间经常会有关系,比如客户和订单之间就存在1对N的关系,老师跟学生之间就存在多对多的关系,那么我们如何在Hibernate中设计,设计成我们需要的东西呢,如下:
2.首先我看了下最简单的Set,Map,List,Array,Bag,等集合属性是如何映射到数据库表的,首先建立一个User实体类代码如下:(这里我们需要注意的set和map和list和array的区别,等下最下面给出详细的区别,然后这里我们可以直接在这里new出他们的实现类,也可以到后面的test类中自己new都行)
package com.icss.hibernate.set; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class User { private Integer id; private String name; private Set<String> addressSet;//无序,不重复 private List<String> addressList=new ArrayList<String>();//List是有序的,可以重复 private Map<String, String> addressMap=new HashMap<String, String>();//HashMap 无序,不重复(以key为准) public Map<String, String> getAddressMap() { return addressMap; } public void setAddressMap(Map<String, String> addressMap) { this.addressMap = addressMap; } public List<String> getAddressList() { return addressList; } public void setAddressList(List<String> addressList) { this.addressList = addressList; } 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; } public Set<String> getAddressSet() { return addressSet; } public void setAddressSet(Set<String> addressSet) { this.addressSet = addressSet; } }
3.下面就是写User对应的.hbm.xml文件盒Hibernate.cfg.xml文件了代码如下:
这个文件就是映射到数据库中对应的表的设计文件,当buildSessionFactory的时候Hibernate就会帮助我们自动生成我们设计的表,所以里面的细节我们一定要注意,前面的主键,属性,就不多说了,主要说下集合属性的映射:
addressSet属性,Set集合
table属性:集合表的名称
key子元素:集合外键的列名
element子元素:存放集合元素的列的信息
<!-- addressList属性,List集合
list-index:用于存放索引的列
-->
其实所有的集合配置都差不多。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.icss.hibernate.set"> <class name="User" table="USERS"> <id name="id" type="java.lang.Integer"> <column name="USER_ID" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="USER_NAME" /> </property> <set name="addressSet" table="user_addressSet"> <key column="userId" ></key> <element type="string" column="address"></element> </set> <!-- 映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 name: 多这一端关联的一那一端的属性的名字 class: 一那一端的属性对应的类名 column: 一那一端在多的一端对应的数据表中的外键的名字 --> <list name="addressList" table="user_addressList"> <key column="userId"></key> <list-index column="idx"></list-index> <element type="string" column="address"></element> </list> <map name="addressMap" table="user_addressMap"> <key column="userId"></key> <map-key type="string" column="key_"></map-key> <element type="string" column="address"></element> </map> </class> </hibernate-mapping>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory > <!-- 配置数据库信息 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.url">jdbc:mysql:///321</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="hibernate.connection.password">123</property> <!-- 其他配置 --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <!-- create:先删除,再创建 update:如果表不存在就创建,不一样就更新,一样就什么都不做。 create-drop:初始化时创建表,SessionFactory执行close()时删除表。 validate:验证表结构是否一致,如果不一致,就抛异常。 --> <property name="hbm2ddl.auto">update</property> <!-- 导入映射文件 --> <mapping resource="com/icss/hibernate/set/User.hbm.xml"/> </session-factory> </hibernate-configuration>
4.最后我们写一个测试文件测试一下:
package com.icss.hibernate.set; import static org.junit.Assert.*; import java.util.HashSet; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.After; import org.junit.Before; import org.junit.Test; public class HibernateTest { private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before public void init(){ Configuration configuration=new Configuration().configure(); sessionFactory =configuration.buildSessionFactory(); session=sessionFactory.openSession(); transaction=session.beginTransaction(); } @Test public void testSave() { User user=new User(); user.setName("张三"); Set<String> set=new HashSet<String>(); set.add("江苏省"); set.add("泰州市"); set.add("长沙市,天心区!!"); user.setAddressSet(set); user.getAddressList().add("云南省昆明市"); user.getAddressList().add("云南省丽江市"); user.getAddressList().add("云南省大理市"); user.getAddressMap().put("江西省", "南昌市"); user.getAddressMap().put("浙江省", "义乌市"); user.getAddressMap().put("山东省", "蓬莱市"); session.save(user); session.getTransaction().commit(); session.close(); } @Test public void getUser(){ session = sessionFactory.openSession(); session.beginTransaction(); User user=(User) session.get(User.class, 11); System.out.println(user.getName()); System.out.println(user.getAddressList()); System.out.println(user.getAddressMap()); session.getTransaction().commit(); session.close(); } }
OK,至此我们的集合映射属性就写完了,测试一下,就能得到相应的结果,一个User可以对应多个地址,在数据库的表也没问题。另外给出设计2个表关系的图说明:
以及Hibernate整体的结构示意图如下:
以及我们测试的结果示意图如下: