▁▃▅ Hibernate 入门 03 - 使用Hibernate完成持久化操作 ▅▃▁

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

系列目录:(后续不断更新...)

Hibernate 入门 01 - 框架技术 (介绍Hibernate框架的发展由来)Hibernate 入门 02 - Hibernate介绍及其环境搭建Hibernate 入门 03 - 使用Hibernate完成持久化操作Hibernate 入门 04 - Hibernate中java对象的三种状态

▁▃▅Hibernate 入门 03 - 使用Hibernate完成持久化操作▅▃▁

康姆昂,北鼻,来此狗。动次打次,Hibernate继续走起、

目录:使用Hibernate实现按主键查询使用Hibernate实现数据库的增、删、改操作

2.1 使用Hibernate实现增加操作

2.2 使用Hibernate实现修改、删除操作

2.2.1 使用Hibernate实现修改操作

2.2.2 使用Hibernate实现删除操作技能训练

为工程准备了Hibernate环境后,就可以通过Hibernate API操纵数据库。Hibernate内部也是采用JDBC来访问数据库的。

如下图就是JDBC API及Hibernate API方式来访问数据库:

使用Hibernate操作数据库包括7个步骤:(1)读取并解析配置文件

Configuration cfg =newConfiguration().configure();

根据默认位置的Hibernate配置文件的配置信息,构建Configuration对象。

Configuration负责管理Hibernate的配置信息。

(2)读取并解析映射信息,创建sessionFactory对象:

SessionFactory sessionFactory = cfg.buildSessionFactory();

SessionFactory负责创建Session对象。

Configuration对象会根据当前的数据库配置信息,构造SessionFactory对象。

SessionFactory对象一旦构造完毕,则Configuration对象的任何变更将不会影响已经创建的SessionFactory对象。

如果Hibernate配置信息有改动,那么需要基于改动后的Configuration对象重新构建一个SessionFactory对象。

(3)打开Session:

Session session = sessionFactory.openSession();//或者使用 sessionFactory.getCurrentSession();

Session是Hibernate持久化操作的基础。Session负责完成对象的持久化操作,它相当于JDBC中的Connection。

Session作为贯穿Hibernate的持久化管理器的核心,提供了众多持久化方法,如save()、delete()、update()、get()、load()等。

通过这些方法,即可透明地完成对象的增删改查(CRUD)。

(4)开始一个事务(增删改操作必须,查询操作可选):

Transaction transaction = session.beginTransaction();//打开事务

(5)数据库操作:

session.save(obj);//将obj对象进行保存操作

(6)结束事务:

transaction.commit();//提交事务

(7)关闭session:

session.close();//关闭session

如果在Hibernate配置文件中,参数current_session_context_class设置为thread,并采用SessionFactory的getCurrentSession()方法获得Session对象,则不需要执行session.close()方法。

资料:

在项目开发过程中,通常使用工具类来管理SessionFactory和Session,代码如下所示:

1packagecom.geeksss.HibernateStudy.util;23importorg.hibernate.Session;4importorg.hibernate.SessionFactory;5importorg.hibernate.cfg.Configuration;67publicclassHibernateUtil {8//初始化一个ThreadLocal对象,ThreadLocal对象有get()、set()方法9PRivatestaticfinalThreadLocal sessionTL =newThreadLocal();10privatestaticConfiguration configuration;11privatestaticfinalSessionFactory sessionFactory;12static{13try{14configuration =newConfiguration().configure();15sessionFactory =configuration.buildSessionFactory();16}catch(Throwable ex){17ex.printStackTrace();18thrownewExceptionInInitializerError(ex);19}20}21publicstaticSession currentSession(){22/*23* sessionTL的get()方法根据当前县城返回其对应的线程内部变量,即Session对象。24* 多线程情况下共享数据库连接是不安全的。25* ThreadLoca保证了每个线程都有自己独立的Session对象。26*/27Session session =(Session)sessionTL.get();28/*29* 如果session为null,则打开一个新的session30* 如果该线程是初次访问,session是null,则创建一个Session对象31*/32if(session==null){33session = sessionFactory.openSession();//创建一个Session对象34sessionTL.set(session);//保存该Session对象到ThreadLocal中35}36returnsession;//如果当前线程已经访问过数据库,则从sessionTL中get()就可以获取该线程上次获取过的Session对象。37}38/**39* 关闭session40* 首先调用sessionTL.get()方法获取Session对象;41* 接着调用sessionTL.set(null)方法,把sessionTL管理的Session对象置为null;42* 最后关闭Session。43*/44publicstaticvoidcloseSession(){45Session session =(Session)sessionTL.get();46sessionTL.set(null);47session.close();48}49}

HibernateUtil.java (Hibernate工具类)

通过ThreadLocal类,既实现了多线程并发,同时,也实现了Singleton单例模式。

1. 使用Hibernate实现按主键查询在进行修改或删除操作时,应先加载对象,然后再执行修改或删除操作。

Hibernate提供了两种方法按照主键加载对象:get()和load()方法、

Object get(Class clazz, Serializable id)。Object load(Class theClass, Serializable id)。

虽然两个方法都能够加载对象,但是他们是有区别的。

下面以部门表为例,通过两段代码讲解他们的区别:

(1) get()方法加载部门对象的代码如下:

1packagecom.geeksss.HibernateStudy.test;23importorg.hibernate.HibernateException;4importorg.hibernate.Session;5importorg.hibernate.SessionFactory;6importorg.hibernate.cfg.Configuration;78importcom.geeksss.HibernateStudy.entity.Dept;9importcom.geeksss.HibernateStudy.entity.Users;10importcom.geeksss.HibernateStudy.util.HibernateUtil;1112publicclassTest {13publicstaticvoidmain(String[] args) {1415Configuration cfg =null;16SessionFactory sessionFactory =null;17Session session =null;1819try{20//读取配置文件21cfg =newConfiguration().configure();22//创建SessionFactory23sessionFactory =cfg.buildSessionFactory();24//打开session;25session =sessionFactory.openSession();26//加载数据操作27Users user = (Users)session.get(Users.class,newInteger("4"));28//输出操作29System.out.println("使用get()方式获取id为4的用户是:"+user.getName());30}catch(HibernateException e) {31e.printStackTrace();32}finally{33if(null!=session){34session.close();35}36}3738}39}

使用Session.get()方式获取数据

运行效果如图:

(2) load()方法加载数据,只需要将get换为load即可,结果不变。如图:

到此,可能大家肯定会想,为什么查询一个数据,会有两种方式呢?

希望大家明白:学一个东西,不管是什么,既然存在,那么就有它存在的意义。

get()和load()亦是如此,肯定有区别的啊~下面我们来演示看一下。。。

现在我的数据库中,User表中只有4条记录:

下面我们分别使用get()和load()获取id为10的对象并输出,看一下结果。

1.get()方式,查询返回null:

2.load()方式,查询返回如下异常:

异常信息为: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.geeksss.HibernateStudy.entity.Users#10]

即:对象未找到。

由此,我们得知:

当使用Session的get()方法时,如果加载的数据不存在,get()方法会返回一个null;但是使用load()方法,若加载的数据不存在,则会抛出异常。

这是get()方法和load()方法的区别之一,两个方法的其他区别,我们后面会慢慢讲到。

2. 使用Hibernate实现数据库的增、删、改操作2.1 使用Hibernate实现增加用户记录增加操作的测试代码如下:

1packagecom.geeksss.HibernateStudy.test;23importorg.hibernate.HibernateException;4importorg.hibernate.Session;5importorg.hibernate.SessionFactory;6importorg.hibernate.Transaction;7importorg.hibernate.cfg.Configuration;89importcom.geeksss.HibernateStudy.entity.Users;1011publicclassTest {12publicstaticvoidmain(String[] args) {13Configuration cfg =null;14SessionFactory sessionFactory =null;15Session session =null;16Transaction transaction =null;1718Users user =newUsers();//实例化一个对象 并赋值19user.setName("李四");20user.setPassWord("ls123456");21user.setTelephone("13800138000");22user.setUsername("lisi");23user.setisAdmin(false);2425try{26cfg =newConfiguration().configure();//读取配置文件27sessionFactory = cfg.buildSessionFactory();//创建SessionFactory28session = sessionFactory.openSession();//打开session;29transaction = session.beginTransaction();//开启一个事务30session.save(user);//持久化操作31transaction.commit();//提交事务32}catch(HibernateException e) {33e.printStackTrace();34transaction.rollback();//回滚事务35}finally{36if(null!=session) session.close();//关闭session37}3839}40}

与JDBC一样,持久化操作放在try中,如果正常则提交,如果异常则进入catch回滚,最后关闭session。

不过,运行出现异常,结果如下:

仔细观察,我们发现,在控制台中,插入的SQL语句正确打印,但是出错,错误信息显示:“当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'Users' 中的标识列插入显式值。”

很明显,在这里我们插入数据的时候,并没有通过user.setId(xxx)来为其设置编号,那么也就是默认的0。

打开Users.hbm.xml映射文件,我们发现主键的生成策略我们设置的是“assigned”,也就是由应用程序控制,不用Hibernate干涉。(上节介绍过)

而在这里,我们SQL Server中的Users主键是自动增长的,因此,我们设置为“identity”(自增)或“native”(自动识别)都是可以的。

设置完映射文件的代码如下:

1<?xml version="1.0" encoding="UTF-8"?>2<!DOCTYPE hibernate-mapping PUBLIC3"-//Hibernate/Hibernate Mapping DTD 3.0//EN"4"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">56<hibernate-mappingpackage="com.geeksss.HibernateStudy.entity">7<classname="Users"table="Users">8<idname="id"type="java.lang.Integer"column="Id">9<generatorclass="identity"></generator>10</id>11<propertyname="name"type="java.lang.String"column="Name"></property>12<propertyname="password"type="java.lang.String"column="Password"></property>13<propertyname="telephone"type="java.lang.String"column="Telephone"></property>14<propertyname="username"type="java.lang.String"column="Username"></property>15<propertyname="isAdmin"type="java.lang.Boolean"column="IsAdmin"></property>16</class>17</hibernate-mapping>

再次运行程序,插入成功:

2.2 使用Hibernate实现用户信息的修改、删除下面学习如何使用Hibernate修改和删除数据。

对于Hibernate这种ORM工具,操作都是针对对象的。

要修改和删除数据,首先要获得数据,然后再进行修改和删除数据。

2.2.1 使用Hibernate修改用户数据实例代码如下:

1packagecom.geeksss.HibernateStudy.test;23importorg.hibernate.HibernateException;4importorg.hibernate.Session;5importorg.hibernate.SessionFactory;6importorg.hibernate.Transaction;7importorg.hibernate.cfg.Configuration;89importcom.geeksss.HibernateStudy.entity.Dept;10importcom.geeksss.HibernateStudy.entity.Users;11importcom.geeksss.HibernateStudy.util.HibernateUtil;1213publicclassTest {14publicstaticvoidmain(String[] args) {1516Configuration cfg =null;17SessionFactory sessionFactory =null;18Session session =null;19Transaction transaction =null;20try{21cfg =newConfiguration().configure();//读取配置文件22sessionFactory = cfg.buildSessionFactory();//创建SessionFactory23session = sessionFactory.openSession();//打开session;2425Users user = (Users)session.get(Users.class,newInteger("4"));//加载数据操作26System.out.println("修改之前编号4用户姓名是:"+user.getName());//输出操作2728transaction = session.beginTransaction();//创建事务29user.setName("测试修改");//修改对象30transaction.commit();//提交事务 完成修改3132user = (Users)session.get(Users.class,newInteger("4"));//重新加载数据33System.out.println("修改之后编号4用户姓名是:"+user.getName());//输出操作34}catch(HibernateException e) {35e.printStackTrace();36if(null!=transaction){37transaction.rollback();38}39}finally{40if(null!=session){41session.close();42}43}4445}46}

使用Hibernate实现修改Users数据

执行结果如下:

在使用Hibernate修改数据时,首先要加载对象,然后修改对象的属性,最后提交事务。

Hibernate会生成并执行修改的SQL语句,其中的原理会在后面慢慢讲到滴~

2.2.2 使用Hibernate实现删除Users数据实例代码如下:

1packagecom.geeksss.HibernateStudy.test;23importorg.hibernate.HibernateException;4importorg.hibernate.Session;5importorg.hibernate.SessionFactory;6importorg.hibernate.Transaction;7importorg.hibernate.cfg.Configuration;89importcom.geeksss.HibernateStudy.entity.Dept;10importcom.geeksss.HibernateStudy.entity.Users;11importcom.geeksss.HibernateStudy.util.HibernateUtil;1213publicclassTest {14publicstaticvoidmain(String[] args) {1516Configuration cfg =null;17SessionFactory sessionFactory =null;18Session session =null;19Transaction transaction =null;20try{21cfg =newConfiguration().configure();//读取配置文件22sessionFactory = cfg.buildSessionFactory();//创建SessionFactory23session = sessionFactory.openSession();//打开session;2425Users user = (Users)session.get(Users.class,newInteger("4"));//加载数据操作26System.out.println("删除之前编号4用户是:"+user);//输出操作2728transaction = session.beginTransaction();//创建事务29session.delete(user);//删除user对象30transaction.commit();//提交事务 完成删除3132user = (Users)session.get(Users.class,newInteger("4"));//重新加载数据33System.out.println("删除之后编号4用户是:"+user);//输出操作34}catch(HibernateException e) {35e.printStackTrace();36if(null!=transaction){37transaction.rollback();38}39}finally{40if(null!=session){41session.close();42}43}4445}46}

使用Hibernate实现删除Users对象

执行结果如下:

与修改类似,删除时也需要先加载数据。

在使用Hibernate编写持久化代码时,业务不需要再有数据库表、字段等概念。

从面相业务领域对象的角度,要删除的是某个业务对象。以面相对象的方式编写的代码是Hibernate持久化操作接口设计的一个理念。

需要注意的是,增、删、改操作一定要在事务环境中完成。

3. 技能训练 - 在租房网系统中实现用户表的增删改查操作在上一节我们已经搭建好的Hibernate环境中,使用Hibernate实现用户记录的增加、修改、删除和查询操作。

要求按照用户编号查询指定的用户记录。

同志们,有错提错,代码撸起吧~ 呵呵。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航