4.2 Hibernate应用基础
2016-02-29 00:00
204 查看
摘要: Hibernate应用实例开发、Hibernate主要文件、Hibernate核心接口、HQL
1)建立数据库及表
本书使用SQL Server 2005数据库。在XSCJ数据库中建立KCB表。
表名:KCB
填写要建立的连接的名称“MyConn”(自定义),连接数据库的URL“jdbc:sqlserver://localhost:1433;databaseName=XSCJ”,填写数据库的用户名和密码。添加数据库驱动。
![](http://static.oschina.net/uploads/space/2016/0229/120600_x3K2_220508.png)
图4.2 MyEclipse Database浏览器,创建一个新的连接
![](http://static.oschina.net/uploads/space/2016/0229/120627_Piaz_220508.png)
图4.3 编辑数据库连接驱动
编辑完成以后,在MyEclipse Database浏览器中,右击刚才创建的MyConn数据库连接,选择“Open connection…”菜单项,打开名为“MyConn”的数据连接,如图4.4所示。
![](http://static.oschina.net/uploads/space/2016/0229/120627_14Cv_220508.png)
图4.4 打开数据库连接
![](http://static.oschina.net/uploads/space/2016/0229/120627_xvF5_220508.png)
图4.5 选择Hibernate版本及所需Jar包
单击【Next】按钮,进入如图4.6所示界面。创建Hibernate配置文件hibernate.cfg.xml,将该文件放在src文件夹下,后面会详细介绍该文件内容。这里先说明添加Hibernate开发功能的步骤。
![](http://static.oschina.net/uploads/space/2016/0229/120627_DSD1_220508.png)
图4.6 创建配置文件hibernate.cfg.xml
单击【Next】按钮,进入如图4.7所示界面,指定Hibernate数据库连接细节。由于在前面已经配置一个名为MyConn的数据库连接,所以这里只需要选择DB Driver为“MyConn”即可。
![](http://static.oschina.net/uploads/space/2016/0229/120627_i7HJ_220508.png)
图4.7 指定hibernate数据库连接
单击【Next】按钮,出现如图4.8所示界面。Hibernate中有一个与数据库打交道重要的类Session。而这个类是由工厂SessionFactory创建的。这个界面询问是否需要创建SessionFactory类。如果需要创建,还需要指定创建的位置和类名。这些接口都会在后面详细介绍。单击【Finish】按钮,完成Hibernate的配置。
![](http://static.oschina.net/uploads/space/2016/0229/120627_Pket_220508.png)
图4.8 创建SessionFactory类来简化Hibernate会话处理
打开MyEclipse Database Explorer视图。打开前面创建的MyConn数据连接,选择【XSCJ】→【dbo】→【TABLE】菜单项,右击KCB表,选择【Hibernate Reverse Engineering…】菜单项,如图4.9所示,将启动Hibernate Reverse Engineering向导,该向导用于完成从已有的数据库表生成对应的Java类和相关映像文件的配置工作。
![](http://static.oschina.net/uploads/space/2016/0229/120628_eZe8_220508.png)
图4.9 Hibernate反向工程菜单
首先,选择生成的Java类和映像文件所在的位置,如图4.10所示。POJO(Plain Old Java Object,简单的Java对象),通常也称为VO(Value Object,值对象)。 使用POJO名称是为了避免和EJB混淆起来,其中有一些属性及getter、setter方法。当然,如果有一个简单的运算属性也是可以的,但不允许有业务方法。
![](http://static.oschina.net/uploads/space/2016/0229/120628_rMaA_220508.png)
图4.10 生成Hibernate映射文件和Java类
单击【Next】按钮,进入如图4.11所示的界面,选择主键生成策略。
![](http://static.oschina.net/uploads/space/2016/0229/120628_AzXF_220508.png)
图4.11 配置反向工程细节
点击【Finish】,org.model包中会出现Kcb.java类和Kcb.hbm.xml。然后在hibernate.cfg.xml文件中配置映射文件<mapping resource="org/model/Kcb.hbm.xml"/>,该语句放在<session-factory>和</session-factory>之间。
可以发现,该类中的属性和表中的字段是一一对应的。那么通过什么方法把它们一一映射起来呢?就是前面提到的*.hbm.xml映射文件。这里当然就是Kcb.hbm.xml。
该配置文件大致分为3个部分:
(1)类、表映射配置
name属性指定POJO类为org.model.Kcb,table属性指定当前类对应数据库表KCB。
(2)id映射配置
id节点定义实体类的标志(assigned),在这里也就是对应数据库表主键的类属性。<generator class="assigned" />指定主键的生成方式。
Hibernate的主键生成策略分为三大类:Hibernate对主键id赋值、应用程序自身对id赋值、由数据库对id赋值。
assigned:应用程序自身对id赋值。当设置<generator class="assigned"/>时,应用程序自身需要负责主键id的赋值。例如下述代码:
native:由数据库对id赋值。当设置<generator class="native"/>时,数据库负责主键id的赋值,最常见的是int型的自增型主键。
hilo:通过hi/lo算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
seqhilo:与hi/lo类似,通过hi/lo算法实现的主键生成机制,只是主键历史状态保存在sequence中,适用于支持sequence的数据库,如Oracle。
increment:主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。当有多个实例访问同一数据库时,可能造成主键重复异常。
identity:采用数据库提供的主键生成机制,如SQL Server、MySQL中的自增主键生成机制。
sequence:采用数据库提供的sequence机制生成主键,如Oracle sequence。
uuid.hex:由Hibernate基于128位唯一值产生算法,根据当前设备IP、时间、JVM启动时间、内部自增量等4个参数生成十六进制数值(编码后长度为32位的字符串表示)作为主键。即使是在多实例并发运行的情况下,这种算法在最大程度上保证了产生id的唯一性。当然,重复的概率在理论上依然存在,只是概率比较小。
uuid.string:与uuid.hex类似,只是对生成的主键进行编码(长度16位)。
foreign:使用外部表的字段作为主键。
select:Hibernate 3新引入的主键生成机制,主要针对遗留系统的改造工程。
(3)属性、字段映射配置
属性、字段映射将映射类属性与库表字段相关联。
name="kcm" 指定映像类中的属性名为“kcm”,此属性将被映像到指定的库表字段KCM。type="java.lang.String"指定映像字段的数据类型。column name="KCM"指定类的kcm属性映射KCB表中的KCM字段。
Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需要的各种属性。Hibernate初始化期间会自动在CLASSPATH中寻找这个文件,并读取其中的配置信息,为后期数据库操作做好准备。
在Hibernate中,Session负责完成对象持久化操作。该文件负责创建Session对象,以及关闭Session对象。从该文件可以看出,Session对象的创建大致需要以下3个步骤:
① 初始化Hibernate配置管理类Configuration。
② 通过Configuration类实例创建Session的工厂类SessionFactory。
③ 通过SessionFactory得到Session实例。
使用Hibernate必须首先提供这些基础信息以完成初始化工作,为后续操作做好准备。这些属性在Hibernate配置文件hibernate.cfg.xml中加以设定,当调用:
时,Hibernate会自动在目录下搜索hibernate.cfg.xml文件,并将其读取到内存中作为后续操作的基础配置。
Configuration实例config会根据当前的数据库配置信息,构造SessionFacory实例并返回。SessionFactory一旦构造完毕,即被赋予特定的配置信息。就是说,之后config的任何变更将不会影响到已经创建的SessionFactory实例sessionFactory。如果需要使用基于变更后的config实例的SessionFactory,需要从config重新构建一个SessionFactory实例。如果需要访问多个数据库,针对每个数据库,应分别创建其对应的SessionFactory实例。
SessionFactory保存了对应当前数据库配置的所有映射关系,同时也负责维护当前的二级数据缓存和Statement Pool。由此可见,SessionFactory的创建过程非常复杂、代价高昂。这也意味着,在系统设计中充分考虑到SessionFactory的重用策略。由于SessionFactory采用了线程安全的设计,可由多个线程并发调用。大多数情况下,针对一个数据库共享一个SessionFactory实例即可。
同时,值得注意的是,Hibernate Session的设计是非线程安全的,即一个Session实例同时只可由一个线程使用。同一个Session实例的多线程并发调用将导致难以预知的错误。
Session实例由SessionFactory构建:
上面是直接给出查询条件的值,也可以是设参数,例如以下语句:
就要在后面设置其值:
上面的方法是通过“?”来设置参数,还可以用“:”后跟变量的方法来设置参数,如上例可以改为:
由于上例中kch为String类型,所以要用setString(),如果是int型,就要用setInt()。通用的方法是setParameter()方法,不管是什么类型的参数都可以。其使用方法是相同的,例如:
Query还有一个list()方法,用于取得一个List集合的示例,此示例中包括可能是一个Object集合,也可能是Object数组集合。例如:
HQL常用的几种查询方式:
(1)查询所有课程信息
(2)查询某门课程信息
(3)查询满足条件的课程信息
(1)按指定参数查询
(2)使用范围运算查询
(3)使用比较运算符查询
(4)使用字符串匹配运算查询
附:目录《JavaEE基础实用教程》笔记说明
1.Hibernate应用实例开发
1)建立数据库及表
本书使用SQL Server 2005数据库。在XSCJ数据库中建立KCB表。表名:KCB
项目名 | 列名 | 数据类型 | 是否可空 | 默认值 | 说明 |
课程号 | KCH | char(3) | 主键 | ||
课程名 | KCM | char(20) | 是 | ||
开学学期 | KXXQ | smallint | 是 | 只能为1-8 | |
学时 | XS | int | 是 | 0 | |
学分 | XF | int | 是 | 0 |
2)在MyEclipse中创建对SQL Server 的连接
启动MyEclipse,选择【Window】→【Open Perspective】→【MyEclipse Database Explorer】菜单项,打开MyEclipse Database浏览器,右击菜单,如图4.2所示,选择【New…】菜单项,出现如图4.3所示的对话框,编辑数据库连接驱动。填写要建立的连接的名称“MyConn”(自定义),连接数据库的URL“jdbc:sqlserver://localhost:1433;databaseName=XSCJ”,填写数据库的用户名和密码。添加数据库驱动。
![](http://static.oschina.net/uploads/space/2016/0229/120600_x3K2_220508.png)
图4.2 MyEclipse Database浏览器,创建一个新的连接
![](http://static.oschina.net/uploads/space/2016/0229/120627_Piaz_220508.png)
图4.3 编辑数据库连接驱动
编辑完成以后,在MyEclipse Database浏览器中,右击刚才创建的MyConn数据库连接,选择“Open connection…”菜单项,打开名为“MyConn”的数据连接,如图4.4所示。
![](http://static.oschina.net/uploads/space/2016/0229/120627_14Cv_220508.png)
图4.4 打开数据库连接
3)创建Web项目,命名为“HibernateTest”
4)添加Hibernate开发能力
右击项目名HibernateTest,选择【MyEclipse】→【Add Hibernate Capabilites】菜单项,出现如图4.5所示的对话框,选择Hibernate框架应用版本及所需要的类库。![](http://static.oschina.net/uploads/space/2016/0229/120627_xvF5_220508.png)
图4.5 选择Hibernate版本及所需Jar包
单击【Next】按钮,进入如图4.6所示界面。创建Hibernate配置文件hibernate.cfg.xml,将该文件放在src文件夹下,后面会详细介绍该文件内容。这里先说明添加Hibernate开发功能的步骤。
![](http://static.oschina.net/uploads/space/2016/0229/120627_DSD1_220508.png)
图4.6 创建配置文件hibernate.cfg.xml
单击【Next】按钮,进入如图4.7所示界面,指定Hibernate数据库连接细节。由于在前面已经配置一个名为MyConn的数据库连接,所以这里只需要选择DB Driver为“MyConn”即可。
![](http://static.oschina.net/uploads/space/2016/0229/120627_i7HJ_220508.png)
图4.7 指定hibernate数据库连接
单击【Next】按钮,出现如图4.8所示界面。Hibernate中有一个与数据库打交道重要的类Session。而这个类是由工厂SessionFactory创建的。这个界面询问是否需要创建SessionFactory类。如果需要创建,还需要指定创建的位置和类名。这些接口都会在后面详细介绍。单击【Finish】按钮,完成Hibernate的配置。
![](http://static.oschina.net/uploads/space/2016/0229/120627_Pket_220508.png)
图4.8 创建SessionFactory类来简化Hibernate会话处理
5)生成数据库表对应的Java类对象和映射文件
首先在MyEclispse下创建一个名为“org.model”的包,这个包将用来存放与数据库表对应的Java类POJO。打开MyEclipse Database Explorer视图。打开前面创建的MyConn数据连接,选择【XSCJ】→【dbo】→【TABLE】菜单项,右击KCB表,选择【Hibernate Reverse Engineering…】菜单项,如图4.9所示,将启动Hibernate Reverse Engineering向导,该向导用于完成从已有的数据库表生成对应的Java类和相关映像文件的配置工作。
![](http://static.oschina.net/uploads/space/2016/0229/120628_eZe8_220508.png)
图4.9 Hibernate反向工程菜单
首先,选择生成的Java类和映像文件所在的位置,如图4.10所示。POJO(Plain Old Java Object,简单的Java对象),通常也称为VO(Value Object,值对象)。 使用POJO名称是为了避免和EJB混淆起来,其中有一些属性及getter、setter方法。当然,如果有一个简单的运算属性也是可以的,但不允许有业务方法。
![](http://static.oschina.net/uploads/space/2016/0229/120628_rMaA_220508.png)
图4.10 生成Hibernate映射文件和Java类
单击【Next】按钮,进入如图4.11所示的界面,选择主键生成策略。
![](http://static.oschina.net/uploads/space/2016/0229/120628_AzXF_220508.png)
图4.11 配置反向工程细节
点击【Finish】,org.model包中会出现Kcb.java类和Kcb.hbm.xml。然后在hibernate.cfg.xml文件中配置映射文件<mapping resource="org/model/Kcb.hbm.xml"/>,该语句放在<session-factory>和</session-factory>之间。
6)创建测试类
在src文件夹下创建包test,在该包下建立测试类,命名为Test.java,其代码。package test; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.model.Kcb; import org.util.HibernateSessionFactory; public class Test { public static void main(String[] args) { // 调用HibernateSessionFactory的getSession方法创建Session对象 Session session = HibernateSessionFactory.getSession(); // 创建事务对象 Transaction ts = session.beginTransaction(); Kcb kc = new Kcb(); // 创建POJO类对象 kc.setKch("198"); // 设置课程号 kc.setKcm("机电"); // 设置课程名 kc.setKxxq(new Short((short) 5)); // 设置开学学期 kc.setXf(new Integer(5)); // 设置学分 kc.setXs(new Integer(59)); // 设置学时 // 保存对象 session.save(kc); ts.commit(); // 提交事务 Query query = session.createQuery("from Kcb where kch=198"); List list = query.list(); Kcb kc1 = (Kcb) list.get(0); System.out.println(kc1.getKcm()); HibernateSessionFactory.closeSession(); // 关闭Session } }
7)运行
因为该程序为Java Application,所以可以直接运行。运行程序,控制台就会打印出“机电”。在完全没有操作数据库的情况下,就完成了对数据的插入。下面将详细讲解各文件的作用。2.Hibernate各种文件的作用
1)POJO类和其映射配置文件
POJO类如下:package org.model; public class Kcb implements java.io.Serializable { private String kch; // 对应表中KCH字段 private String kcm; // 对应表中KCM字段 private Short kxxq; // 对应表中KXXQ字段 private Integer xs; // 对应表中XS字段 private Integer xf; // 对应表中XF字段 public Kcb() { } // 上述属性的getter和setter方法 }
可以发现,该类中的属性和表中的字段是一一对应的。那么通过什么方法把它们一一映射起来呢?就是前面提到的*.hbm.xml映射文件。这里当然就是Kcb.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> <!-- name指定POJO类,table指定对应数据库的表 --> <class name="org.model.Kcb" table="KCB"> <!-- name指定主键,type主键类型 --> <id name="kch" type="java.lang.String"> <column length="3" name="KCH"/> <!-- 主键生成策略 --> <generator class="assigned"/> </id> <!-- POJO属性及表中字段的对应 --> <property name="kcm" type="java.lang.String"> <column length="12" name="KCM"/> </property> <property name="kxxq" type="java.lang.Short"> <column name="KXXQ"/> </property> <property name="xs" type="java.lang.Integer"> <column name="XS"/> </property> <property name="xf" type="java.lang.Integer"> <column name="XF"/> </property> </class> </hibernate-mapping>
该配置文件大致分为3个部分:
(1)类、表映射配置
<class name="org.model.Kcb" table="KCB">
name属性指定POJO类为org.model.Kcb,table属性指定当前类对应数据库表KCB。
(2)id映射配置
<id name="kch" type="java.lang.String"> <column name="KCH" length="3" /> <generator class="assigned" /> </id>
id节点定义实体类的标志(assigned),在这里也就是对应数据库表主键的类属性。<generator class="assigned" />指定主键的生成方式。
Hibernate的主键生成策略分为三大类:Hibernate对主键id赋值、应用程序自身对id赋值、由数据库对id赋值。
assigned:应用程序自身对id赋值。当设置<generator class="assigned"/>时,应用程序自身需要负责主键id的赋值。例如下述代码:
Kcb kc=new Kcb(); // 创建POJO类对象 kc.setKch("198"); // 设置课程号 kc.setKcm("机电"); // 设置课程名 kc.setKxxq(new Integer(5).shortValue()); // 设置开学学期 kc.setXf(new Integer(4).shortValue()); // 设置学分 kc.setXs(new Integer(59).shortValue()); // 设置学时
native:由数据库对id赋值。当设置<generator class="native"/>时,数据库负责主键id的赋值,最常见的是int型的自增型主键。
hilo:通过hi/lo算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
seqhilo:与hi/lo类似,通过hi/lo算法实现的主键生成机制,只是主键历史状态保存在sequence中,适用于支持sequence的数据库,如Oracle。
increment:主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。当有多个实例访问同一数据库时,可能造成主键重复异常。
identity:采用数据库提供的主键生成机制,如SQL Server、MySQL中的自增主键生成机制。
sequence:采用数据库提供的sequence机制生成主键,如Oracle sequence。
uuid.hex:由Hibernate基于128位唯一值产生算法,根据当前设备IP、时间、JVM启动时间、内部自增量等4个参数生成十六进制数值(编码后长度为32位的字符串表示)作为主键。即使是在多实例并发运行的情况下,这种算法在最大程度上保证了产生id的唯一性。当然,重复的概率在理论上依然存在,只是概率比较小。
uuid.string:与uuid.hex类似,只是对生成的主键进行编码(长度16位)。
foreign:使用外部表的字段作为主键。
select:Hibernate 3新引入的主键生成机制,主要针对遗留系统的改造工程。
(3)属性、字段映射配置
属性、字段映射将映射类属性与库表字段相关联。
<property name="kcm" type="java.lang.String"> <column name="KCM" length="12" /> </property>
name="kcm" 指定映像类中的属性名为“kcm”,此属性将被映像到指定的库表字段KCM。type="java.lang.String"指定映像字段的数据类型。column name="KCM"指定类的kcm属性映射KCB表中的KCM字段。
2)hibernate.cfg.xml文件
该文件是Hibernate重要的配置文件,配置该文件主要是配置SessionFractory类。<?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> <!-- 数据库连接的URL --> <property name="connection.url">jdbc:sqlserver://localhost:1433;databaseName=XSCJ</property> <!-- 数据库连接的用户名,此处为自己数据库的用户名和密码 --> <property name="connection.username">liuyanbo</property> <!-- 数据库连接的密码 --> <property name="connection.password">123456</property> <!-- SQL方言,这里使用的是SQL Server --> <property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <!-- 使用的数据库的连接,我们创建的MyConn --> <property name="myeclipse.connection.profile">MyConn</property> <!-- 数据库JDBC驱动程序 --> <property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property> <!-- 表和类对应的映射文件,如果多个,都要在这里注册 --> <mapping resource="org/model/Kcb.hbm.xml"/> </session-factory> </hibernate-configuration>
Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需要的各种属性。Hibernate初始化期间会自动在CLASSPATH中寻找这个文件,并读取其中的配置信息,为后期数据库操作做好准备。
3)HibernateSessionFactory
HibernateSessionFactory类是自定义的SessionFactory,名字可以自定义。这里用的HibernateSessionFactory。package org.util; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; public class HibernateSessionFactory { // 定义一个静态字符串变量存放Hibernate的配置文件名 private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; // 创建一个线程局部变量对象 private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); // 创建一个静态的Configuration对象 private static Configuration configuration = new Configuration(); // 定义一个静态的SessionFactory对象 private static org.hibernate.SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; // 根据配置文件得到SessionFactory对象 static { try { // 得到configuration对象 // 该句和上面创建的静态对象合起来就为 // configuration=new Configuration().configure(configFile); configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } private HibernateSessionFactory() { } // 取得Session对象 public static Session getSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session == null || !session.isOpen()) { if (sessionFactory == null) { rebuildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } return session; } // 可以调用该方法重新创建SessionFactory对象 public static void rebuildSessionFactory() { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } // 关闭Session public static void closeSession() throws HibernateException { Session session = (Session) threadLocal.get(); threadLocal.set(null); if (session != null) { session.close(); } } public static org.hibernate.SessionFactory getSessionFactory() { return sessionFactory; } public static void setConfigFile(String configFile) { HibernateSessionFactory.configFile = configFile; sessionFactory = null; } public static Configuration getConfiguration() { return configuration; } }
在Hibernate中,Session负责完成对象持久化操作。该文件负责创建Session对象,以及关闭Session对象。从该文件可以看出,Session对象的创建大致需要以下3个步骤:
① 初始化Hibernate配置管理类Configuration。
② 通过Configuration类实例创建Session的工厂类SessionFactory。
③ 通过SessionFactory得到Session实例。
3.Hibernate核心接口
1)Configuration接口
Configuration负责管理Hibernate的配置信息。Hibernate运行时需要一些底层实现的基本信息。这些信息包括:数据库URL、数据库用户名、数据库用户密码、数据库JDBC驱动类、数据库dialect。用于对特定数据库提供支持,其中包含了针对特定数据库特性的实现,如Hibernate数据库类型到特定数据库数据类型的映射等。使用Hibernate必须首先提供这些基础信息以完成初始化工作,为后续操作做好准备。这些属性在Hibernate配置文件hibernate.cfg.xml中加以设定,当调用:
Configuration config=new Configuration().configure();
时,Hibernate会自动在目录下搜索hibernate.cfg.xml文件,并将其读取到内存中作为后续操作的基础配置。
2)SessionFactory接口
SessionFactory负责创建Session实例,可以通过Configuration实例构建SessionFactory。Configuration config=new Configuration().configure(); SessionFactory sessionFactory=config.buildSessionFactory();
Configuration实例config会根据当前的数据库配置信息,构造SessionFacory实例并返回。SessionFactory一旦构造完毕,即被赋予特定的配置信息。就是说,之后config的任何变更将不会影响到已经创建的SessionFactory实例sessionFactory。如果需要使用基于变更后的config实例的SessionFactory,需要从config重新构建一个SessionFactory实例。如果需要访问多个数据库,针对每个数据库,应分别创建其对应的SessionFactory实例。
SessionFactory保存了对应当前数据库配置的所有映射关系,同时也负责维护当前的二级数据缓存和Statement Pool。由此可见,SessionFactory的创建过程非常复杂、代价高昂。这也意味着,在系统设计中充分考虑到SessionFactory的重用策略。由于SessionFactory采用了线程安全的设计,可由多个线程并发调用。大多数情况下,针对一个数据库共享一个SessionFactory实例即可。
3)Session接口
Session是Hibernate持久化操作的基础,提供了众多持久化方法,如save、update、delete等。通过这些方法,透明地完成对象的增加、删除、修改、查找等操作。同时,值得注意的是,Hibernate Session的设计是非线程安全的,即一个Session实例同时只可由一个线程使用。同一个Session实例的多线程并发调用将导致难以预知的错误。
Session实例由SessionFactory构建:
Configuration config=new Configuration().configure(); SessionFactory sessionFactory=config.buldSessionFactory(); Session session=sessionFactory.openSession();
4)Transaction接口
Transaction是Hibernate中进行事务操作的接口,Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction,甚至可以是CORBA 事务。之所以这样设计是可以让开发者能够使用一个统一的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移值。事务对象通过Session创建。例如以下语句:Transaction ts=session.beginTransaction();
5)Query接口
在Hibernate 2.x中,find()方法用于执行HQL语句。Hibernate 3.x废除了find()方法,取而代之的是Query接口,它们都用于执行HQL语句。Query和HQL是分不开的。Query query=session.createQuery(“from Kcb where kch=198”);
上面是直接给出查询条件的值,也可以是设参数,例如以下语句:
Query query=session.createQuery("from Kcb where kch=?");
就要在后面设置其值:
Query.setString(0, "要设置的值");
上面的方法是通过“?”来设置参数,还可以用“:”后跟变量的方法来设置参数,如上例可以改为:
Query query=session.createQuery("from Kcb where kch=:kchValue"); Query.setString("kchValue","要设置的课程号值");
由于上例中kch为String类型,所以要用setString(),如果是int型,就要用setInt()。通用的方法是setParameter()方法,不管是什么类型的参数都可以。其使用方法是相同的,例如:
Query.setParameter(0, "要设置的值");
Query还有一个list()方法,用于取得一个List集合的示例,此示例中包括可能是一个Object集合,也可能是Object数组集合。例如:
Query query=session.createQuery("from Kcb where kch=198"); List list=query.list();
4.HQL查询
Hibernate Query Language。语法与SQL很像,但HQL是一种面向对象的查询语言。SQL的操作对象是数据表和列等数据对象,而HQL的操作对象是类、实例、属性等。HQL的查询依赖于Query类,每个Query实例对应一个查询对象。Query query=session.createQuery(“from Kcb where kch=198”);
HQL常用的几种查询方式:
1)基本查询
基本查询是HQL中最简单的一种查询方式。下面以课程信息为例说明其几种查询情况。(1)查询所有课程信息
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); Query query=session.createQuery("from Kcb"); List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
(2)查询某门课程信息
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); // 查询一门学时最长的课程 Query query=session.createQuery("from Kcb order by xs desc"); query.setMaxResults(1); // 设置最大检索数目为1 // 装载单个对象 Kcb kc=(Kcb)query.uniqueResult(); ts.commit(); HibernateSessionFactory.closeSession();
(3)查询满足条件的课程信息
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); // 查询课程号为001的课程信息 Query query=session.createQuery("from Kcb where kch=001"); List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
2)条件查询
查询的条件有几种情况,下面举例说明。(1)按指定参数查询
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); // 查询课程名为计算机基础的课程信息 Query query=session.createQuery("from Kcb where kcm=?"); query.setParameter(0, "计算机基础"); List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
(2)使用范围运算查询
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); // 查询这样的课程信息,课程名为计算机基础或数据结构,且学时在40~60之间 Query query=session.createQuery("from Kcb where (xs between 40 and 60) and kcm in('计算机基础','数据结构')"); List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
(3)使用比较运算符查询
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); // 查询学时大于51且课程名不为空的课程信息 Query query=session.createQuery("from Kcb where xs>51 and kcm is not null"); List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
(4)使用字符串匹配运算查询
Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); // 查询课程号中包含“001”字符串且课程名前面三个字为计算机的所有课程信息 Query query=session.createQuery("from Kcb where kch like '%001%' and kcm like '计算机%'"); List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
3)分页查询
为了满足分页查询的需要,Hibernate的Query实例提供了两个有用的方法:setFirstResult(int firstResult)和setMaxResults(int maxResult)。其中setFirstResult(int firstResult)方法用于指定从哪一个对象开始查询(序号从0开始),默认为第1个对象,也就是序号0。SetMaxResults(int maxResult)方法用于指定一次最多查询出的对象的数目,默认为所有对象。如下面的代码片段:Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); Query query=session.createQuery("from Kcb"); int pageNow=1; // 想要显示第几页 int pageSize=5; // 每页显示的条数 query.setFirstResult((pageNow-1)*pageSize); // 指定从哪一个对象开始查询 query.setMaxResults(pageSize); // 指定最大的对象数目 List list=query.list(); ts.commit(); HibernateSessionFactory.closeSession();
附:目录《JavaEE基础实用教程》笔记说明
相关文章推荐
- Hibernate Oracle sequence的使用技巧
- jsp Hibernate批量更新和批量删除处理代码
- jsp hibernate的分页代码第1/3页
- JAVA+Hibernate 无限级分类
- SSH整合中 hibernate托管给Spring得到SessionFactory
- jsp hibernate 数据保存操作的原理
- hibernate中的增删改查实现代码
- 解决hibernate+mysql写入数据库乱码
- java优化hibernate性能的几点建议
- java Hibernate延迟加载
- hibernate 常用方法介绍
- 详解Java的Hibernate框架中的注解与缓存
- 浅析Java的Hibernate框架中的继承关系设计
- JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
- 深入理解Hibernate中的flush机制
- 简要分析Java的Hibernate框架中的自定义类型
- 简单的手工hibernate程序示例
- 详解Java的Hibernate框架中的Interceptor和Collection
- 详解Java的Hibernate框架中的缓存与二级缓存
- MyBatis与Hibernate的比较