Hibernate 应用
来源:互联网 发布:怎样下载cad软件 编辑:程序博客网 时间:2024/06/04 19:02
Hibernate对象关系映射,基本工作原理是将对象数据保存到关系数据库的表中,以及将关系数据库中数据读入到对象中。
对象关系映射Object Relation Mapping, ORM,数据持久化
Hibernate 工作过程
搭建Hibernate实验环境 需要引入Hibernate下的核心包hibernate3.jar 、依赖包即 \lib 文件夹下的所有jar文件 、mysql驱动包 、Hibernate核心配置文件 hibernate.cfg.xml。
驱动包jar包,如下所示:
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
hibernate3.jar
javassist-3.4.GA.jar
jta-1.1.jar
slf4j-api-1.5.2.jar
log4j-1.2.15.jar
slf4j-log4j12-1.5.2.jar
mysql-connector-java-5.1.6-bin.jar
ddl.sql(自定义的mysql语句,在首先Hibernate执行之前,需要先用mysql命令行执行这一个文件)
hibernate.cfg.xml文件配置如下:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <!-- 数据库方言设置 --> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLInnoDBDialect </property> <!-- 数据库连接参数设置 --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.connection.url">jdbc:mysql:///hb_01</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!--实际操作数据库时是否显示SQL --> <!-- <property name="hibernate.show_sql">true</property> --> <property name="hibernate.format_sql">true</property> <!--将数据库schema的DDL导出到数据库 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 以下定义实体类与数据库表的映像文件 --> <mapping resource="com/qiujy/domain/Account.hbm.xml" /> </session-factory></hibernate-configuration>
之后,对一个真正的类Accout进行定义,定义如下:
/** * Filename: Account.java * Author: qiujy * Createtime: 2009-1-11 * Copyrights 2009 qiujy All rights reserved. * EMail: qjyong@gmail.com */package com.qiujy.domain;import java.util.Date;public class Account { private Long id; //对象标示符(OID) private String loginname; private String password; private String email; private Date registrationTime; public Account(){} //省略了getters和setters方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getLoginname() { return loginname; } public void setLoginname(String loginname) { this.loginname = loginname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getRegistrationTime() { return registrationTime; } public void setRegistrationTime(Date registrationTime) { this.registrationTime = registrationTime; }}
之后,映射持久化类到数据库表中。
Account.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对象关系映射文件的根元素 --><hibernate-mapping> <!-- class元素用来定义一个持久化类及对应的数据库表 --> <class name="com.qiujy.domain.Account" table="account"> <!-- id元素:指定每个持久化类的唯一标识(即对象标识符OID)到数据库表主键字段的映射 name属性:指定持久化类的OID名 column属性:指定数据库表主键字段名。此属性的名和映射到数据库表的字段名相同时,可省略 type属性:指定主键映射时所使用的Hibernate类型名。此属性的类型为基本数据类型和String类型时,可省略 --> <id name="id" column="id" type="long"> <!-- generator元素:指定对象标识符的生成器名。 native生成器把对象标识符值的生成工作交由底层数据库来完成 --> <generator class="native" /> </id> <!-- property元素:指定持久化类的每一个要映射到数据库表的字段的属性的信息。 name属性;指定持久化类中要映射到数据库表字段的属性名。 column属性:指定对应的表的字段名。此属性的名和映射到数据库表的字段名相同时,可省略 type属性:指定属性映射所使用的Hibernate类型名。此属性的类型为基本数据类型和String类型时,可省略 not-null属性:指定此属性映射到数据库表的字段值是否允许为值 --> <property name="loginname" column="loginname" type="string" not-null="true"/> <property name="password" column="password" type="string" not-null="true"/> <property name="email" column="email" type="string"/> <!-- 属性类型为Date类型的必须要明确指定使用的Hibernate类型名 --> <property name="registrationTime" column="registration_time" type="timestamp"/> </class></hibernate-mapping>
之后就用一个测试用例,利用Hibernate API进行持久化操作了!!!
/** * Filename: CreateAccountTest.java * Author: qiujy * Createtime: 2009-1-11 * Copyrights 2009 qiujy All rights reserved. * EMail: qjyong@gmail.com */import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import com.qiujy.domain.Account;/** * 新增账号的测试 * @author qiujy */public class CreateAccountTest { public static void main(String[] args) { //根据hibernate的默认配置文件构建一个SessoinFactory实例 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); //获取Session实例 Session session = sessionFactory.openSession(); //开启事务 session.beginTransaction(); //创建一个账号 Account acc = new Account(); acc.setLoginname("张三"); acc.setPassword("1234"); acc.setEmail("zs@test.com"); acc.setRegistrationTime(new Date()); //利用Session实例进行持久化操作 session.save(acc); //提交事务 session.getTransaction().commit(); //关闭Session session.close(); }}
下面是Hibernate 工作的过程
掌握持久化类的实例的状态及状态之间的转变,Session的使用与之有关
Hibernate 高级映射
01 集合映射
分别对set,list,bag 和map进行介绍
set
学生有很多爱好,hobbies ( type = “string” ), 可以在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.qiujy.domain.Student" table="student"> <id name="id" column="id" type="long"> <generator class="native" /> </id> <property name="name" not-null="true" /> <!-- set元素用来映射java.util.Set类型的属性 name属性:指定要映射的属性名 table属性:指定对应的数据库表名 --> <set name="hobbies" table="student_hobby"> <!-- key子元素:指定集合属性对应的表的外键列 --> <key column="student_id" /> <!-- element子元素:映射集合内的元素 --> <element type="string" column="hobby_name" not-null="true" /> </set> </class></hibernate-mapping>
同理,list
<?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.qiujy.domain.Student" table="student"> <id name="id" column="id" type="long"> <generator class="native" /> </id> <property name="name" not-null="true"/><!-- list元素用来映射java.util.List类型的属性 name属性:指定要映射的属性名 table属性:指定对应的数据库表名--><list name="hobbies" table="student_hobby"> <!-- key元素:指定集合属性对应的表的外键列 --> <key column="student_id" /> <!-- list-index元素:指定索引列 --> <list-index column="posistion"/> <!-- element元素:映射集合内的元素 --> <element type="string" column="hobby_name" not-null="true"/></list> </class></hibernate-mapping>
bag( 允许重复元素的无序集合,可以使用java.Util.Collection 或者java.util.List接口 来表示这种语义)
如student中有一个Collection<String> hobbies
字段。
对应的hbm.xml如下:
<bag name="hobbies" table="student_hobby"> <!-- key元素:指定集合属性对应的表的外键列 --> <key column="student_id" /> <!-- element元素:映射集合内的元素 --> <element type="string" column="hobby_name" not-null="true"/></bag>
映射map private Map<Long,String> hobbies; //个人爱好
<map name="hobbies" table="student_hobby"> <!-- key元素:指定集合属性对应的表的外键列 --> <key column="student_id" /> <!-- map-key元素:指定Map属性的键在对应表中的列 --> <map-key column="hobby_id" type="long"/> <!-- element元素:映射集合内的元素 --> <element type="string" column="hobby_name" not-null="true"/></map>
排序集合与有序集合太多东西,具体可以看代码。
02 组件映射
1 组件类座位持久化类的单个属性
举个例子,在设计一个购物系统时,客户Customer需要有联系地址,还需要有送货地址,可以Customer中,有homeAddress类和deliverAddress类。
同时,数据库那么在对应的数据库中只设计单一Customer表。
映射关系可以写成如下:
<?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.qiujy.domain.Customer" table="customer"> <id name="id" column="id" type="long"> <generator class="native" /> </id> <property name="loginname" not-null="true"/> <property name="password" not-null="true"/> <property name="email"/> <!-- 用component元素映射组件类属性homeAddress --> <component name="homeAddress" class="com.qiujy.domain.Address"> <!-- 用property映射组件类的每个属性 --> <property name="province" column="home_province"/> <property name="city" column="home_city"/> <property name="detail" column="home_detail"/> <property name="zipcode" column="home_zipcode"/> <property name="telephone" column="home_telephone"/> <property name="mobilephone" column="home_mobilephone"/> </component> <!-- 用component元素映射组件类属性deliverAddress --> <component name="deliverAddress" class="com.qiujy.domain.Address"> <property name="province" column="deliver_province"/> <property name="city" column="deliver_city"/> <property name="detail" column="deliver_detail"/> <property name="zipcode" column="deliver_zipcode"/> <property name="telephone" column="deliver_telephone"/> <property name="mobilephone" column="deliver_mobilephone"/> </component> </class></hibernate-mapping>
第二种,组件类作为持久化类的集合属性
例如,一个相册里有很多照片,Album, Photo,持久化类和组件类的区别是,前者有对象标示符,后者没有。
映射文件可以为:
<?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.qiujy.domain.Album" table="album"> <!-- 映射对象标识符 --> <id name="id" column="id" type="long"> <!-- 指定对象标识符生成器 --> <generator class="native" /> </id> <!-- 用property映射每个普通属性 --> <property name="title"/> <property name="description"/> <property name="creationTime" column="creation_time"/> <!-- 用bag来映射List集合属性 --> <bag name="photos" table="photo"> <!-- key元素:指定集合属性对应的表的外键列 --> <key column="album_id" not-null="true" /> <!-- composite-element元素:映射集合里的元素 class属性:指定集合里的元素的类类型 --> <composite-element class="com.qiujy.domain.Photo"> <!-- 用property映射每个普通属性 --> <property name="name" /> <property name="filePath" column="file_path" /> <property name="description" /> <property name="width" /> <property name="height" /> </composite-element> </bag> </class></hibernate-mapping>
详情见: hb_03_component.
3 组件类作为持久化对象的对象标识符属性
比如User这张表,把first_name和last_name 两个字段作为联合主键,要映射到持久化类的话,必须把这两个字段定义到一个组件类:UserOid,用来表示复合对象标识符。
同时,这个组件类,必须实现Serializable接口和重写hashcode()和equals()方法。
详情见: hb_03_componentOid.
03关联关系映射
1. 单向多对一
多对一:多个员工属于同一部门。Department类与Employee类
可以见hb_04_many2one_unidirectional.
2. 单向一对一
每一个中国公民,都有一张身份证,单向的意思是:只考虑从公民这一端找到它的身份证,而身份证这一端不知道公民的存在。
有两种方式。。。
一 基于唯一外键
公民把身份证的主键作为外键,并且这个外键是唯一的。
在citizen.hbm.xml中,配置如下:
<hibernate-mapping> <!-- 映射持久化类 --> <class name="com.qiujy.domain.Citizen" table="citizen"> <!-- 映射对象标识符 --> <id name="id" column="id" type="long"> <generator class="native" /> </id> <!-- 映射普通属性 --> <property name="name"/> <property name="gender"/> <!-- 用many-to-one元素映射基于唯一外键的一对一关联 name属性:指定关联的属性名 column属性:指定此关联属性在数据库表中的外键字段名 unique属性:指定值为“true”来限制多端的多重性为一 cascade属性:用来指定两个对象之间的操作联动关系 --> <many-to-one name="idCard" column="idcard_id" unique="true" cascade="all"/> </class></hibernate-mapping>
详情可见:hb_04_one2one_unidirectional_fk
二:基于主键
公民的id就是idcard的id,这种方式叫做基于主键的单向一对一。
citizen.hb.xml<hibernate-mapping> <!-- 映射持久化类 --> <class name="com.qiujy.domain.Citizen" table="citizen"> <!-- 映射对象标识符 --> <id name="id" column="id"> <!-- foreign表示使用另外一个相关联的对象(用property属性指定的那个属性)的标识符 --> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <!-- 映射普通属性 --> <property name="name"/> <property name="gender"/> <!-- 用one-to-one元素映射基于主键的一对一关联 name属性:指定关联的属性名 constrained属性:true表示该类对应的数据库表和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。 --> <one-to-one name="idCard" constrained="true"/> </class></hibernate-mapping>
详情可见:hb_04_one2one_unidirectional_pk
- 双向一对一
也有两种实现方式,基于唯一外键和基于主键的方式。
基于唯一外键的一对一双向关联,其外键可以存放在任意一端,在需要存放外键的一端,使用Many-to-one元素来映射关联对象,同时添加unique=true属性; 没有存放外键的那一端需要使用one-to-one元素,此时还需要通过property-ref属性来指定这一端只是关联另外一端的属性的反向引用,并不需要额外的列或者外键约束,由Hibernate管理这个关系。
例子:hb_04_one2one_bidirecrtional_fk.
基于主键的双向一对一
hb_04_one2one_bidirecrtional_pk.
- 单向一对多
一个账号可以有多个订单(set<Order>
),但是订单上没有写是哪个账号信息
hb_04_many2one_unidirecrtional
5.多向一对多(多向多对一)
一个账号可以有多个订单(set<Order>
),订单上有写是哪个账号信息account_id
hb_04_one2many_bidirecrtional
单向多对多
大学学生和课程之间的关联就是单向多对多关联。 课程不知道有哪些学生选了。
在关系模型中,是无法直接表达两个表之间的多对多关联的,需要有一个中间连接表。在连接表中用外键关联到两个表中。
hb_04_many2many_unidirecrtional双向多对多
大学学生和课程之间的关联就是单向多对多关联。 课程知道有哪些学生选了。
同样,需要一个中间表。
hb_04_many2many_bidirecrtional
04 继承关系映射
1:整体继承层次一张表
singer 父类有两个子类:SingleSinger, Bands. 全部放在一张表,需要一个鉴别字段,判断是SingleSinger还是Bands.
2:每个子类一个表
父类也有表,子类也有表,子类的字段都是独有的字段。
3:每一个具体类一个表。
上面父类的通用字段每一个表中都有。父类没有表。
hb_05_inheritancemapping_1
hb_05_inheritancemapping_2
hb_05_inheritancemapping_3
源代码地址如下:
01-03
http://download.csdn.net/detail/chengyangyy/9119523
04
http://download.csdn.net/detail/chengyangyy/9119537
05
http://download.csdn.net/detail/chengyangyy/9119545
- Hibernate 应用
- Hibernate?应用
- hibernate应用配置说明
- Hibernate的简单应用
- Hibernate 应用总结
- Spring+Hibernate应用
- Hibernate的简单应用
- hibernate 初级应用篇
- Hibernate经典应用
- Hibernate的Discriminator应用
- 搭建Hibernate应用
- 搭建Hibernate应用
- Hibernate+EhCache初级应用
- hibernate与应用缓存
- Hibernate应用总结
- Spring+Hibernate简单应用
- Hibernate的应用说明
- Spring + Hibernate简单应用
- Node.js中的DNS模块
- OpenCV 利用命令行(cmd)训练模型
- Windows下使用VS编译Lua
- Scala深入浅出实战经典:39,ListBuffer、ArrayBuffer、Queue、Stack操作代码实战
- 【c++ templates读书笔记】【1】函数模板
- Hibernate 应用
- Android SDK Manager
- Scala深入浅出实战经典:40,Set、Map、TreeSet、TreeMap操作代码实战
- arraylist add(int index) 方法时 index是处于前半部分还是后半部分效率高
- NYOJ -2括号配对问题
- Node.js中的Net模块
- https https和http区别,https证书分为哪几类?
- Android教程-01 Android Studio创建第一个项目
- Linux下线程同步的几种方法