a:数据库的相关知识: (1):一个表能否有多个主键:不能; (2):为什么要设置主键:数据库存储的数据都是有效的,必须保持唯一性; (3)为什么id作为主键:因为表中通常找不到合适的列作为唯一列,即主键,所有为了方便用id列,因为id是数据库系统维护可以保证唯一,所以就把这列作为主键,简单的说为了方便;如果找不到合适的列,除了使用id列以为作为主键,也可以使用联合主键,即多列的值作为一个主键,从而确保了记录的唯一性,即为联合主键;
Hibernate的映射很重要哦,如果是一般的映射,很容易掌握和使用,但是如果是集合映射呢,这里简单使用一下集合映射;
1:第一步,作为使用别人框架的中国人,我们只能先引入别人的包咯,千万别忘记了哦
2:第二步,就是配置hibernate.cfg.xml了,这里的配置之前已经说过了,分三大部分
第一部分,数据库连接配置。
第二部分,其他相关配置。
这里使用了自动创建数据表, <property name="hibernate.hbm2ddl.auto">update</property>
下面的源码详细介绍了几种方法的区别,如何找到hibernate.hbm2ddl.auto这句话呢,如下所示:
第三部分,加载映射文件。
1 <!DOCTYPE hibernate-configuration PUBLIC
2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
3 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
4
5 <hibernate-configuration>
6 <!-- 一个session-factory节点代表一个数据库 -->
7 <session-factory>
8 <!-- 第一部分:数据库连接配置 -->
9 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
10 <property name="hibernate.connection.url">jdbc:mysql:///test</property>
11 <property name="hibernate.connection.username">root</property>
12 <property name="hibernate.connection.password">123456</property>
13
14 <!-- 第二部分:其他相关配置 -->
15 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
16 <property name="hibernate.show_sql">true</property>
17 <property name="hibernate.format_sql">true</property>
18 <property name="hibernate.hbm2ddl.auto">update</property>
19 <!--
20 1:每次在创建sessionFactory时执行创建表,当调用sessionFactory的close方法的时候,删除表
21 #hibernate.hbm2ddl.auto create-drop
22
23 2:每次都重新建表,如果已经存在就先删除再创建
24 #hibernate.hbm2ddl.auto create
25
26 3:如果表不存在就创建,表存在就不创建
27 #hibernate.hbm2ddl.auto update
28
29 4:生成环境时候执行验证,当映射文件的内容与数据库表结构不一样的时候就报错
30 #hibernate.hbm2ddl.auto validate
31 -->
32
33 <!-- 第三部分,加载映射文件 -->
34 <mapping resource="com/bie/po/User.hbm.xml"/>
35
36 </session-factory>
37 </hibernate-configuration>
38
39
40
3:第三步,创建实体类,我依次使用了set,list,map集合来完成映射,这里一下全都写到了实体类里面了!!!
1 package com.bie.po;
2
3 import java.util.List;
4 import java.util.Map;
5 import java.util.Set;
6
7 /**
8 * @author BieHongLi
9 * @version 创建时间:2017年3月15日 下午4:07:18
10 * 实体类
11 */
12 public class User {
13
14 private int id;
15 private String name;
16 //一个用户,对应多个地址
17 private Set<String> address;
18
19 private List<String> addressList;
20
21 private Map<String, String> addressMap;
22
23
24 public Map<String, String> getAddressMap() {
25 return addressMap;
26 }
27 public void setAddressMap(Map<String, String> addressMap) {
28 this.addressMap = addressMap;
29 }
30 public List<String> getAddressList() {
31 return addressList;
32 }
33 public void setAddressList(List<String> addressList) {
34 this.addressList = addressList;
35 }
36 public int getId() {
37 return id;
38 }
39 public void setId(int id) {
40 this.id = id;
41 }
42 public String getName() {
43 return name;
44 }
45 public void setName(String name) {
46 this.name = name;
47 }
48 public Set<String> getAddress() {
49 return address;
50 }
51 public void setAddress(Set<String> address) {
52 this.address = address;
53 }
54
55
56
57 }
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
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
5
6 <hibernate-mapping>
7 <class name="com.bie.po.User" table="t_test">
8 <!-- 主键映射 -->
9 <id name="id" column="id">
10 <generator class="native"></generator>
11 </id>
12 <!-- 非主键映射 -->
13 <property name="name" column="name"></property>
14
15 <!--
16 set集合属性的映射:重点消化
17 name指定要映射的set集合的属性
18 table集合属性要映射的表
19 key指定集合表(t_address)的外键字段
20 element指定集合表的其他字段
21 type元素类型,一定要指定
22 -->
23 <set name="address" table="t_address">
24 <key column="uid"></key>
25 <element column="address" type="string"></element>
26 </set>
27
28
29 <!--
30 List集合属性的映射
31 name指定要映射的list集合的属性
32 table集合属性要映射的表
33 key指定集合表(t_addressList)的外键字段
34 element指定集合表的其他字段
35 type元素类型,一定要指定
36 list-index是list集合一定要指定的,指定排序列的名称,因为list是有序的
37 -->
38 <list name="addressList" table="t_addressList">
39 <key column="uid"></key>
40 <list-index column="idx"></list-index>
41 <element column="address" type="string"></element>
42 </list>
43
44 <!--
45 Map映射
46 name指定要映射的map集合的属性
47 table集合属性要映射的表
48 key指定集合表(t_addressMap)的外键字段
49 element指定集合map的其他字段value
50 type元素类型,一定要指定
51 map-key指定map的key
52 -->
53 <map name="addressMap" table="t_addressMap">
54 <key column="uid"></key>
55 <map-key type="string" column="shortName"></map-key>
56 <element type="string" column="address"></element>
57 </map>
58
59
60 </class>
61 </hibernate-mapping>
5:映射配置好之后呢,就可以开始进行测试了,这里使用junit进行测试哦~~~
这里需要注意的是最后一个测试获取数据的时候,
只有当使用集合数据的时候,才向数据库发送执行sql的语句(又叫做懒加载)
当查询用户,同时可以获取用户关联的list集合的数据,(因为存在正确映射)
1 package com.bie.test;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 import org.hibernate.Session;
11 import org.hibernate.SessionFactory;
12 import org.hibernate.Transaction;
13 import org.hibernate.cfg.Configuration;
14 import org.junit.Test;
15
16 import com.bie.po.User;
17
18 /**
19 * @author BieHongLi
20 * @version 创建时间:2017年3月15日 下午4:31:23
21 *
22 */
23 public class SetTest {
24
25 //私有化session工厂
26 private static SessionFactory sf;
27 static{
28 //首先默认加载src/hibernate.cfg.xml文件
29 //其次创建session工厂文件
30 sf = new Configuration()
31 .configure()
32 //.addClass(User.class),测试的时候可以使用这个代替加载映射文件<mapping resource="com/bie/po/User.hbm.xml"/>
33 .buildSessionFactory();
34 }
35
36 @Test
37 public void test(){
38 //创建session
39 Session session = sf.openSession();
40 //创建session开启事务
41 Transaction tx = session.beginTransaction();
42
43 //保存
44 Set<String> addressSet = new HashSet<>();
45 addressSet.add("北京");
46 addressSet.add("上海");
47
48 //用户对象
49 User user = new User();
50 user.setName("tom");
51 user.setAddress(addressSet);
52
53 //保存到session中
54 session.save(user);
55
56 tx.commit();
57 //session.getTransaction().commit();这样写就不用使用事务tx接受了,更加方便快捷
58 session.close();
59 }
60
61 @Test
62 public void test2(){
63 //创建session
64 Session session = sf.openSession();
65 //开启事务
66 session.beginTransaction();
67
68 //List集合保存
69 List<String> list = new ArrayList<>();
70 list.add("深圳");
71 list.add("广州");
72
73 //User用户
74 User user = new User();
75 user.setName("张三");
76 user.setAddressList(list);
77
78 //保存实体类
79 session.save(user);
80
81 //提交事务
82 session.getTransaction().commit();
83 //关闭session
84 session.close();
85 }
86
87 @Test
88 public void test3(){
89 Session session = sf.openSession();
90 session.beginTransaction();
91
92 Map<String, String> map = new HashMap<String,String>();
93 map.put("1001", "新乡");
94 map.put("1002", "郑州");
95
96 User user = new User();
97 user.setName("李四");
98 user.setAddressMap(map);
99
100 session.save(user);
101
102 session.getTransaction().commit();
103 session.close();
104 }
105
106 @Test
107 public void getList(){
108 Session session = sf.openSession();
109 session.beginTransaction();
110
111 User user = (User)session.get(User.class, 2);
112 System.out.println(user.getId());
113 System.out.println(user.getName());
114
115 //当查询用户,同时可以获取用户关联的list集合的数据,(因为存在正确映射)
116 //当使用集合数据的时候,才向数据库发送执行sql的语句(又叫做懒加载)
117 System.out.println(user.getAddressList());
118
119 session.getTransaction().commit();
120 session.close();
121 }
122
123 }
演示效果如下所示,需要注意的是,这里使用自动创建表的:
如果生活也是这般,有简到难,该多好~~~