Hibernate之集合映射的使用(Set集合映射,list集合映射,Map集合映射)

a:数据库的相关知识:

  (1):一个表能否有多个主键:不能;

  (2):为什么要设置主键:数据库存储的数据都是有效的,必须保持唯一性;

  (3)为什么id作为主键:因为表中通常找不到合适的列作为唯一列,即主键,所有为了方便用id列,因为id是数据库系统维护可以保证唯一,所以就把这列作为主键,简单的说为了方便;如果找不到合适的列,除了使用id列以为作为主键,也可以使用联合主键,即多列的值作为一个主键,从而确保了记录的唯一性,即为联合主键;

Hibernate的映射很重要哦,如果是一般的映射,很容易掌握和使用,但是如果是集合映射呢,这里简单使用一下集合映射;

1:第一步,作为使用别人框架的中国人,我们只能先引入别人的包咯,千万别忘记了哦

2:第二步,就是配置hibernate.cfg.xml了,这里的配置之前已经说过了,分三大部分

  第一部分,数据库连接配置。

  第二部分,其他相关配置。

    这里使用了自动创建数据表, <property name="hibernate.hbm2ddl.auto">update</property>

    下面的源码详细介绍了几种方法的区别,如何找到hibernate.hbm2ddl.auto这句话呢,如下所示:

Hibernate之集合映射的使用(Set集合映射,list集合映射,Map集合映射)

  第三部分,加载映射文件。

 <!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节点代表一个数据库 -->
<session-factory>
<!-- 第一部分:数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property> <!-- 第二部分:其他相关配置 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!--
1:每次在创建sessionFactory时执行创建表,当调用sessionFactory的close方法的时候,删除表
#hibernate.hbm2ddl.auto create-drop 2:每次都重新建表,如果已经存在就先删除再创建
#hibernate.hbm2ddl.auto create 3:如果表不存在就创建,表存在就不创建
#hibernate.hbm2ddl.auto update 4:生成环境时候执行验证,当映射文件的内容与数据库表结构不一样的时候就报错
#hibernate.hbm2ddl.auto validate
--> <!-- 第三部分,加载映射文件 -->
<mapping resource="com/bie/po/User.hbm.xml"/> </session-factory>
</hibernate-configuration>

3:第三步,创建实体类,我依次使用了set,list,map集合来完成映射,这里一下全都写到了实体类里面了!!!

 package com.bie.po;

 import java.util.List;
import java.util.Map;
import java.util.Set; /**
* @author BieHongLi
* @version 创建时间:2017年3月15日 下午4:07:18
* 实体类
*/
public class User { private int id;
private String name;
//一个用户,对应多个地址
private Set<String> address; private List<String> addressList; private Map<String, String> addressMap; 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 int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getAddress() {
return address;
}
public void setAddress(Set<String> address) {
this.address = address;
} }

4:创建好实体类,就可以进行映射配置了,如实体类名.hbm.xml

   (1)set集合属性的映射:重点消化
           name指定要映射的set集合的属性
           table集合属性要映射的表
           key指定集合表(t_address)的外键字段
           element指定集合表的其他字段
           type元素类型,一定要指定

  (2)List集合属性的映射
                name指定要映射的list集合的属性
                table集合属性要映射的表
                key指定集合表(t_addressList)的外键字段
                element指定集合表的其他字段
                type元素类型,一定要指定
                list-index是list集合一定要指定的,指定排序列的名称,因为list是有序的

  (3) Map映射
                name指定要映射的map集合的属性
                table集合属性要映射的表
                key指定集合表(t_addressMap)的外键字段
                element指定集合map的其他字段value
                type元素类型,一定要指定
                map-key指定map的key

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="com.bie.po.User" table="t_test">
<!-- 主键映射 -->
<id name="id" column="id">
<generator class="native"></generator>
</id>
<!-- 非主键映射 -->
<property name="name" column="name"></property> <!--
set集合属性的映射:重点消化
name指定要映射的set集合的属性
table集合属性要映射的表
key指定集合表(t_address)的外键字段
element指定集合表的其他字段
type元素类型,一定要指定
-->
<set name="address" table="t_address">
<key column="uid"></key>
<element column="address" type="string"></element>
</set> <!--
List集合属性的映射
name指定要映射的list集合的属性
table集合属性要映射的表
key指定集合表(t_addressList)的外键字段
element指定集合表的其他字段
type元素类型,一定要指定
list-index是list集合一定要指定的,指定排序列的名称,因为list是有序的
-->
<list name="addressList" table="t_addressList">
<key column="uid"></key>
<list-index column="idx"></list-index>
<element column="address" type="string"></element>
</list> <!--
Map映射
name指定要映射的map集合的属性
table集合属性要映射的表
key指定集合表(t_addressMap)的外键字段
element指定集合map的其他字段value
type元素类型,一定要指定
map-key指定map的key
-->
<map name="addressMap" table="t_addressMap">
<key column="uid"></key>
<map-key type="string" column="shortName"></map-key>
<element type="string" column="address"></element>
</map> </class>
</hibernate-mapping>

5:映射配置好之后呢,就可以开始进行测试了,这里使用junit进行测试哦~~~

  这里需要注意的是最后一个测试获取数据的时候,

  只有当使用集合数据的时候,才向数据库发送执行sql的语句(又叫做懒加载)

  当查询用户,同时可以获取用户关联的list集合的数据,(因为存在正确映射)

 package com.bie.test;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test; import com.bie.po.User; /**
* @author BieHongLi
* @version 创建时间:2017年3月15日 下午4:31:23
*
*/
public class SetTest { //私有化session工厂
private static SessionFactory sf;
static{
//首先默认加载src/hibernate.cfg.xml文件
//其次创建session工厂文件
sf = new Configuration()
.configure()
//.addClass(User.class),测试的时候可以使用这个代替加载映射文件<mapping resource="com/bie/po/User.hbm.xml"/>
.buildSessionFactory();
} @Test
public void test(){
//创建session
Session session = sf.openSession();
//创建session开启事务
Transaction tx = session.beginTransaction(); //保存
Set<String> addressSet = new HashSet<>();
addressSet.add("北京");
addressSet.add("上海"); //用户对象
User user = new User();
user.setName("tom");
user.setAddress(addressSet); //保存到session中
session.save(user); tx.commit();
//session.getTransaction().commit();这样写就不用使用事务tx接受了,更加方便快捷
session.close();
} @Test
public void test2(){
//创建session
Session session = sf.openSession();
//开启事务
session.beginTransaction(); //List集合保存
List<String> list = new ArrayList<>();
list.add("深圳");
list.add("广州"); //User用户
User user = new User();
user.setName("张三");
user.setAddressList(list); //保存实体类
session.save(user); //提交事务
session.getTransaction().commit();
//关闭session
session.close();
} @Test
public void test3(){
Session session = sf.openSession();
session.beginTransaction(); Map<String, String> map = new HashMap<String,String>();
map.put("1001", "新乡");
map.put("1002", "郑州"); User user = new User();
user.setName("李四");
user.setAddressMap(map); session.save(user); session.getTransaction().commit();
session.close();
} @Test
public void getList(){
Session session = sf.openSession();
session.beginTransaction(); User user = (User)session.get(User.class, 2);
System.out.println(user.getId());
System.out.println(user.getName()); //当查询用户,同时可以获取用户关联的list集合的数据,(因为存在正确映射)
//当使用集合数据的时候,才向数据库发送执行sql的语句(又叫做懒加载)
System.out.println(user.getAddressList()); session.getTransaction().commit();
session.close();
} }

演示效果如下所示,需要注意的是,这里使用自动创建表的:

Hibernate之集合映射的使用(Set集合映射,list集合映射,Map集合映射)

如果生活也是这般,有简到难,该多好~~~

上一篇:解决windows10和ubuntu16.04双系统下时间不对的问题


下一篇:快速傅里叶变换FFT& 数论变换NTT