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

Hibernate读书笔记之映射,集合映射,关联关系

2017年11月09日 ⁄ 综合 ⁄ 共 5017字 ⁄ 字号 评论关闭

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整体的结构示意图如下:

以及我们测试的结果示意图如下:

抱歉!评论已关闭.