来源:wcily123的blog (特此赞一下^^很受益)
软件开发的分层思想:
三层架构:
|
数据表现层 |
业务逻辑层 |
数据持久层 |
SUN 的桌面应用 |
Swing AWT |
普通Java 类 |
JDBC |
SUN 的WEB 基本应用 |
JSP |
普通 Servlet |
JDBC |
SUN 的WEB 高级应用 |
JSF |
SessionBean |
Persistence |
WEB 国内流行开源 |
Struts |
Spring |
Hibernate |
一、 对象持久化的理论
1. 对象持久化:内存中的对象转存到外部持久设备上,在需要的时候还可以恢复。
2. 对象持久化的原因( 目标) :
物理:
1) 内存不能持久,需要在硬盘上持久保存 //( 物理上,物理的都不是根本原因)
2) 内存容量有限,需要在容量更大的硬盘上保存
应用:
3) 共享(Internet 的本质:信息的收集、整理、发布) // 最重要的原因
4) 检索( 大规模) // 也很重要
5) 管理( 备份、安全)
3. 怎样进行对象持久化?( 仅从JAVA 方面讲)
物理:
1) 对象序列化
2) DB 技术(JDBC 数据库)
4. 怎样利用数据库做对象持久化?
1) JDBC
优点:功能完备、理论上效率高
缺点:复杂( 难) 、代码量大、面向R( 过程;二维表关系)
2) EJB 仅讲Entity Bean
优点:封装JDBC
缺点:更复杂的API 、重量级( 侵入式) 、功能不完备、难共享
缺点的后果:开发周期长、测试困难、面向过程
以上是 2.0 之前的版本,但 3.0 跟Hibernate 基本一样
3) ORM 轻量级框架(Hibernate)
现阶段最佳的持久化工具:文档齐全、服务很好、工业标准、大量应用、易学
优点:封装JBDC 、简单的API 、轻量级( 只做持久化)( 用类库) 、PO( 持久对象)->POJO( 纯JAVA) 、开源
缺点:不够JDBC 灵活
5. 结论:
1) 对象持久化是必须的
2) 必须使用DB 来实现
3)Hibernate 必须的( 现阶段最佳选择)
开源工具的通常问题:1. 文档不全;2. 服务不全;3. 标准化不够
而Hibernate 避免了所有这些问题
二、 ORM 和Hibernate 的相关知识( 理解)
1) ORM:Object Relational Mapping
对象- 关系映射实现了面向对象世界中对象到关系数据库中的表的自动的( 和透明的) 持久化 , 使用元数据(meta data) 描述对象与数据库间的映射。
2) Hibernate 是非常优秀、成熟的O/R Mapping 框架。它提供了强大的对象和关系数据库映射以及查询功能。
规范:
1. 一个映射文件对应一个持久类( 一一对应)
2. 映射文件的名字和它所描述的持久类的名字保持一致
3. 映射文件应该与它所描述的类在同一包中
po -> (pojo)
-> oid( 唯一,中性)
-> getters/setters
-> 构造方法
三、Hibernate 核心API( 理解)
Configuration 类:
Configuration 对象用于配置和启动Hibernate 。Hibernate 应用通过Configuration 实例来指定对象- 关系 映射文件的位置或者动态配置Hibernate 的属性,然后创建SessionFactory 实例。
SessionFactory 接口:
一个SessionFactory 实例对应一个数据存储源。应用从SessionFactory 中获取Session 实例。
1) 它是线程安全的,这意味着它的一个实例能够被应用的多个线程共享。
2) 它是重量级的,这意味着不能随意创建或者销毁,一个数据库只对应一个SessionFactory 。
通常构建SessionFactory 是在某对象Bean 的静态初始化代码块中进行。
如果应用只是访问一个数据库,只需创建一个SessionFactory 实例,并且在应用初始化的时候创建该实例。
如果应用有同时访问多个数据库,则需为每个数据库创建一个单独的SessionFactory 。
Session 接口:
是Hibernate 应用最广泛的接口。它提供了和持久化相关的操作,如添加,删除,更改,加载和查询对象。
1) 它是线程不安全的,因此在设计软件架构时,应尽量避免多个线程共享一个Session 实例。
2)Session 实例是轻量级的,这意味着在程序可以经常创建和销毁Session 对象,
例如为每个客户请求分配单独的Session 实例。
原则:一个线程一个Session ;一个事务一个Session 。
Transaction 接口:
是Hibernate 的事务处理接口,它对底层的事务接口进行封装。
Query 和Criteria 接口:
这两个是Hibernate 的查询接口,用于向数据库查询对象,以及控制执行查询的过程。
Query 实例包装了一个HQL 查询语句。
Criteria 接口完全封装了基于字符串形式的查询语句,比Query 接口更面向对象。Criteria 更擅长于执行动态查询。
补充:find 方法也提供数据查询功能,但只是执行一些简单的HQL 查询语句的快捷方式( 已过时) ,远没有Query 接口强大!
四、Hibernate开发步骤:(重点:必须掌握)
开始:(设置环境变量和配置)
在myeclipse里导入Hibernate的文件包(包括各数据库的驱动和其他的jar包,对版本敏感,注意各版本的兼容)
按hibernate规范编写名字为hibernate.cfg.xml文件(默认放在工程文件夹下)
步骤一:设计和建立数据库表
可以用Hibernate直接生成映射表。
Oracle里建表: create table t_ad (oid number(15) primary key,
ACTNO varchar(20) not null unique,BALANCE number(20));
步骤二:持久化类的设计
POJO---- POJO 在Hibernate 语义中理解为数据库表所对应的Domain Object。(此类中只含有属性、构造方法、get/set方法)
这里的POJO就是所谓的“Plain Ordinary Java Object”,字面上来讲就是无格式普通Java 对象,
简单的可以理解为一个不包含逻辑代码的值对象(Value Object 简称VO)。
步骤三:持久化类和关系数据库的映射
编写*.hbm.xml文件---该文件配置持久化类和数据库表之间的映射关系
<class name=“POJO的类全路径” table=“对应的库表名” //这两项一定要配置,其它的都可以不配置 discriminator-value=“discriminator_value” //区分不同子类的值,多态时使用。默认与类名一样 dynamic-update=“true | false” //是否动态更新SQL。false:每次都更新所有属性;true:只更新修改的 dynamic-insert=“true | false” //是否动态插入SQL。false:每次都插入所有属性;true:只插入非空的 select-before-update=“true | false” //是否在update前查询对象是否被修改过,修改过才update polymorphism=“implicit | explicit” //设置多态是显性(explicit)的还是隐性(implicit)的 where=“查询时使用的SQL的条件子句” //查询时使用的SQL的条件子句 lazy=“true | false” //设置延迟加载策略 />
一个实体对应一个xml文件,组件用id,非组件用property。
*.hbm.xml文件样板:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!--package指文件所在的包名 --> <hibernate-mapping package="com.tarena.ebank.biz.entity"> <!-- name:POJO类的名; table数据库里对应的表名--> <class name="Account" table="student"> <!-- OID:(唯一,中性)表自动生成的(需要另外添加hilo表) --> <id name="oid" column="OID"> <generator class="hilo"> <param name="table">t_hi</param> <param name="column">hi</param> </generator></id> <property name="actNo" column="ACTNO" unique="true" not-null="true"/> <property name="bal" column="BALANCE" not-null="true"/> </class> </hibernate-mapping>
步骤四:Hibernate配置文件
hibernate.cfg.xml或hibernate.properties
1.需要配置那些信息:持久化映射,方言,特性,登陆信息
多数使用默认的设置。
A、dialect:方言,就是拼驱动程序和SQL语句。每种数据库对应一种方言其实就是指定了用那一种数据库。
Oracle数据库方言:org.hibernate.dialect.OracleDialect
MySql数据库方言:org.hibernate.dialect.MySQLDialect
B、Object Persistence:对象持久化。把内存中的数据保存到一个永久的介质中,比如说数据库。
C、ORM:对象关系映射,是一个自动的过程
注:持久对象与临时对象最大的区别是有没有数据库id标识。
2.hibernate.cfg.xml的样板:
<?xml version='1.0' encoding='UTF-8'?> <!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="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="connection.password">password</property> <!-- 自动建表语句:create覆盖旧表,update自动更新,none不理会 --> <property name="hbm2ddl.auto">update</property> <!-- 是否在控制台上打印SQL(Hibernate把语句转化为SQL语句),默认false--> <property name="show_sql">true</property> <!-- 缓存策略,数据量不大可不写 --> <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <property name="cache.use_query_cache">false</property> <property name="cache.use_second_level_cache">false</property> <!-- 不同数据库使用的SQL选择 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="myeclipse.connection.profile">mysql</property> <!-- 连接池配置,练习时不写,使用默认的 --> <property name="connection.pool_size">1</property> <!--决定是采用thread或jta或自定义的方式来产生session,练习时不写,使用默认的 --> <property name="current_session_context_class">thread</property> <!-- *.hbm.xml文件路径,各关联表要一同写上 --> <mapping resource="many_to_one/vo/Customer.hbm.xml" /> <mapping resource="com/tarena/ebank/biz/entity/Order.hbm.xml" /> </session-factory> </hibernate-configuration>