搜档网
当前位置:搜档网 › Hibernate学习笔记

Hibernate学习笔记

Hibernate学习笔记
Hibernate学习笔记

Hibernate项目的构建与配置

1.在项目里倒入Hibernate所必须的Jar包

(1)Hibernate框架可以使用在任何的Java项目里,并不一定是Web项目。只需要在项目里倒入Hibernate

所必须要使用的jar包就可以了。

(2)在Hibernate的官网下载hibernate-release-4.2.2.Final.zip解压,要使用Hibernate必须导入的

jar包就在目录“hibernate-release-4.2.2.Final\lib\required”下。倒入此路径下的所有jar包就可以了。

2.配置hibernate.cfg.xml文件

(1)配置hibernate.cfg.xml文件可以参考“\project\etc”目录下的hibernate.cfg.xml文件与

hibernate.properties文件。

(2)使用Hibernate连接MySQL的hibernate.cfg.xml配置文件如下:

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"https://www.sodocs.net/doc/7b14688746.html,/dtd/hibernate-configuration-3.0.dtd">

(设置显示Hibernate产生的SQL语句)

true

(设置MySQL的SQL语法的方言)

org.hibernate.dialect.MySQLDialect

(设置MySQL的驱动程序)

org.gjt.mm.mysql.Driver

(设置MySQL的数据库路径、用户名、密码)

jdbc:mysql:///java

root

lizhiwei

(设置当数据库要保存的表不存在时,就新建表)

update

(设置对象与数据库表的关系映射文件)

(3)此配置文件一般放在项目的src目录下。(注意:在项目中要加入MySQL的驱动jar包)

3.编写实例类与对象-关系映射文件

(1)一个实例类对象就是数据库表里的一条记录,关系映射文件就指明了类的成员变量与数据库字段间的

关系以及该类对象保存在哪个表中。

(2)实例类User.java:

public class User {

private long id;

private String name;

private int age;

private char sex;

public long getId() {

return id;

}

public void setId(long id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

https://www.sodocs.net/doc/7b14688746.html, = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public char getSex() {

return sex;

}

public void setSex(char sex) {

this.sex = sex;

}

@Override

public String toString() {

return"User [id=" + id + ", name=" + name + ", age=" + age + ", sex="

+ sex + "]";

}

}

(3)User.java对应的User.hbm.xml文件:

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"https://www.sodocs.net/doc/7b14688746.html,/dtd/hibernate-mapping-3.0.dtd">(package的值是User.java所在的包路径)

(name的值是实例的类名,table的值是对应的数据库表名)

(name的值是实例的主键名)

(定义了主键值生成器)

(定义实例属性与数据库表字段的对应关系)

(4)User.hbm.xml文件与User.java文件放在同一目录下。

4.编写测试类

(1)测试类Hibernate.java如下:

package test;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

import https://www.sodocs.net/doc/7b14688746.html,er;

public class Hibernate {

public static void main(String[] args) {

Configuration cfg=new Configuration();

cfg.configure();

ServiceRegistry sr = new ServiceRegistryBuilder()

.applySettings(cfg.getProperties())

.buildServiceRegistry();

SessionFactory sf=cfg.buildSessionFactory(sr);

Session s=sf.openSession();

Transaction tx=s.beginTransaction();

User u=new User();

u.setName("KKKK");

u.setAge(20);

u.setSex('f');

s.save(u);

https://www.sodocs.net/doc/7b14688746.html,mit();

s.close();

System.out.println("OK");

}

}

(2)运行Hibernate.java即可在数据库里保存一条记录!!!

Hibernate核心知识

1.创建Session对象操作数据库

(1)创建Session对象的过程

?创建Configuration对象使用new关键字,如:Configuration cfg=new Configuration()。

?读取Hibernate配置文件(hibernate.cfg.xml),有如下三种方式:

cfg.configure();//读取默认名称的配置文件

cfg.configure("hibernate.cfg.xml");//读取指定名称的配置文件

cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect") .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")

.setProperty("hibernate.order_updates", "true");//程序设置配置属性?读取对象—关系映射文件,有如下两种方式:

cfg.addResource("Student.hbm.xml").addResource("Teacher.hbm.xml");//读取配置文件

cfg.addClass(vo.Student.class).addClass(vo.Teacher.class);//读取类

?得到SessionFactory,得到了该对象就可以得到很多Session对象,有如下两种方式:ServiceRegistry sr = new ServiceRegistryBuilder()

.applySettings(cfg.getProperties())

.buildServiceRegistry();

SessionFactory sf=cfg.buildSessionFactory(sr);

SessionFactory sessions = cfg.buildSessionFactory();//此种方式已过时?得到Session对象的两种方式以及区别:

Session s=sf.getCurrentSession();//要配置"hibernate.current_session_context_class"

如果前一个Session未close,从上下文得到Session,不一定会new一个新的。建议使用。

Session s=sf.openSession();//一定会new一个新的Session

注意:getCurrentSession()方法创建的Session对象提交事务时就会自动关闭Session,不必调用close()方法。而openSession()不会,需要调用close()方法关闭Session。

?得到一个Session后就可以对数据进行增删查改了。可以把一个Session看成一个事务。

(2)事务的开始与提交

Transaction tx=s.beginTransaction();//开始事务,s是Session对象

{ 对数据进行增删查改 }//处理事务

https://www.sodocs.net/doc/7b14688746.html,mit();//提交事务

2.Hibernate的ID生成策略

(1)使用节点设置主键生成器。例如:

(2)increment:适用于代理主键,由Hibernate自动以递增的方式生成标识符,每次增量为1。ID必须为long、

int、short类型。

(3)identity:适用于代理主键,由底层数据库生成标识符,前提条件是底层数据库支持自动增长的字段

类型,例如:DB2、MySQL、MS SQLServer、Sybase等。OID必须是long、int、short类型。

(4)sequence:适用于代理主键,Hibernate根据底层数据库的序列来生成标识符,前提条件是底层数据库

支持序列,例如DB2、Oracle等。OID必须是long、int、short类型。

(5)hilo:适用于代理主键,Hibernate根据high/low算法来生成标识符,Hibernate把特定的表字段作为

“high”值,在默认情况下选用hibernate_unique_key表的next_hi字段。OID必须是long、int、short 类型;high/low算法生成的标识符只能在一个数据库中保证唯一。

(6)native:适用于代理主键,根据底层数据库对自动生成标识符的支持能力,来选择identity、sequence

或hilo。OID必须是long、int、short类型。

(7)uuid.hex:适用于代理主键,Hibernate采用128位的UUID算法来生成标识符,UUID能在网络环境下生成

唯一的字符串标识符。

(8)assigned:适用于自然主键,由Java应用程序负责生成标识符,为了能让Java应用程序设置OID,不能

把setID()方法申明为private类型。

(9)select:适用于遗留数据库中的代理主键或自然主键,由数据库中的触发器来生成标识符。

(10)foreign:用另一个关联对象的标识符来作为当前对象的标识符,主要用于一对一的关联场合。

3.Hibernate核心接口

(1)Configuration接口

Configuration接口的作用是对Hibernate进行配置,以及对它进行启动。在Hibernate的启动过程中,Configuration类实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory 对象。

重要方法:

public Configuration configure (?)在参数中指定要加载的配置文件

public SessionFactory buildSessionFactory()根据配置文件实例化一个新的SessionFactory 对象,这个SessionFactory将是不可变的,所以在创建了SessionFactory对象后,对Configuration 对象作出的所有修改不会影响以前创建出的SessionFactory对象。

Configuration对象的作用是除了有读取配置文件的功能,还能创建SessionFactory对象。通常,一个应用程序会创建一个Configuration对象,然后利用Configuration实例建立唯一的

SessionFactory实例,这就意味着Configuration对象只存在于系统的初始化阶段,然后所有的持久化操作都能通过这个唯一的SessionFactory实例来进行。

Configuration对象只有在Hibernate 进行初始化的时候才需要创建,当使用Configuration对象的实例创建了SessionFactory对象的实例后,其配置信息已经绑定在他返回的SessionFactory对象实例中。因此,一般情况下,得到SessionFactory对象后,Configuration对象的使命就结束了。(2)SessionFactory接口

这里用到了一个设计模式—工厂模式,用户程序从工厂类SessionFactory中取得Session的实例。SessionFactory不是轻量级的!它的设计者的意图是让它能在整个应用共享。典型地来说,一个项目通常只需要一个SessionFactory就够了,但是当你的项目要操作多个数据库时,那你必须为每个数据库指定一个SessionFactory。一个SessionFactory实例对应一个数据存储源,应用从

SessionFactory中获得Session实例。

它具有如下特点:

1)它是线程安全的,这意味着它的同一个实例可以被应用的各个线程共享。

2)它是重量级的,这意味着不能随意创建或销毁它的实例。

3)之所以说SessionFactory是重量级的,是因为它需要一个很大的缓存,用来存放预定义的SQL 语句以及映射元数据等。用户还可以为SessionFactory配置一个缓存插件,这个缓存插件被称为Hibernate的第二级缓存,该缓存用来存放被工作单元读过的数据,将来其它工作单元可能会重用这些数据,因此这个缓存中的数据能够被所有工作单元共享,一个工作单元通常对应一个数据库事务。

SessionFactory接口负责初始化Hibernate。

重要方法:

public Sessioin openSession()创建一个数据库连接,并把他放在Session对象中,并返回

public Session openSession(Connection connection)创建一个Session对象,并把参数给出的 connection对象放在其中

public boolean isClosed()判断当前SessionFactory对象是否关闭了

public void close()关闭SessionFactory以及释放所有的SessionFactory涉及到的资源(缓存,数据库连接池等)但在调用此方法之前,应该确定没有当前对象创建的 Session没有关闭

(3)Session接口

Session接口对于Hibernate 开发人员来说是一个最重要的接口。然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁它都不会占用很多资源。这在实际项目中确实很重要,因为在客户程序中,可能会不断地创建以及销毁Session对象,如果Session的开销太大,会给系统带来不良影响。

Session具有一下特点:

1)不是线程安全的,因此在设计软件架构时,应该避免多个线程共享同一个Session实例。

2)Session实例是轻量级的,所谓轻量级,是指它的创建和销毁不需要消耗太多的资源。这意味着在程序中可以经常创建和销毁Session对象,例如为每个客户请求分配单独的 Session实例,或者为每个工作单元分配单独的Session实例。

3)Session有一个缓存,被称为Hibernate的第一级缓存,它存放被当前工作单元加载的对象。

每个Session实例都有自己的缓存,这个Session实例的缓存只能被当前工作单元访问。Session接口负责执行被持久化对象的CRUD操作 (CRUD的任务是完成与数据库的交流,添加、更新、删除、加载和查询对象,包含了很多常见的SQL语句。)。

在Hibernate的设计者的头脑中,他们将session看作介于数据连接与事务管理一种中间接口。

我们可以将session想象成一个持久对象的缓冲区,Hibernate能检测到这些持久对象的改变,并及时刷新数据库。我们有时也称Session是一个持久层管理器,因为它包含这一些持久层相关的操作,诸如存储持久对象至数据库,以及从数据库中获得它们。请注意,Hibernate 的session不同于JSP应用中的HttpSession。以后会将HttpSesion对象称为用户session。

重要方法:

public Transaction beginTransaction()在数据库中重新开始一个事务

public Transaction getTransaction()返回和当前session联系的Transaction对象

public Connection connection close()结束当前的Session对象

public void clear()清空Session,清除所有保存在当前Session缓存中的实体对象,终止所有正在执行的方法(eg: save() , update() ,delete() .....)

public Serializable save(Object object)对当前参数指定的对象进行持久化(系统会首先赋予参数对象一个标识符OID),他相当于insert语句后面在详细介绍

public Connection connection()得到当前Session 中包含的Connection对象。

public boolean contains(Object object)判断参数给出的对象(持久化类)是否在当前Session 的缓存中

public void evict(Object object)将参数给出的Object从当前Session对象类中删除,使这个对象从持久态变成游离态,这种状态的改变不会引起对数据库的同步

public Object load(Class theclass ,Serializable id)返回第一个参数指定类对应的表中,第二个参数指定的行(第二个参数就是要取得对象的OID,他对应表中主键列的值)

public void update(Object object)更新一个对象到数据库中

public void delete (Object object)从数据库中删除和参数指定的对象对应的记录

public Object get(Class class,Serializable id)和load()方法一样区别在于,如果数据库表中没有对应的记录,get()方法返回null,load()方法将报异常

(4)Transaction接口

Transaction接口是一个可选的API,你可以选择不使用这个接口,取而代之的是Hibernate的设计者自己写的底层事务处理代码。它将应用代码从底层的事务实现中抽象出来——这可能是一个JDBC 事务(Connection事务,基于数据库的事务),一个JTA事务(基于分布式的事务,同时管理多个数据库之间的事务)或者甚至是一个公共对象请求代理结构(CORBA)——允许应用通过一组一致的API 控制事务边界。这有助于保持Hibernate应用在不同类型的执行环境或容器中的可移植性。

Transaction tx = session.beginTransaction();

注:使用Hibernate进行操作时(增、删、改)必须显示的调用Transaction(默认:autoCommit=false)。

重要方法:

public void commit()刷新当前的Session以及结束事务的工作,提交事务

public void rollback()强迫回滚当前事务

public boolean isActive()这个事务是否存活

(5)Query和Criteria接口

它们是Hibernate的查询接口,用于向数据库查询对象,以及控制执行查询的过程。query实例封装了一个HQL(Hibernate Query Language)查询语句,HQL是面向对象的,它引用类名及类的属性名,而不是表名及表的字段名。Criteria接口完全封装了基于字符串形式的查询语句,比Query接口更加面向对象,Criteria接口更擅长于执行动态查询。 Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。

Criteria接口与Query接口非常类似,它允许你创建并执行面向对象的标准化查询。

值得注意的是Query接口也是轻量级的,它不能在Session之外使用。Session接口的find()方法也具有数据查询功能,但它只是执行一些简单的HQL查询语句的快捷方法,它的功能远没有Query接口强大。

(6)Callback接口

当一些有用的事件发生时—例如持久对象的载入、存储、删除时,Callback接口会通知Hibernate 去接收一个通知消息。一般而言,Callback接口在用户程序中并不是必须的,但要在项目中创建审计日志时,可能会用到它。

4.对象三种状态

(1)临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象

叫临时对象。

(2)持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对

象。处于此状态的对象叫持久对象。

(3)游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已

经持久化,但不在Session缓存中。处于此状态的对象叫游离对象。

(4)三种状态的转换图:

(5)游离对象和临时对象异同:两者都不会被Session关联,对象属性和数据库可能不一致;游离对象有持

久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了。

(6)Hibernate和SQL的关系:在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作

数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库。

(7)Session.save(user)运行机理。

?把User对象加入缓存中,使它变成持久化对象。

?选用映射文件指定的标识生成ID。

?在Session清理缓存时候执行:在底层生成一个insert sql语句,把对象存入数据库。

注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改。

(8)Session.delete(user)运行过程。

?如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:在Session清理缓存时候。

?如果user是游离对象:将user对象和Session关联,使之成为持久化对象;然后按照user 是持久化对象的过程执行。

5.关联关系映射

(1)关系映射说明

?首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射。ORM 的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作。Hibernate正是实现了这种思想,达到了方便开发人员以面向对象的思想来实现对数据库的操作。

?Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java)、映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg.xml),它们各自的作用如下。

?映射类(*.java):它是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象了。

?映射文件(*.hbm.xml):它是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。

?数据库配置文件(*.properties/*.cfg.xml):它是指定与数据库连接时需要的连接信息,比如连接哪种数据库、登录数据库的用户名、登录密码以及连接字符串等。当然还可以把映射类的地址映射信息放在这里。

(2)多对一(many-to-one)

?单向 many-to-one 关联是最常见的单向关联关系

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key, addressId bigint not null)

create table Address ( addressId bigint not null primary key )

?使用连接表的单向 many-to-one 关联

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress (

personId bigint not null primary key,

addressId bigint not null )

create table Address ( addressId bigint not null primary key )

(3)一对一(One-to-one)

?基于外键的单向一对一关联

映射文件的配置:

产生的数据库语句:

create table Person (

personId bigint not null primary key,

addressId bigint not null unique )

create table Address ( addressId bigint not null primary key )

?基于主键的单向一对一联

映射文件的配置:

person

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table Address ( personId bigint not null primary key )

?基于连接表的单向一对一关联(非常少见)

映射文件的配置:

not-null="true"unique="true"/>

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress (

personId bigint not null primary key,

addressId bigint not null unique )

create table Address ( addressId bigint not null primary key )

?基于外键的双向一对一关联(很常见)

映射文件的配置:

产生的数据库语句:

create table Person (

personId bigint not null primary key,

addressId bigint not null unique )

create table Address ( addressId bigint not null primary key )

?基于主键的双向一对一关联(需要使用特定的 id 生成器)

映射文件的配置:

person

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table Address ( personId bigint not null primary key )

?基于连接表的双向一对一关联(极为罕见)

映射文件的配置:

not-null="true"unique="true"/>

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress (

personId bigint not null primary key,

addressId bigint not null unique )

create table Address ( addressId bigint not null primary key )

(4)一对多(one-to-man)

?基于外键的单向一对多关联(不推荐,推荐使用连接表)

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table Address ( addressId bigint not null primary key, personId bigint not null) ?基于连接表的单向一对多关联(应该优先被采用)

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress ( personId not null, addressId bigint not null primary key)

create table Address ( addressId bigint not null primary key )

?双向一对多(多对一)关联

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key, addressId bigint not null)

create table Address ( addressId bigint not null primary key )

如果你使用 List(或者其他有序集合类),你需要设置外键对应的 key 列为 not null。

Hibernate 将从集合端管理关联,维护每个元素的索引,并通过设置 update="false" 和

insert="false" 来对另一端反向操作。

映射文件的配置:

...

insert="false"update="false"/>

...

假若集合映射的 元素对应的底层外键字段是 NOT NULL 的,那么为这一 key 元素定义not-null="true" 是很重要的。不要仅仅为可能的嵌套 元素定义 not-null="true", 元素也是需要的。

?基于连接表的双向一对多关联

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress (

personId bigint not null,

addressId bigint not null primary key )

create table Address ( addressId bigint not null primary key )

(5)多对多(many-to-many)

?单向多对多关联

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress (

personId bigint not null,

addressId bigint not null,

primary key (personId, addressId) )

create table Address ( addressId bigint not null primary key )

?双向多对多关联

映射文件的配置:

产生的数据库语句:

create table Person ( personId bigint not null primary key )

create table PersonAddress (

personId bigint not null,

addressId bigint not null,

primary key (personId, addressId) )

create table Address ( addressId bigint not null primary key )

(6)更复杂的关联映射

更复杂的关联映射请参考Hibernate文档。

6.Hibernate连接池设置

(1)Hibernate默认连接池

?默认情况下(即没有配置连接池的情况下),Hibernate会采用内建的连接池.但这个连接池性能不佳,且存在诸多BUG,因此官方也只是建议仅在开发环境下使用。

org.gjt.mm.mysql.Driver

jdbc:mysql:///java

root

lizhiwei

true

org.hibernate.dialect.MySQLDialect

update

(2)proxool连接池(首选)

?目前proxool被大部分人认为是最优秀的,它提供监控的功能,方便易用,便于发现连接泄漏的情况。

?新建proxool的配置文件,文件名:proxoolconf.xml,放在与hibernate.cfg.xml同目录下。

DBPool

jdbc:oracle:thin:@localhost:1521:orcl

oracle.jdbc.driver.OracleDriver

90000

20

5

100

10

?配置hibernate.cfg.xml文件

org.hibernate.connection.ProxoolConnectionProvider

DBPool

proxoolconf.xml

org.hibernate.dialect.Oracle10gDialect

true

(3)C3P0连接池

oracle.jdbc.driver.OracleDriver

jdbc:oracle:thin:@localhost:1521:orcl

system

orcl

org.hibernate.dialect.Oracle10gDialect

true

org.hibernate.connection.C3P0ConnectionProvider

20

5

120

100

120

2

(4)dbcp连接池

dbcp连接池与C3P0连接池配置很相似,只需要在基础配置上加入下面的配置。

100

1

60000

10

100

1

60000

10

(5)JNDI连接池

?数据源由应用服务配置好(如Tomcat、resin、weblogic等),Hibernate需要做的只是通过JNDI 名查找到此数据源。应用服务器将连接池对外显示为JNDI绑定数据源,它是javax.jdbc.Datasource 类的一个实例。

?只要配置一个Hibernate文件,如:hibernate.properties。

hibernate.connection.datasource=java:/comp/env/jdbc/schoolproject

hibernate.transaction.factory_class = org.hibernate.transaction.JTATransactionFactory

hibernate.transaction.manager_loopup_class = org.hibernate.transaction.JBossTransactionManagerLookup hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

?服务器配置Tomcat6\conf\context.xml

maxActive="100" maxIdle="30"maxWait="10000"username="system"password="orcl"

driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>

(6)结论

由于在Hibernate3.0中,已经不再支持dbcp了,Hibernate的作者在https://www.sodocs.net/doc/7b14688746.html,中,明确指出在实践中发现dbcp有BUG,在某些种情会产生很多空连接不能释放,所以抛弃了对dbcp的支持。我不知是否在dbcp最新版本中解决了这个问题,我以前在一个访问量不大的项目中用过dbcp,运行了一年多都没出现问题。不过在网上的确也有不少网友指出dbcp在大型的应用中会出现不稳定的情况。所以在真相未经证实的情况下,我觉得对dbcp持慎重的态度。

至于c3p0,有评论说它的算法不是最优的,而且,我在matrix中,见到有网友做了一个实验,在同一项目中分别用了几个常用的Hibernate连接池配置,然后测试其性能,发现c3p0占用资源比较大,效率也不高。

所以,基于上述原因,我才花两晚的时间去研究proxool的配置,proxool不少行家推荐使用,而且暂时来说,是负面评价是最少的一个。在三星中也有项目是用proxool的。

7.数据的查询方式(SQL、HQL、QBC)

(1)Hibernate数据查询的三种方式

?使用HQL语句查询

//session.createQuery("HQL查询语句");

Query query=session.createQuery("from Person");//s.createQuery("from vo.Person")

List arryp=(List)query.list();

for(Person p : arryp)

{System.out.println(p);}

?使用SQL查询

//session.createSQLQuery("SQL查询语句");

SQLQuery sql_query=session.createSQLQuery("select * from person");

sql_query=sql_query.addEntity(Person.class);//把查询结果放到对象里

List arryp=(List)sql_query.list();

for(Person p : arryp)

{System.out.println(p);}

?使用QBC查询

Criteria c=session.createCriteria(Person.class)//选择查询的表

.add(Restrictions.like("name", "李志伟%"));//设置查询条件

List arryp=(List)c.list();

for(Person p : arryp)

{System.out.println(p);}

?下面主要讲HQL语法。

(2)from子句

?Hibernate 中最简单的查询语句的形式如下:from eg.Cat。该子句简单的返回 eg.Cat 类的所有实例。通常我们不需要使用类的全限定名,因为 auto-import(自动引入)是缺省的情况。所以我们几乎只使用如下的简单写法:from Cat

?为了在这个查询的其他部分里引用 Cat,你将需要分配一个别名。例如:from Cat as cat这个语句把别名 cat指定给类Cat的实例,这样我们就可以在随后的查询中使用此别名了。关键字 as 是可选的,我们也可以这样写:from Cat cat

?子句中可以同时出现多个类,其查询结果是产生一个笛卡儿积或产生跨表的连接。例如:from Formula, Parameter 或 from Formula as form, Parameter as param。查询语句中别名的开头部分小写被认为是实践中的好习惯,这样做与 Java 变量的命名标准保持了一致(比如,domesticCat)。(3)关联(Association)与连接(Join)

?我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名,这时要使用关键字join。例如:

from Cat as cat

inner join cat.mate as mate

left outer join cat.kittens as kitten

from Cat as cat left join cat.mate.kittens as kittens

from Formula form full join form.parameter param

?受支持的连接类型是从 ANSI SQL 中借鉴来的:inner join、left outer join、right outer join、full join(全连接,并不常用)。语句 inner join,left outer join 以及 right outer join 可以简写。例如:

from Cat as cat

join cat.mate as mate

left join cat.kittens as kitten

?通过 HQL 的 with 关键字,你可以提供额外的 join 条件。例如:

from Cat as cat

left join cat.kittens as kitten

with kitten.bodyWeight > 10.0

?使用“fetch”连接允许值关联或集合将随着使用一个选择它们的父对象的初始化。这是一个集合的情况下尤其有用。它有效地覆盖了外连接和映射文件关联和集合懒惰声明。例如:

from Cat as cat

inner join fetch cat.mate

left join fetch cat.kittens

?一个 fetch 连接通常不需要被指定别名,因为相关联的对象不应当被用在 where 子句(或其它任何子句)中。同时,相关联的对象并不在查询的结果中直接返回,但可以通过他们的父对象来访问到他们。

from Cat as cat

inner join fetch cat.mate

left join fetch cat.kittens child

left join fetch child.kittens

?假若使用 iterate() 来调用查询,请注意 fetch 构造是不能使用的(scroll() 可以使用)。

fetch 也不应该与 setMaxResults() 或 setFirstResult() 共用,这是因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,也就是说无法预先知道精确的行数。fetch 还不能与独立的 with 条件一起使用。通过在一次查询中 fetch 多个集合,可以制造出笛卡尔积,因此请多加注意。对 bag 映射来说,同时 join fetch 多个集合角色可能在某些情况下给出并非预期的结果,也请小心。最后注意,使用 full join fetch 与 right join fetch 是没有意义的。

?如果你使用属性级别的延迟获取(lazy fetching)(这是通过重新编写字节码实现的),可以使用 fetch all properties 来强制 Hibernate 立即取得那些原本需要延迟加载的属性(在第一个查询中)。

from Document fetch all properties order by name

from Document doc fetch all properties where lower(https://www.sodocs.net/doc/7b14688746.html,) like '%cats%' (4)join语法的形式

?HQL 支持两种关联 join 的形式:implicit(隐式)与 explicit(显式)。上一节中给出的查询都是使用 explicit(显式)形式的,其中 form 子句中明确给出了 join 关键字。这是建议使用的方式。

?implicit(隐式)形式不使用 join 关键字。关联使用"点号"来进行“引用”。implicit join 可以在任何 HQL 子句中出现。implicit join 在最终的 SQL 语句中以 inner join 的方式出现。例如:from Cat as cat where https://www.sodocs.net/doc/7b14688746.html, like '%s%'

(5)引用identifier属性

?通常有两种方法来引用实体的 identifier 属性:特殊属性(lowercase)id 可以用来引用实体的 identifier 属性假设这个实体没有定义用 non-identifier 属性命名的 id。如果这个实体定义了 identifier 属性,你可以使用属性名。

?对组合 identifier 属性的引用遵循相同的命名规则。如果实体有一个 non-identifier 属性命名的 id,这个组合 identifier 属性只能用自己定义的名字来引用;否则,特殊 id 属性可以用来引用 identifier 属性。

?注意:从 3.2.2 版本开始,这已经改变了很多。在前面的版本里,不管实际的名字,id 总是指向 identifier 属性;而用 non-identifier 属性命名的 id 就从来不在 Hibernate 查询里引用。

(6)select子句

?select 子句选择将哪些对象与属性返回到查询结果集中。考虑如下情况:

select mate

from Cat as cat

inner join cat.mate as mate

该语句将选择其它 Cat 的 mate(其他猫的配偶)。实际上,你可以更简洁的用以下的查询语句表达相同的含义:select cat.mate from Cat cat

?查询语句可以返回值为任何类型的属性,包括返回类型为某种组件(Component)的属性,例:select https://www.sodocs.net/doc/7b14688746.html, from DomesticCat cat

where https://www.sodocs.net/doc/7b14688746.html, like 'fri%'

select https://www.sodocs.net/doc/7b14688746.html,.firstName from Customer as cust

?查询语句可以返回多个对象和(或)属性,存放在 Object[] 队列中,例如:

select mother, offspr, https://www.sodocs.net/doc/7b14688746.html,

from DomesticCat as mother

inner join mother.mate as mate

left outer join mother.kittens as offspr

?或存放在一个 List 对象中,例如:

select new list(mother, offspr, https://www.sodocs.net/doc/7b14688746.html,)

from DomesticCat as mother

inner join mother.mate as mate

left outer join mother.kittens as offspr

?假设类 Family 有一个合适的构造函数—作为实际的类型安全的 Java 对象,例如:select new Family(mother, mate, offspr)

from DomesticCat as mother

join mother.mate as mate

left join mother.kittens as offspr

?你可以使用关键字 as 给“被选择了的表达式”指派别名,例如:

select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n

from Cat cat

?这种做法在与子句 select new map 一起使用时最有用,例如:

select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )

from Cat cat(该查询返回了一个 Map 的对象,内容是别名与被选择的值组成的名-值映射) (7)聚集函数

?HQL 查询甚至可以返回作用于属性之上的聚集函数的计算结果,例如:

select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)

from Cat cat

?受支持的聚集函数如下:avg(...)、sum(...)、min(...)、max(...)、count(*)、count(...)、count(distinct ...)、count(all...)。你可以在选择子句中使用数学操作符、连接以及经过验证的SQL 函数,例如:

select cat.weight + sum(kitten.weight)

from Cat cat

join cat.kittens kitten

group by cat.id, cat.weight

?使用“||”连接字符串,例如:

select firstName||' '||initial||' '||upper(lastName) from Person

?关键字 distinct 与 all 也可以使用,它们具有与 SQL 相同的语义,例如:

select distinct https://www.sodocs.net/doc/7b14688746.html, from Cat cat

select count(distinct https://www.sodocs.net/doc/7b14688746.html,), count(cat) from Cat cat

(8)多态查询

?一个如下的查询语句:from Cat as cat。不仅返回 Cat 类的实例,也同时返回子类 DomesticCat 的实例。Hibernate 可以在 from 子句中指定任何 Java 类或接口。查询会返回继承了该类的所有持久化子类的实例或返回声明了该接口的所有持久化类的实例。下面的查询语句返回所有的被持久化的对象,例如:from https://www.sodocs.net/doc/7b14688746.html,ng.Object o

?接口 Named 可能被各种各样的持久化类声明:

from Named n, Named m where https://www.sodocs.net/doc/7b14688746.html, = https://www.sodocs.net/doc/7b14688746.html,

?注意,最后的两个查询将需要超过一个的 SQL SELECT。这表明 order by 子句没有对整个结果集进行正确的排序。(这也说明你不能对这样的查询使用 Query.scroll() 方法。)

(9)where子句

?where 子句允许你将返回的实例列表的范围缩小。如果没有指定别名,你可以使用属性名来直接引用属性:from Cat where name='Fritz'

?如果指派了别名,需要使用完整的属性名:from Cat as cat where https://www.sodocs.net/doc/7b14688746.html,='Fritz'

?返回名为(属性 name 等于)'Fritz' 的 Cat 类的实例。下面的查询:

select foo

from Foo foo, Bar bar

where foo.startDate = bar.date

?将返回所有满足下面条件的 Foo 类的实例:存在如下的 bar 的一个实例,其 date 属性等于 Foo 的 startDate 属性。复合路径表达式使得 where 子句非常的强大,考虑如下情况:from Cat cat where https://www.sodocs.net/doc/7b14688746.html, is not null

?该查询将被翻译成为一个含有表连接(内连接)的SQL查询。如果你打算写像这样的查询语句,在SQL中,你为达此目的将需要进行一个四表连接的查询,如下:

from Foo foo

where foo.bar.baz.customer.address.city is not null

?“=”运算符不仅可以被用来比较属性的值,也可以用来比较实例:

from Cat cat, Cat rival where cat.mate = rival.mate

select cat, mate

from Cat cat, Cat mate

where cat.mate = mate

?特殊属性(小写)的id可以用来表示一个对象的唯一标识符。第二个查询是有效的。此时不需要进行表连接。

from Cat as cat where cat.id = 123

from Cat as cat where cat.mate.id = 69

?同样也可以使用复合标识符。比如 Person 类有一个复合标识符,它由 country 属性与medicareNumber 属性组成,第二个查询也不需要进行表连接。

from bank.Person person

where person.id.country = 'AU'

and person.id.medicareNumber = 123456

from bank.Account account

where account.owner.id.country = 'AU'

and account.owner.id.medicareNumber = 123456

?同样的,特殊属性 class 在进行多态持久化的情况下被用来存取一个实例的鉴别值(discriminator value)。一个嵌入到 where 子句中的 Java 类的名字将被转换为该类的鉴别值。

from Cat cat where cat.class = DomesticCat

?您还可以使用组件或复合用户类型,或属性表示组件类型。一个“任意”类型有两个特殊的属性 id 和 class,来允许我们按照下面的方式表达一个连接(AuditLog.item 是一个属性,该属性被映射为 )。

from AuditLog log, Payment payment

where log.item.class = 'Payment' and log.item.id = payment.id ?注意,在上面的查询与句中,log.item.class 和 payment.class 将涉及到完全不同的数据库中的列。

(10)表达式

?在 where 子句中允许使用的表达式包括大多数你可以在 SQL 使用的表达式种类:

?数学运算符 +,-,*,/

?二进制比较运算符 =, >=, <=, <>, !=, like

?逻辑运算符 and,or,not

?括号 ( ),表示分组

?in、not in、between、is null、is not null、is empty、is not empty、member of and not member of

?"Simple" case, case ... when ... then ... else ... end, and "searched" case, case when ...

then ... else ... end

?字符串连接符 ...||... or concat(...,...)

?current_date(), current_time(), and current_timestamp()

?second(...)、minute(...)、hour(...)、day(...)、month(...) 和 year(...)

?EJB-QL 3.0 定义的任何功能或操作符:substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()

?coalesce() 和 nullif()

?str() 把数字或者时间值转换为可读的字符串

?cast(... as ...),其第二个参数是某 Hibernate 类型的名字,以及 extract(... from ...),只要 ANSI cast() 和 extract() 被底层数据库支持

?HQL index() 函数,作用于 join 的有序集合的别名。

?HQL 函数,把集合作为参数:size(), minelement(), maxelement(), minindex(), maxindex(),还有特别的 elements() 和 indices 函数,可以与数量词加以限定:some, all, exists, any, in。

?任何数据库支持的 SQL 标量函数,比如 sign(), trunc(), rtrim(), sin()

?JDBC 风格的参数传入,例如:命名参数 :name,:start_date,:x1

?SQL 直接常量 'foo', 69, 6.66E+2, '1970-01-01 10:00:01.0'

?Java public static final 类型的常量 eg.Color.TABBY

?关键字 in 与 between 可按如下方法使用:

from DomesticCat cat where https://www.sodocs.net/doc/7b14688746.html, between 'A' and 'B'

from DomesticCat cat where https://www.sodocs.net/doc/7b14688746.html, in ( 'Foo', 'Bar', 'Baz' )

from DomesticCat cat where https://www.sodocs.net/doc/7b14688746.html, not between 'A' and 'B'

from DomesticCat cat where https://www.sodocs.net/doc/7b14688746.html, not in ( 'Foo', 'Bar', 'Baz' ) ?同样,子句 is null 与 is not null 可以被用来测试空值(null)。

?在 Hibernate 配置文件中声明 HQL“查询替代(query substitutions)”之后,布尔表达式(Booleans)可以在其他表达式中轻松的使用:

true 1, false 0?系统将该 HQL 转换为 SQL 语句时,该设置表明将用字符 1 和 0 来取代关键字 true 和false:from Cat cat where cat.alive = true

?你可以用特殊属性 size,或是特殊函数 size() 测试一个集合的大小。

from Cat cat where cat.kittens.size > 0

from Cat cat where size(cat.kittens) > 0

?对于索引了(有序)的集合,你可以使用 minindex 与 maxindex 函数来引用到最小与最大的索引序数。同理,你可以使用 minelement 与 maxelement 函数来引用到一个基本数据类型的集合中最小与最大的元素。例如:

from Calendar cal where maxelement(cal.holidays) > current_date

from Order order where maxindex(order.items) > 100

from Order order where minelement(order.items) > 10000

?在传递一个集合的索引集或者是元素集(elements 与 indices 函数)或者传递一个子查询的结果的时候,可以使用 SQL 函数 any, some,all, exists, in:

select mother from Cat as mother, Cat as kit

where kit in elements(foo.kittens)

select p from NameList list, Person p

where https://www.sodocs.net/doc/7b14688746.html, = some elements(https://www.sodocs.net/doc/7b14688746.html,s)

from Cat cat where exists elements(cat.kittens)

from Player p where 3 > all elements(p.scores)

from Show show where 'fizard' in indices(show.acts)

?注意,在 Hibernate3 中,这些结构变量— size,elements,indices,minindex,maxindex,minelement,maxelement —只能在 where 子句中使用。

?一个被索引过的(有序的)集合的元素(arrays,lists,maps)可以在其他索引中被引用(只能在 where 子句中):

from Order order where order.items[0].id = 1234

select person from Person person, Calendar calendar

where calendar.holidays['national day'] = person.birthDay

and person.nationality.calendar = calendar

select item from Item item, Order order

where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 select item from Item item, Order order

where order.items[ maxindex(order.items) ] = item and order.id = 11 ?在 [] 中的表达式甚至可以是一个算数表达式:

select item from Item item, Order order

where order.items[ size(order.items) - 1 ] = item

?对于一个一对多的关联(one-to-many association)或是值的集合中的元素,HQL 也提供内建的 index() 函数。

select item, index(item) from Order order

join order.items item

where index(item) < 5

?如果底层数据库支持标量的 SQL 函数,它们也可以被使用:

from DomesticCat cat where upper(https://www.sodocs.net/doc/7b14688746.html,) like 'FRI%'

(11)order by子句

?查询返回的列表(list)可以按照一个返回的类或组件(components)中的任何属性(property)进行排序:

from DomesticCat cat

order by https://www.sodocs.net/doc/7b14688746.html, asc, cat.weight desc, cat.birthdate

?可选的 asc 或 desc 关键字指明了按照升序或降序进行排序。

(12)group by子句

?一个返回聚集值(aggregate values)的查询可以按照一个返回的类或组件(components)中的任何属性(property)进行分组:

select cat.color, sum(cat.weight), count(cat)

from Cat cat

group by cat.color

select foo.id, avg(name), max(name)

from Foo foo join https://www.sodocs.net/doc/7b14688746.html,s name

group by foo.id

having 子句在这里也允许使用。

select cat.color, sum(cat.weight), count(cat)

from Cat cat

group by cat.color

having cat.color in (eg.Color.TABBY, eg.Color.BLACK) ?如果底层的数据库支持的话(例如不能在 MySQL 中使用),SQL 的一般函数与聚集函数也可以出现在 having 与 order by 子句中。

select cat

from Cat cat join cat.kittens kitten

group by cat.id, https://www.sodocs.net/doc/7b14688746.html,, cat.other, cat.properties

having avg(kitten.weight) > 100

order by count(kitten) asc, sum(kitten.weight) desc ?注意 group by 子句与 order by 子句中都不能包含算术表达式(arithmetic expressions)。

也要注意 Hibernate 目前不会扩展 group 的实体,因此你不能写 group by cat,除非 cat 的所有属性都不是聚集的(non-aggregated)。你必须明确的列出所有的非聚集属性。

(13)子查询

?对于支持子查询的数据库,Hibernate 支持在查询中使用子查询。一个子查询必须被圆括号包围起来(经常是 SQL 聚集函数的圆括号)。甚至相互关联的子查询(引用到外部查询中的别名的子查询)也是允许的。

from Cat as fatcat

where fatcat.weight > ( select avg(cat.weight) from DomesticCat cat ) from DomesticCat as cat

where https://www.sodocs.net/doc/7b14688746.html, = some ( select name.nickName from Name as name )

from Cat as cat

where not exists ( from Cat as mate where mate.mate = cat )

from DomesticCat as cat

where https://www.sodocs.net/doc/7b14688746.html, not in ( select name.nickName from Name as name )

select cat.id, (select max(kit.weight) from cat.kitten kit)

from Cat as cat

?注意,HQL 自查询只可以在 select 或者 where 子句中出现。

(14)小技巧&小窍门

?你可以统计查询结果的数目而不必实际的返回他们:

( (Integer) session.createQuery("select count(*) from ....").iterate().next() )

.intValue() ?若想根据一个集合的大小来进行排序,可以使用如下的语句:

select usr.id, https://www.sodocs.net/doc/7b14688746.html,

from User as usr

left join usr.messages as msg

group by usr.id, https://www.sodocs.net/doc/7b14688746.html,

order by count(msg)

?如果你的数据库支持子选择,你可以在你的查询的 where 子句中为选择的大小(selection size)指定一个条件:

from User usr where size(usr.messages) >= 1

?如果你的数据库不支持子选择语句,使用下面的查询:

select usr.id, https://www.sodocs.net/doc/7b14688746.html,

from User usr

join usr.messages msg

group by usr.id, https://www.sodocs.net/doc/7b14688746.html,

having count(msg) >= 1

?因为内连接(inner join)的原因,这个解决方案不能返回含有零个信息的 User 类的实例,

所以这种情况下使用下面的格式将是有帮助的:

select usr.id, https://www.sodocs.net/doc/7b14688746.html,

from User as usr

left join usr.messages as msg

group by usr.id, https://www.sodocs.net/doc/7b14688746.html,

having count(msg) = 0

?JavaBean 的属性可以被绑定到一个命名查询(named query)的参数上:

Query q = s.createQuery(

"from foo Foo as foo where https://www.sodocs.net/doc/7b14688746.html,=:name and foo.size=:size");

q.setProperties(fooBean); // fooBean has getName() and getSize()

List foos = q.list();

?通过将接口 Query 与一个过滤器(filter)一起使用,集合(Collections)是可以分页的:Query q = s.createFilter( collection, "" ); // the trivial filter

q.setMaxResults(PAGE_SIZE);

q.setFirstResult(PAGE_SIZE * pageNumber);

List page = q.list();

?通过使用查询过滤器(query filter)可以将集合(Collection)的元素分组或排序:Collection orderedCollection = s.filter( collection, "order by this.amount" );

Collection counts = s.filter(

collection, "select this.type, count(this) group by this.type" );

(15)Row value构造函数语法

?HQL 支持 ANSI SQL row value constructor 语法(有时也叫作 tuple 语法),即使底层数据库可能不支持这个概念。在这里我们通常指的是多值(multi-valued)的比较,典型地是和组件相关联。来看看一个定义了 name 组件的实体 Person:

from Person p where https://www.sodocs.net/doc/7b14688746.html,.first='John' and https://www.sodocs.net/doc/7b14688746.html,st='Jingleheimer-Schmidt' ?那是有效的语法,虽然有点冗长。我们可以使它更加简洁一点,并使用 row value constructor 语法:

from Person p where https://www.sodocs.net/doc/7b14688746.html,=('John', 'Jingleheimer-Schmidt')

?在 select 子句里指定这个也是很有用的:

select https://www.sodocs.net/doc/7b14688746.html, from Person p

?当使用需要比较多个值的子查询时,采用 row value constructor 语法也很有用处:from Cat as cat

where not ( https://www.sodocs.net/doc/7b14688746.html,, cat.color ) in (

select https://www.sodocs.net/doc/7b14688746.html,, cat.color from DomesticCat cat )

?决定是否使用这个语法的一件因素就是:这个查询将依赖于元数据里的组件子属性(sub-properties)的顺序。

8.1+N问题

(1)1+N问题的产生

在Hibernate中,如果两个类设置了manyToOne之后,在查询的时候,由于N对1的一方默认的fetch=FetchType.EAGER,所以会把被关联的对象一起取出来。就会产生N条无关的select语句,影响数据库性能。

(2)1+N问题的解决

方式一:使用注解:设置fetch=https://www.sodocs.net/doc/7b14688746.html,ZY(在使用的时候才发出语句)

方式二:Join Fetch:将Many与One做外连接,因此只要发一条语句就可以查出Many与其相关联的One对象数据,Criteria默认就是这种做法。例如:

List topics= (List)session.createCriteria(Topic.class).list();

方式三:使用注解BatchSize,在One对象设置Size后,取出Many里的数据后,再发N/Size条语句取关联对象的数据,从而达到少发语句的目的。

9.缓存机制

(1)基本的缓存原理

Hibernate缓存分为二级,第一级存放于session中称为一级缓存,默认带有且不能卸载。第二级是由sessionFactory控制的进程级缓存。是全局共享的缓存,凡是会调用二级缓存的查询方法都会从中受益。只有经正确的配置后二级缓存才会发挥作用。同时在进行条件查询时必须使用相应的方法才能从缓存中获取数据。比如Query.iterate()方法、load、get方法等。必须注意的是session.find 方法永远是从数据库中获取数据,不会从二级缓存中获取数据,即便其中有其所需要的数据也是如此。

查询时使用缓存的实现过程为:首先查询一级缓存中是否具有需要的数据,如果没有,查询二级缓存,如果二级缓存中也没有,此时再执行查询数据库的工作。要注意的是:此3种方式的查询速度是依次降低的。

(2)存在的问题

?一级缓存的问题以及使用二级缓存的原因

因为Session的生命期往往很短,存在于Session内部的第一级最快缓存的生命期当然也很短,所以第一级缓存的命中率是很低的。其对系统性能的改善也是很有限的。当然,这个Session内部缓存的主要作用是保持Session内部数据状态同步。并非是hibernate为了大幅提高系统性能所提供的。

为了提高使用hibernate的性能,除了常规的一些需要注意的方法比如:使用延迟加载、迫切外连接、查询过滤等以外,还需要配置hibernate的二级缓存。其对系统整体性能的改善往往具有立竿见影的效果!

?1+N次查询的问题

执行条件查询时,iterate()方法具有著名的“n+1”次查询的问题,也就是说在第一次查询时iterate方法会执行满足条件的查询结果数再加一次(n+1)的查询。但是此问题只存在于第一次查询时,在后面执行相同查询时性能会得到极大的改善。此方法适合于查询数据量较大的业务数据。

但是注意:当数据量特别大时(比如流水线数据等)需要针对此持久化对象配置其具体的缓存策略,比如设置其存在于缓存中的最大记录数、缓存存在的时间等参数,以避免系统将大量的数据同时装载入内存中引起内存资源的迅速耗尽,反而降低系统的性能!!!

(3)使用hibernate二级缓存的其他注意事项

另外,hibernate会自行维护二级缓存中的数据,以保证缓存中的数据和数据库中的真实数据的一致性!无论何时,当你调用save()、update()或 saveOrUpdate()方法传递一个对象时,或使用load()、 get()、list()、iterate() 或scroll()方法获得一个对象时, 该对象都将被加入到Session 的内部缓存中。当随后flush()方法被调用时,对象的状态会和数据库取得同步。

也就是说删除、更新、增加数据的时候,同时更新缓存。当然这也包括二级缓存!只要是调用hibernate API执行数据库相关的工作。hibernate都会为你自动保证缓存数据的有效性!!但是,如果你使用了JDBC绕过hibernate直接执行对数据库的操作。此时,Hibernate不会(也不可能)自行感知到数据库被进行的变化改动,也就不能再保证缓存中数据的有效性!!这也是所有的ORM产品共同具有的问题。幸运的是,Hibernate为我们暴露了Cache的清除方法,这给我们提供了一个手动保证数据有效性的机会!!

一级缓存,二级缓存都有相应的清除方法。其中二级缓存提供的清除方法为:按对象class清空缓存。按对象class和对象的主键id清空缓存。清空对象的集合中的缓存数据等。

(4)二级缓存的适用情况

?并非所有的情况都适合于使用二级缓存,需要根据具体情况来决定。同时可以针对某一个持久化对象配置其具体的缓存策略。适合于使用二级缓存的情况:

?数据不会被第三方修改:一般情况下,会被hibernate以外修改的数据最好不要配置二级缓存,以免引起不一致的数据。但是如果此数据因为性能的原因需要被缓存,同时又有可能被第3方比如SQL 修改,也可以为其配置二级缓存。只是此时需要在sql执行修改后手动调用cache的清除方法。以保证数据的一致性

?数据大小在可接收范围之内:如果数据表数据量特别巨大,此时不适合于二级缓存。原因是缓存的数据量过大可能会引起内存资源紧张,反而降低性能。如果数据表数据量特别巨大,但是经常使用的往往只是较新的那部分数据。此时,也可为其配置二级缓存。但是必须单独配置其持久化类的缓存策略,比如最大缓存数、缓存过期时间等,将这些参数降低至一个合理的范围(太高会引起内存资源紧张,太低了缓存的意义不大)。

?数据更新频率低:对于更新频率过高的数据,频繁同步缓存中数据的代价可能与查询缓存中的数据从中获得的好处相当,坏处益处相抵消。此时缓存的意义也不大。

?非关键数据(不是财务数据等):财务数据等是非常重要的数据,绝对不允许出现或使用无效的数据,所以此时为了安全起见最好不要使用二级缓存。因为此时“正确性”的重要性远远大于“高性能”的重要性。

(5)一般系统中有三种情况会绕开hibernate执行数据库操作

?多个应用系统同时访问一个数据库:此种情况使用hibernate二级缓存会不可避免的造成数据不一致的问题,此时要进行详细的设计。比如在设计上避免对同一数据表的同时的写入操作,使用数据库各种级别的锁定机制等。

?动态表相关:所谓“动态表”是指在系统运行时根据用户的操作系统自动建立的数据表。比如“自定义表单”等属于用户自定义扩展开发性质的功能模块,因为此时数据表是运行时建立的,所以不能进行hibernate的映射。因此对它的操作只能是绕开hibernate的直接数据库JDBC操作。如果此时动态表中的数据没有设计缓存,就不存在数据不一致的问题。如果此时自行设计了缓存机制,则调用自己的缓存同步方法即可。

?使用sql对hibernate持久化对象表进行批量删除时:此时执行批量删除后,缓存中会存在已被删除的数据。分析:

当执行了sql批量删除后,后续的查询只可能是以下三种方式:

a. session.find()方法:根据前面的总结,find方法不会查询二级缓存的数据,而是直接查询

数据库。所以不存在数据有效性的问题。

b. 调用iterate方法执行条件查询时:根据iterate查询方法的执行方式,其每次都会到数据库

Hibernate学习入门教程

Hibernate学习入门教程 开发环境搭建 [日期:2015-08-11] 来源:Linux社区作者:doctorJoe [字体:大中小] 其实一两个月前就在了解Hibernate方面的知识了,但一直以来,都没有好好的总结,而且一直使用的是myeclipse,感觉有些傻瓜式的操作就可以搭建起Hibernate的开发环境,但这样一点都不好,没有理解到Hibernate到底是怎么配置的,所以你今天特使用Eclipse来一步一步搭建Hibernate的开发环境,下面,正式进入正题。 在Hibernate中开启日志https://www.sodocs.net/doc/7b14688746.html,/Linux/2015-07/120499.htm Hibernate+JUnit测试实体类生成数据库表https://www.sodocs.net/doc/7b14688746.html,/Linux/2015-07/120161. htm Hibernate整体理解https://www.sodocs.net/doc/7b14688746.html,/Linux/2014-07/104405.htm Hibernate的映射机制https://www.sodocs.net/doc/7b14688746.html,/Linux/2014-12/110265.htm 新建一个web项目,名字就随便吧,你喜欢什么名字就什么吧,这是我的截图。

引入hibernate的依赖jar包,我使用的是hibernate-release-4.3.10.Final,下载好后解压,打开压缩包下的lib目录下的require文件夹,这是hibernate的所以来的必须的jar包,接下来,在刚才新建的项目里新建一个libs文件夹,将刚才的所说的jar包copy进去,另外,由于我们需要连接MySQL数据库以及使用JUnit测试,将所需的mysql-connector-java-5.0.8-bin.jar和junit-4.5.jar两个jar包引用进去,关于这些jar包,可以在网上搜索。接下来,就是把这些jar 包添加到编译环境中去,选中libs下的jar包,右击选择Build Path –>Add to Build Path,这样就把依赖jar包成功添加进去了。 继续往下,我们需要配置最重要的hibernate配置文件hibernate.cfg.xml以及进行日志处理的log4j.properties属性文件:打开上一步解压后的hibernate文件夹,打开project—>etc文件夹,将该文件夹下的hibernate.cfg.xml和log4j.properties文件拷贝到项目的src文件夹下,打开hibernate.cfg.xml文件,将session-factory标签中的内容替换成如下的内容: org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql:///hibernatedemo root yzp140103 这样就配置好了。 接下来,要做的就是做开发测试了:在项目的src目录下新建一个实体类包com.joe.entity,在该包下新建一个实体类Student,代码如下: package com.joe.entity; import java.io.Serializable;

Hibernate学习笔记

Hibernate项目的构建与配置 1.在项目里倒入Hibernate所必须的Jar包 (1)Hibernate框架可以使用在任何的Java项目里,并不一定是Web项目。只需要在项目里 倒入Hibernate所必须要使用的jar包就可以了。 (2)在Hibernate的官网下载hibernate-release-4.2.2.Final.zip解压,要使用Hibernate 必须导入的jar包就在目录“hibernate-release-4.2.2.Final\lib\required”下。倒入此路径下的所有jar包就可以了。 2.配置hibernate.cfg.xml文件 (1)配置hibernate.cfg.xml文件可以参考“\project\etc”目录下的hibernate.cfg.xml 文件与hibernate.properties文件。 (2)使用Hibernate连接MySQL的hibernate.cfg.xml配置文件如下: (设置显示Hibernate产生的SQL语句) true (设置MySQL的SQL语法的方言) org.hibernate.dialect.MySQLDialect (设置MySQL的驱动程序) org.gjt.mm.mysql.Driver (设置MySQL的数据库路径、用户名、密码) jdbc:mysql:///java root lizhiwei (设置当数据库要保存的表不存在时,就新建表) update (设置对象与数据库表的关系映射文件) (3)此配置文件一般放在项目的src目录下。(注意:在项目中要加入MySQL的驱动jar包)3.编写实例类与对象-关系映射文件 (1)一个实例类对象就是数据库表里的一条记录,关系映射文件就指明了类的成员变量与数 据库字段间的关系以及该类对象保存在哪个表中。 (2)实例类User.java: public class User { private long id; private String name; private int age; private char sex; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { https://www.sodocs.net/doc/7b14688746.html, = name; }

MyEclipse+Hibernate+快速入门+中文版

提纲 1前言2准备工作3介绍4Hibernate 一览5创建HibernateDemo 项目 5创建HibernateDemo Java Project 5555使用模版调整生成更好的代码55编辑映射文件 6使用HQL 编辑器 7测试HibernateDemo 应用 8使用示例HibernateDemo 项目 9 总结1.前言 本文档基于以下环境编写:Sun JDK 1.5,Eclipse 3.2和MyEclipse 5.0.所有的截屏基于Eclipse,MyEclipse Enterprise Workbench,和Windows XP 的默认用户界面设置.如果你对本文档的介绍有阅读上的困难,请阅读用户反馈部分来了解如何向MyEclipse 文档团队提交反馈. 2.准备工作 下面是这个快速入门的准备工作列表: Java 2SDK,Standard Edition 1.4或者更高版本(参考来了解下载地址) Eclipse 3.2SDK (参考资源来了解下载地址) MyEclipse 5.0(参考资源来了解下载地址) 选择以下可以被Hibernate 和MyEclipse Database Explorer 所支持的数据库服务器列表中的一个 : MyEclipse Hibernate 快速入门中 文版

3.介绍 这个快速入门展示了使用MyEclipse Enterprise Workbench 开发Hibernate 的基本功能,概念和技术.我们将全程带领你来开发一个非常简单的Java Hibernate 应用.对于这个教程没有包含到的问题和概念,我们推荐你去参考资源部分列出的Hibernate 资源. 这个文档展示了如何进行下列工作: 为Java 项目添加MyEclipse Hibernate 支持 在项目中创建Hibernate 配置文件 如何使用自定义的Session Factory 从Database Explorer 的表定义中生成Java 类和Hibernate 数据库映射文件(.hbm ) ?使用HQL 编辑器 创建使用Hibernate 的小测试应用注意:在使用本教程时建议您事先阅读了Database Explorer 快速入门这个教程来了解如何创建连接和元数据功能. 4.Hibernate 一览 Hibernate 是一个非常流行的开源的易于配置和运行的基于Java 的对象-关系映射(JORM)引擎.它提供了很丰富的功能包括: 多种映射策略 可迁移的持久化 单个对象映射到多个表 支持集合 多态关联可自定义的SQL 查询 Axion Hypersonic DB InstantDB Interclient Firebird ODBC Bridge jTDS Mckoi Microsoft SQL Server Mimer SQL MySQL Oracle Pointbase PostgresQL SAPDB Sunopsis XML Sybase ThinkSQL

Hibernate知识的学习

Hibernate知识的学习 --------------------------------------------------第一章------------------------------------------------ 1、为什么用Hibernate呢? 他属于ORM中的一种;用来解决对象与关系模型不匹配的; ===用来解决对象与关系模型不匹配的{方法有两种:使用JDBC手工来操作;还有就是使用ORM来解决}; 学习Hibernate都要到那些包; Hibernate自动创建表; Hibernate测试类中应该怎样启动hibernate调用(主要是构造一个sessionFactory工厂,通过工厂来产生一个session对象,在通过session对象来对Hibernate操作数据库); --------------------------------------------------第二章------------------------------------------------ Hibernate的开发流程;(三点) Hibernate控制一个JavaBean时,应注意的JavaBean应该满足哪三点? --------------------------------------------------第三章------------------------------------------------ 做了一个简单的Hibernate的实例:其中编写了一个HibernateUtil.java文件来专门创建Session 对象的一个公共组件!Hibernate02实例中 --------------------------------------------------第四章------------------------------------------------ Hibernate中Session是最核心的接口,现在我们来学习一下: 通过session对象来完成增、删、改、查、的主要操作! 1.session对象的常用方法: save():添加一个对象,对应到表也就是添加一个信息; delete():删除一个对象,对应到表也就是删除一条信息; update():修改数据库信息,注意一点,当数据库没有信息时,会报出异常; get():根据id查询信息,会立刻访问数据库;【查询数据库时可以不打开事务操作】; Load():根据id查询信息,(返回的是代理,不会立即访问数据库【所以先不产生sql语句,而是当你真正的使用通过Load方法从数据库中去到的记录对象时才输出sql语句】也就是使用了懒加载机制 .如果在使用了Load方法了后,千万不要试图判断去到的对象是否为空值,因为load在这里将会产生出一个对应表JavaBean实体类的子类来处理的,相当于一个代理类的意味;通过user.getClass().getName()来获取这个代理类名称); saveOrUpdate()和merge方法:根据id和version的值来确定是save或update),【调用merge你的对象还是托管的】。【托管中用到了】 refresh():将数据重新读取一次! Lock()方法:查出一条数据,再给数据加一道锁【即为:把对象变成持久对象,但不会同步对象状态】 ------------------------------------------------------------------------------------------- 注意: 1、get和load方法获取数据库表中记录的区别; get():根据id查询信息,会立刻访问数据库;【查询数据库时可以不打开事务操作】; Load():根据id查询信息,(返回的是代理,不会立即访问数据库【所以先不产生sql语句,而是当你真正的使用通过Load方法从数据库中去到的记录对象时才输出sql语句】也就是使用了懒加载机制 .如果在使用了Load方法了后,千万不要试图判断去到的对象是否为空值,因为load在这里将会产生出一个对应表JavaBean实体类的子类来处理的,相当于一个代理类的意味;通过user.getClass().getName()来获取这个代理类名称);

MyEcLipse9.0配置TomCat和hiberhate学习笔记

MyEcLipse9.0配置TomCat和hibernate学习笔记 最近在学习Android,对于一个刚开始学习Android的人来说,配置开发环境就是个大问题,因为Android的企业级开发需要配置的环境不是那么容易的,特此将此笔记文档与大家共享,虽然可能有的朋友不知道我现在说的是什么,但对于一个想在编程方面继续发展的人来说,这是非常重要的 【1】采用标准的JA V A开发环境MyEclipse9.0(最新版) 【2】中间服务器采用入门级的TomCA T(绿色版,解压既能使用) 【3】Android的ADT插件采用Android2.3 【4】数据库采用轻量级的MySQL 【5】还需要JA V A的JDK 【6】还有Android虚拟机的SDK做支持 【7】开发工具,这里我就不上传了,因为群空间太小,就截个图算了,如果大家有兴趣搞Android开发的话,可以自己去网站下载 【8】开发工具有了,下面怎么把中间件服务器TomCat和数据库MySQL整合到MyEcLipse9.0中呢 <1>现将TomCat解压到C盘的ProgramFile文件夹下 <2>因为用的TomCat是绿色版的所以解压既能使用 在运行处敲cmd进入DOS窗口进入刚才装TomCat的目录

进入目录以后,我们要执行的是启动中间件服务器的组件 所以到 Bin下启动中间件服务器的批处理文件 如上图所示,启动startup.bat在bin目录下直接敲startup.bat,启动以后会如下图所示

可以看到启动信息和启动的时间,下面我们可以通过浏览器来查看我们的中间件服务器 在浏览器的地址栏上打 这里的localhost代表本地,也就是你自己的机器,也可以改成IP地址127.0.0.1也能代表本机,后面的8080是端口号,这里需要注意的是你的8080端口号必须没有被正用,否则得改端口号 运行效果如下图 这表示中间件服务器tomcat已经没有问题 【二】 安装MySQL数据库,这里就不截图了,需要注意的是,MYSQL的字符集,因为要开发基于中文的软件,所以一般选择MYSQL的字符集为UTF-8,还有配置MSQL的时候端口为:3306.用户名和我们的LINUX用户名一样,都是root密码可以自定义,这些不要选错,MYSQL

马士兵hibernate学习笔记(原版)-你信不信,我反正是信了

马士兵hibernate学习笔记 课程内容 (6) 1HelloWorld (6) 2Hibernate原理模拟 - 什么是O/R Mapping以及为什么要有O/R Mapping (6) 3常见的0/R框架(了解) (6) 4hibernate基础配置(重点) (6) 5ID生成策略(重点 AUTO) (6) 6Hibernate核心开发接口介绍(重点) (6) 7对象的三种状态(了解) (6) 8关系映射(重点) (6) 9Hibernate査询(HQL) (6) 10在Struts基础上继续完善BBS200 (6) 11性能优化(重点) (6) 12补充话题 (6) 风格 (6) 1先脉络,后细节 (6) 2先操作,后原理 (6) 3重Annotation,轻xml配置文件 (6) 资源 (6) 1http://www. https://www.sodocs.net/doc/7b14688746.html, (6) 2hibernate zh_CN文档 (6) 3hibernate annotation references (6) 环境准备 (6) 1下载hibernate-distribution-3.3.2.GA-dist (6) 2下载hibernate-annotations-3[1].4.0.GA (6) 3注意阅读hibernate compatibility matrix(hibernate 网站download) (6) 4下载slf4jl.5.8 (7) Hibernate HelloWorld (7) 1建立新java 项目,名为hibernate_0100_HelloWorld (7) 2学习建User-library-hibernate,并加入相应的jar包 (7) 3引入mysql的JDBC驱动包 (7) 4在mysql中建立对应的数据库以及表 (7) 5建立hibernate 配置文件hibernate.cfg.xml (7) 6建立Student 类 (7) 7建立Student 映射文件 Student.hbm.xml (7)

(最新)JSF+Spring+Hibernate的实例讲解

JSF+Spring+Hibernate的实例讲解 使用JSF建立一个真实的Web应用程序不是没有意义的任务,这篇文章介绍了如何将JSF与Sping Framework和Hibernate集成,并且给出了使用这些技术建立这个真实的Web应用程序的最佳实践和设计指导 JavaServer Faces(JSF)技术是J2EE应用程序的一个新的用户接口框架,它非常适合基于 MVC(Model-View-Controller)体系结构的应用程序。已经有大量的文章介绍JSF。然而,很多文章都是站在理论研究的层面上,没有挑战一个真实的企业开发。很多问题没有解决,例如,JSF怎样全面适合MVC体系结构?JSF如何与其他JAVA框架集成?业务逻辑应该放在JSF的backing beans里面吗?怎样处理JSF里面的安全问题?最重要的是你怎样使用JSF建立一个真实的Web应用程序? 这篇文章涉及所有这些问题。它向你展示如何集成其他特定的Java框架,Spring Framework和Hibernate,它示范怎样去创建一个叫JCatalog的Web应用程序,一个在线的产品目录系统。这篇文章使用JCatalog例子,介绍了Web应用程序设计的每一个阶段,包括业务需求收集,分析,技术选择,高层体系结构和详细设计。这篇文章论述了JCatalog里面好的和不好的技术,示范了应用程序设计中一些关键方面的方法和步骤。 这篇文章是写给正在从事基于J2EE Web应用程序的Java架构师,开发者,它不是对JSF、Spring Framework和Hibernate的入门教程。如果您对这些领域不熟悉,请参考文章最后的资源链接。 例子应用程序的功能需求 这篇文章的例子应用程序JCatalog是一个真实的Web应用程序,例子足够现实是为了决定应用程序架构而进行意味深长的讨论的基础。我通过介绍JCatalog项目的需求开始。我在这里谈到后面贯穿于整个文章的内容是为了演示技术选择和体系结构设计。 设计Web应用程序的第一步是收集系统的功能需求,这个例子应用程序是一个典型的电子商务应用系统。用户能浏览产品目录和查看产品细节,管理员能管理产品目录。功能还可以增加,举例来说,为了开发一个成熟的电子商务系统,可以添加库存管理和订单处理的功能。 用例 用例分析被用于去访问例子应用程序的功能需求,图1是应用程序的用例图。

传智播客Spring25视频教程学习笔记

传智播客Spring2.5视频教程学习笔记1.全面阐释Spring及其各项功能 1.1Spring是什么? Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架.它的主要目得是简化企业开发。 1.2IoC控制反转 所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。 1.3依赖注入(DI:Dependicy Injection) 所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。 1.4面向切面(AOP) 1.5为什么要使用Spring 解耦(各层之间通过接口调用) 提供事务、消息服务 单例模式 AOP支持 辅助类(JDBCTemplate,HibernateTemplate) 支持与Struts,Hibernate,JPA等框架的集成 1.6实例化bean的方式 构造函数(90%使用),静态工厂方法,实例工厂方法 1.使用类构造器实例化 2.使用静态工厂方法实例化 public class OrderFactory { public static OrderServiceBean createOrder(){ return new OrderServiceBean(); } } 3.使用实例工厂方法实例化 public class OrderFactory { public OrderServiceBean createOrder(){ return new OrderServiceBean(); } }

struts2+spring3+hibernate整合教程

Struts2+Spring3+hibernate3整合 (2011年7月末,最新) 上次下载了一个教程,上面写着:“献给我亲爱的老婆!”(羡慕不已)。想了想,我没老婆,难道没什么好写了!不难… 献给我暗恋过的每一个女人!(嘿嘿…) 如果在你遇到的女生中有一个幽默豁达的女生,不要犹豫,追上去,就娶她了!

一,需要的框架包 二,建立project,添加相应的.jar文件(重点) 1,eclipse中建立dynamic web project,这里是ssh_integrate_0100。 2,src中创建需要的类,这里以一个域模型为user的例子说明。(现在建立这些类,可以方便我们在搭建时候随时测试!) User.java IUserDao.java

UserDaoImpl.java IUserService.java UserServiceImpl.java

3,拷贝spring-framework-3.1.0\dist目录下的所有jar包,注意有一个不是jar的文件,当然拷过去也没事。 4,拷贝spring运行中需要的其他jar文件,主要是 https://www.sodocs.net/doc/7b14688746.html,mons-logging,可以从spring-framework-3.0.2.RELEASE-dependencies 中找到。 ii.Aspectjrt.jar和aspect-waver.jar,可以从spring-framework-2.5.6-with-dependencies/lib/aspectj下面找到(不知道为什 么,spring-framework-3.0.2.RELEASE-dependencies中没有aspectjrt的jar 包) iii.aopalliance.Jar,apache-dbcp.jar,apache-pool.jar,可以从spring-framework-3.0.2.RELEASE-dependencies中找到。 5,建立beans.xml,这里使用的是annotation和component-scan,这样配置可以大大简化配置,所以是best-practice,其他配置请参考spring文档。

Java相关课程系列笔记之十四Hibernate学习笔记(建议用WPS打开)

! Hibernate学习笔记 Java相关课程系列笔记之十四

笔记内容说明 Hibernate(梁建全老师主讲,占笔记内容100%);

目录 一、 Hibernate的概述 0 Hibernate框架的作用 0 Hibernate访问数据库的优点 0 JDBC访问数据库的缺点 0 Hibernate的设计思想 0 二、 Hibernate的基本使用 (1) Hibernate的主要结构 (1) Hibernate主要的API (1) Hibernate使用步骤 (1) HQL语句(简要介绍) (3) 三、数据映射类型 (3) 映射类型的作用 (3) type映射类型的两种写法 (3) 四、 Hibernate主键生成方式 (3) 五种生成方式 (3) 五、 Hibernate基本特性 (4) 对象持久性 (4) 处于持久状态的对象具有的特点 (4) 三种状态下的对象的转换 (4) 批量操作:注意及时清除缓存 (4) 案例:三种状态下的对象使用 (4) 一级缓存机制(默认开启) (4) 一级缓存的好处 (4) 管理一级缓存的方法 (4) 延迟加载机制 (4) 具有延迟加载机制的操作 (4) 常犯的错误 (4) 延迟加载的原理 (4) Session的get和load方法的区别 (4) 延迟加载的好处 (5) 案例:测试延迟加载 (5) 案例:重构NetCTOSS资费管理模块 (5) Java Web程序中如何用延迟加载操作(OpenSessionInView) (5) 六、关联映射 (5) 一对多关系one-to-many (5) 多对一关系many-to-one (5) 多对多关联映射many-to-many (5) 关联操作(查询join fetch/级联cascade) (5) 继承关系映射 (5) 七、 Hibernate查询方法 (6) HQL查询 (6) HQL和SQL的相同点 (6)

SpringMvc学习笔记(二)通过实例学习注解式控制器

Springmvc学习笔记(二) 通过实例学习注解式控制器 一、注解式控制器简介 Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类。Spring2.5之后引入注解式处理器支持,通过@Controller 和@RequestMapping注解定义我们的处理器类。 通过笔记(一)的例子,我们已经初步认识了基于注解的控制器实现方式。下面我们来详细介绍一下注解式控制器运行流程与使用方法。 @Controller:用于标识是处理器类; @RequestMapping:请求到处理器功能方法的映射规则; @RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定; @ModelAttribute:请求参数到命令对象的绑定; @SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中; @CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定; @RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定; @RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换); @ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换); @ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因; @ExceptionHandler:注解式声明异常处理器; @PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;

(完整版)SSH框架搭建实例教程,毕业课程设计

. SSH的理解及其应用实践

1.SSH是什么 (3) 2 Spring 介绍理解: (3) 2.1简单介绍 (3) 2.2各种特性 (3) 2.2.1轻量 (3) 2.2.2控制反转 (3) 2.2.3面向切面 (4) 2 .2.4容器 (4) 2.2.5框架 (4) 2.3总结 (4) 3.Hibernate介绍理解: (4) 3.1简单介绍 (4) 3.2核心接口 (5) .3.2.1 Session接口 (5) 3.2.2 .SessionFactory接口 (5) 3.2.3.Configuration接口 (5) 3.2.4.Transaction接口 (5) 3.2.5 Query和Criteria接口 (5)

4. Struts (6) 4.1什么是Struts框架 (6) 4.2 Struts 概览 (6) 4.2.1Client browser(客户浏览器) (6) 4.4 Struts中的Controller(控制器)命令设计模式的实现 (7) 4.5 在Struts框架中控制器组件的三个构成部分 (7) 4.7 Struts中的Model(模型) (8) 5.SSH整合步骤 (8) 5.1安装所需软件环境: (8) 5.1.1、首先安装JDK,配置Java环境变量 (8) 5.1.2安装MyEelipse (8) 5.1.3 数据库 (9) 5.1.4、 (9) 5.2环境配置好了就可以做SSH整合的项目 (9) 6.搭建框架并简单应用 (11) 6.1准备工作 (11) 6.2(建立项目,包结构,导入所需jar文件) (12) 6.3撰写资源文件 (15) 6.4在com.ssh.utilm 包下添加下列文件 (19) 6.5添加hibernate DAO 模板 (20) 6.6以上的工作还不够,我们还需要进行WEB方面的配置 (20) 7.测试: (23) 7.1.ssh.model 包下建立User.java (23) 7.2 com.ssh.service 包下建立UserService.java (24) 7.3com.ssh.test 下建立Test.java (25)

hibernate教程

一、使用Hibernate的3个准备和7个步骤 准备1:导入Hibernate库(jar包); 准备2:添加配置文件-Hibernate.cfg.xml jdbc:microsoft:sqlserver://localhost:1433;Database=zf sa pwd com.microsoft.jdbc.sqlserver.SQLServerDriver #配置数据库链接 org.hibernate.dialect.SQLServerDialect #数据库方言 true #设置运行时是否在控制台显示SQL语句 #映射文件,可以有多个 准备3:添加实体类和映射文件(User.hbm.xml) 类: public class User implements java.io.Serializable { //要实现Serializable private Integer uid; private String uname; private String upass; public User(){// 要有默认构造方法 } // Getter and setter } User.hbm.xml: 列名

hibernate学习笔记

第一次课: 持久化:就是把瞬时状态的数据转变为持久化状态的数据,这一个过程就是持久化。 (java中内存分为:栈(变量,方法,形参都是在栈上),堆(new出来的对象在堆上)) 1)瞬时状态:刚new出来,在内存中存在的对象就是瞬时状态的。如果程序结束,对象就会被回收。 2)持久化状态:在磁盘或者是数据库中存在的数据就是持久状态。 Hibernate是什么? 1)是一个优秀的持久化框架,对jdbc进行进一步的封装。(hibernate,ibatis )。 2)是一个ORM (Object relation mapping ). Mysql,oracle,access 是关系型数据库 = hibernate操作的是对象。 使用hibernate的步骤:1)新建项目 2)引入jar包(hibernate最少依赖8个jar包) 3)新建 hibernate配置文件(hibernate.cfg.xml) ,放在src根目录下面。 用于数据库的配置信息。 com.mysql.jdbc.Driver root abc jdbc:mysql:///fwcz org.hibernate.dialect.MySQLDialect create 4)写bean/vo类,并且编写映射文件。

Hibernate学习笔记

1、session = HibernateSessionFactory.getSession();// 开启连接 Transaction tx = session.beginTransaction(); // 开启事务 Student stu = (Student) session.get(Student.class, id); session.delete(stu); https://www.sodocs.net/doc/7b14688746.html,mit(); 2、session.save(stu); 3、Query q = session.createQuery("from Student"); list = q.list(); 4、session.update(stu); 5、url:jdbc:mysql://localhost:3306/HibernateProject01 Driver:com.mysql.jdbc.Driver 6、在src源码包中新建log4j.properties log4j.rootLogger=info,CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Target=System.out https://www.sodocs.net/doc/7b14688746.html,yout=org.apache.log4j.PatternLayout https://www.sodocs.net/doc/7b14688746.html,yout.ConversionPattern= %4p[%t](%F:%L) -%m%n 7、 8、session = HibernateUtil.currentSession(); // 开启连接 session.setFlushMode(FlushMode.AUTO); tx = session.beginTransaction(); // 开启事务 stu = (Student) session.get(Student.class, "ff80808105416d"); https://www.sodocs.net/doc/7b14688746.html,mit(); 9、one-to-one和many-to-one中,lazy只可以为false,或不填写 当不填写的时候,采用相应的类里的设置 Set标签是可以的 10、outer-join="true"预先抓取,sql文中是利用连接来实现 常常与hibernate.cfg.xml中的 1 一起使用 11、批量立即加载 在实现上,采用where s.team_id in (?, ?)的形式 12、stu = (Student)session.get(Student.class,"ff80808105416d30001"); stu.setCardId("456"); // 对脱管对象进行更改

Struts2+Hibernate架构教程课后参考答案

第1章 Struts2框架技术入门 1.5 习题 1.5.1 选择题 1.D 2.A 3.C 4.B 5.B 1.5.2 填空题 1.MVC 2.Struts1和WebWork 3.IBM 4.FilterDispatcher 5.JSP、Struts2标签 1.5.3 简答题 1.简述MVC设计模式的工作流程。 答:MVC设计模式工作流程是: (1)用户的请求

相关主题