使用Hibernate快速读取数据库数据 (hibernate 读取数据库)

随着信息量的爆炸性增长,数据管理和处理变得越来越重要。而对于企业系统开发而言,与数据相关的问题集中在数据库操作上。因此,如何快速读取数据库数据是每个企业系统开发人员需要掌握的重要技能。而Hibernate作为一种开源的对象关系映射(ORM)工具,可以帮助开发人员与数据库交互,减少编写数据库操作代码和提高开发效率。在这篇文章中,我们将介绍如何。

概述

Hibernate与传统的数据库操作不同,它是基于面向对象的开发理念,将数据的增删查改都转化为对Object的操作,从而减少一大堆SQL语句的编写,提高开发效率。使用Hibernate,可以将Entity的定义与表结构的定义一一对应,使得开发者无需关心表的创建、维护以及数据的操作,从而简化了开发流程,并且方便了以后的维护。同时,Hibernate也能在一定程度上提高数据库读写的效率。

在开始之前,我们需要先了解Hibernate的几个重要概念:

1. Entity

Entity体现了一张表的结构,其成员变量对应表的属性,同时也定义了表与表之间的关系。比如一个User的Entity就可能拥有username和password的属性,并且与订单之间就可能存在一对多的关系。

2. Session

Session提供了对数据库的操作,包括增删查改等等;同时还提供了事务管理等其他的服务。

3. Criteria

Criteria提供了对查询的重要支持,并且能够解决对多个关联表的查询操作。当然也支持类似group by或是order by的操作。

4. HQL

HQL即Hibernate Query Language,是一种类SQL的Hibernate特有查询语句。

Hibernate配置

在开始使用Hibernate之前,我们需要先配置Hibernate,以便于正确地读取数据库数据。

在本地电脑上新建一个maven工程,在pom.xml文件中添加如下配置信息:

“`

log4j

log4j

1.2.16

org.hibernate

hibernate-core

5.0.7.Final

com.alibaba

druid

1.0.29

mysql

mysql-connector-java

5.1.40

“`

这些依赖包分别提供了log4j、Hibernate、MySQL、数据库连接池Druid等必要的支持。

在完成依赖包的引入之后,我们需要在src/mn/resources目录下(创建一个“resources”目录即可)新建一个Hibernate配置文件,文件名为hibernate.cfg.xml。我们将在这里配置Hibernate所需要的基本信息。

“`

org.hibernate.dialect.MySQL5InnoDBDialect

com.mysql.jdbc.Driver

jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8

root

YourPassword

3

60

10

100

true

true

update

“`

在这段xml配置文件中,主要包括了数据库连接,数据库连接池,方言以及HQL语句的打印等等信息。

Hibernate配置完成之后,我们就可以开始使用Hibernate进行查询操作了。

Hibernate读取数据库数据

在Hibernate中,我们可以使用Session来读取数据库中的数据。Session是一个与Hibernate或Java的线程绑定的事务级别的缓存,这意味着你可以从一次数据库查询中检索大量数据,并且在查询期间快速建立一个缓存,以便在后续的查询中被重复使用。同时,这个缓存是事务级别的,所以你只能在这个事务中使用这个缓存。

在开始使用Hibernate Session进行数据库读取之前,需要先获得SessionFactory对象,SessionFactory是一个线程安全的用于创建Session的工厂,我们可以将它看做是一个与数据库之间的链接。

在一个完整的Hibernate查询过程中,我们需要完成以下三个步骤:

1. 初始化SessionFactory,在这里我们使用一个静态方法获取SessionFactory:

“`

private static SessionFactory sessionFactory;

static {

Configuration cfg = new Configuration().configure(“hibernate.cfg.xml”);

sessionFactory = cfg.buildSessionFactory();

}

“`

2. 创建Session进行数据读取:

“`

Session session = sessionFactory.openSession();

“`

在这里,我们创建一个Session对象,通过调用SessionFactory的openSession方法即可。

3. 关闭Session对象:

“`

session.close();

“`

在完成查询操作之后,我们需要关闭Session对象以释放资源。

接下来,我们将以一个简单的查询为例来介绍Hibernate的查询操作。

我们需要定义一个Student的Entity:

“`

@Entity

public class Student {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

//学生的id,自增类型

private Long id;

@Column

//学生姓名

private String name;

@Column

//学生性别

private String sex;

@Column

//学生班级

private String cls;

//年龄

private Integer age;

//备注

private String comments;

//省略了get和set方法

}

“`

在这里,我们使用了@Entity注解来告诉Hibernate这是一个实体类,同时使用@Id来标识该属性是表的主键。

接下来,我们可以使用Hibernate条件查询来读取数据库中的数据,如下:

“`

Session session = sessionFactory.openSession();

Criteria criteria = session.createCriteria(Student.class);

criteria.add(Restrictions.eq(“name”, “Tom”));

List students0 = criteria.list();

session.close();

“`

在这里,我们首先创建了一个Criteria对象,指定了要查询的实体类Student.class,并调用了Restrictions.eq方法来限定查询条件(等于“Tom”)。最后使用list方法来获取查询结果。

除了Criteria外,Hibernate还提供了HQL和SQL查询方式,如下:

1. HQL查询方式:

“`

Session session = sessionFactory.openSession();

Query query = session.createQuery(“select student from Student student where student.name=:name”);

query.setParameter(“name”, “Tom”);

List students1 = query.list();

session.close();

“`

在这里,我们使用了一个HQL语句来查询列表,注意:student.name、student.id是类属性,而“:name”是一个舌尖式的参数,而且参数类型也不用定义。我们给这个HQL查询取了一个名字“select user from Student user where user.name=:name”,使用时可以这么来:

“`

Query query = session.getNamedQuery(“select user from Student user where user.name=:name”);

“`

2. SQL查询方式:

“`

Session session = sessionFactory.openSession();

SQLQuery sqlQuery = session.createSQLQuery(“select * from student where name = ?”);

sqlQuery.setString(0, “Tom”);

List students2 = sqlQuery.addEntity(Student.class).list();

session.close();

“`

在这里,我们使用了一个SQL查询来查询列表,使用时也是可以进行参数限定的,同时注意:在使用SQL查询方式的时候,需要添加一个addEntity()的方法,来将查询的结果映射到类中,否则将会出错。

Hibernate作为一个强大的ORM框架,在读取数据库数据方面发挥了重要作用。同时,Hibernate通过Session对象的缓存也提升了数据库读取的效率。当然,虽然使用Hibernate可以简化数据库操作并提高开发效率,但使用Hibernate并非万能,有时候出于某些原因,我们还是需要使用传统的SQL方式来进行数据读写,所以需要开发人员根据实际情况选择不同的解决方案来完成项目开发。

相关问题拓展阅读:

hibernate从数据库取不出数据问题

你那个hql没问题?? 试试直接 FROM Files 看看

拿不到数据分析3个问题:1数据库问题;2程轮大序连接数据芦腊库问题;3程序问题。

能插入数据,说明1和2应该是没问题。

剩下3号问题了。

你的问题描述太少,我不知道该怎么详细的分析。建议你debug模式调试看看各个变量的值!

session确定是你要的数据库的连接陪桐滑吗?

list.size() = 0 吗?

重启服务器试过了吗?

查询之前试试清缓存?

hql = “from Files”

select f from Files as f 执行的HQL语句,将类名Files变成files再试下。

session.createQuery(“from Files);

List ilst = query.list();

//另外团乎,看书上查询也在腊或绝事务中,更好轮姿好在事务中。

首先查看数据库的路径

Hibernate上手指南

Hibernate上手

Hibernate,很久以前我就听说过这个名词,但是似乎没什么动力让我去接近它,感觉它是一个很复杂的东西,一直没搞明白它到底是用来做什么的。直到接手了一个项目在技术选型的时候我再一次的看到了Hibernate。我尝试着去使用它,发现它并不是我想像中的那么深奥,它很易用。你并不需要了解它的内部结构,它一样能为你工作的很好,如果你理解了它到底能为你做什么的话

本文着重讲述了为什么要使用Hibernate,此外也简单的介绍了如何使用Hibernate,以及Hibernate中的一些基本概念。我想借这篇文章来向还没有接触过Hibernate的开发者推荐款优秀的开源ORM产品,如果你已经实践过Hibernate,那么我想你没有必要再看下去。

一、Why Hibernate?

现在流行“测试驱动开发”,相似的我觉得“目的驱动学习”是一种比较好的接受新技术,新知识的途径。在学习一样新的技术之前,首先得明确到底有没有必要学习,已有的技术是否已经工作的很好,学习这个新的技术是为了解决什么问题。如果你明确了以上问题,那么寻找并学习新的技术将会事半功倍,并且能快速应用到实际的开发当中来提高效益。

要说Hibernate,就得先介绍一下Object/Relation Mapper(ORM),中文翻译为对象关系映射。之所以会产生这样的概念是源于目前软件开发中的一些不协调的思想。目前流行的编程模型是OOP(Object Oriented Programming),面向对象的编程,而目前流行的数据库模型是Relational Database,这两者思考的方式不一样,这必然产生了开发过程中的不协调。ORM框架(也称为持久层框架梁祥,盯指)的出现就是为了解决这样的问题,屏蔽底层数据库的操作,以面向对象的方式提供给开发者操作数据库中数据的接口。目前流行的ORM框架有Apach OJB,Hibernate,iBatis等等,当然最完善,更好用的是Hibernate,至少我这样认为。或许你对“持久层”感到迷惑,其实说白了很简单,把数据放到数据库中叫做持久化(内存种的数据当然不是持久的),那么负责这一操作的结构层面就叫做持久层。你以前应该听说过表现层,业务层,数据层,那么持久层是在业务层和数据层之间的一层,或者说持久层是数据层的一部分。

接下来,我想通过一个实际开发中的例子来说明ORM带给我们的好处。先来讲一下我们的需求,数据库中有三张表,一张student,一张course,另外一张course_slection。其中student用来保存学生信橡则搏息,course用来表示课程信息,course_selection用来表示学生的选课信息。(表的详细结构这里我就省略了,因为这并不重要)现在要求编写一个程序,用来选出指定学号学生所选的课程名字,那么可能会出现以下几种程序编写的方式:

1. 菜鸟级

代码片段1:

public List selectCourses(String studentId)

{

Connection con = null;

Statement sta = null;

try

{

Class.forName(”oracle.jdbc.driver.OracleDriver”);

con = DriverManager.getConnection(“jdbc:oracle:thin:@10.85.33.199:1521:glee”,

“test”, “test”);

String sql = “select * from course_selection”;

String sql2 = “select name from course where id='”;

sta = con.createStatement();

ResultSet rs = sta.executeQuery(sql);

List list = new LinkedList();

while (rs.next())

{

ResultSet rs2 = sta.executeQuery(sql2 +

rs.getString(”course_id”) + “‘”);

if (rs2.next())

{

list.add(rs2.getString(”name”));

}

}

return list;

}

catch (Exception e)

{

e.printStackTrace();

}

return null;

}

这段程序你一定看的很晕吧,什么乱七八糟的都搞在一起,那么接下来看一段改进过的程序。

2. 改进后的代码

代码片段2:

class DBHelper

{

public static Connection getConnection()

{

try

{

Class.forName(Constants.DB_DRIVER);

return DriverManager.getConnection(Constants.DB_URL,

Constants.DB_USER, Constants.DB_PWD);

}

catch (Exception e)

{

e.printStackTrace();

}

return null;

}

}

public List selectCourses(String studentId)

{

Connection con = null;

Statement sta = null;

try

{

con = DBHelper.getConnection();

String sql = “select * from course_selection”;

String sql2 = “select name from course where id='”;

sta = con.createStatement();

ResultSet rs = sta.executeQuery(sql);

List list = new LinkedList();

while (rs.next())

{

ResultSet rs2 = sta.executeQuery(sql2 + rs.getString(”course_id”) + “‘”);

if (rs2.next())

{

list.add(rs2.getString(”name”));

}

}

return list;

}

catch (Exception e)

{

e.printStackTrace();

}

return null;

}

这段代码的形式是一种被广泛采用的形式,相对之一段代码来说,应该已经有所进步,分离了数据库连接操作,并把数据库连接信息交给单独的类完成(一般放在配置文件里面),往往在开发中还会引入数据库连接池(Connection Pool)来提高性能,我这里都尽量简化了。但这些并不能从根本上改善程序的结构,在业务代码中仍然混杂了很多数据库操作,结构不清晰。下面来看一段彻底分离数据库操作的代码:

3. DAO模式

代码片段3:

public List selectCourses(String studentId)

{

StudentDAO sd = new StudentDAO();

Student student = sd.findById(studentId);

Set set = student.getCourseSelections();

List courseNames = new LinkedList();

for (Iterator iter = set.iterator(); iter.hasNext();)

{

CourseSelection element = (CourseSelection) iter.next();

courseNames.add(element.getCourse()。getName());

}

return courseNames;

}

是不是感觉代码少了很多?或许你对这段代码有点迷惑,没关系,后文会详细解释。我想先解释一下DAO。其实DAO和Hibernate没有必然联系,只不过一般用Hibernate的程序都用DAO模式。DAO的全称是Data Access Object,程序要访问数据库中的数据(包括获取,更新,删除)都通过DAO来访问,实际上DAO才是真正屏蔽了所有数据库操作的东西,这样在业务代码中就可以完全隔离数据层的代码。如果我告诉你,在真正用Hibernate开发的时候,要完成上文提到的功能,需要手写的代码就是“代码片段3”这么多,甚至更少,你是不是有很大的动力去学习Hibernate?那么好吧,让我们开始Hibernate之旅。

二、持久层的组成

这一节的名字应该换成“基于Hibernate的持久层的组成”更合适一点,可是它太长了。既然Hibernate是用来开发持久层,那么我先介绍一下这个持久层中的各个元素。

1. POJO:Plain Old Java Object,你可以把它看作是简单的JavaBean。一般说来,一张数据库表对应一个POJO,也就是对象/关系的一一映射。

2. DAO:对于每一个POJO,一般都有一个DAO与之对应,承担所有关于该POJO的访问控制。实际上也就是控制了对数据库中一张表的访问控制。

3. *.hbm.xml文件:这个文件定义了POJO和数据库中的表是如何映射的,比如POJO中的字段对应数据库表中的哪个字段等等。一般每个映射都用单独的文件来描述,也就是有一个POJO就有一个*.hbm.xml文件。

4. *.cfg.xml文件:这个文件定义了Hibernate的基本信息,比如数据库驱动,用户名,密码等等连接信息,也包括了所有要用的*.hbm.xml文件,在初始化的时候,Hibernate会读取这个文件来找相应的映射文件完成对象/关系。

我们还是以上文的例子来详细描述一下这里提到的各个元素的内容。

1. Student.java:

代码片段4:

public class Student implements java.io.Serializable

{

private String id;

private String name;

private Set courseSelections = new HashSet(0);

public Student()

{

}

public String getId()

{

return this.id;

}

public void setId(String id)

{

this.id = id;

}

public String getName()

{

return this.name;

}

public void setName(String name)

{

this.name = name;

}

public Set getCourseSelections()

{

return this.courseSelections;

}

public void setCourseSelections(Set courseSelections)

{

this.courseSelections = courseSelections;

}

}

#p#副标题#e#

这个类就是一个POJO,你可以很明显的看出来它就是一个JavaBean。我想解释它的courseSelection字段。很显然,在数据库表student中,没有这个字段。这里的这个字段是因为一个外键引用,course_selection的student_id是一个外键,引用了student表中的id字段。那么在Student类中courseSelection来记录这样的外键关系,也就是说,当我们获取了Student对象以后,就可以直接获取他的选课记录,这样就为上层的调用提供了很大的方便。这里有点模糊没关系,我在介绍映射定义文件(*.hbm.xml)的时候还会提到这个问题。

2. StudentDAO.java

代码片段5:

public class StudentDAO

{

Session session;

public StudentDAO()

{

Configuration cfg = new Configuration();

cfg.configure(”/hibernate.cfg.xml”);

SessionFactory sessionFactory = cfg.buildSessionFactory();

session = sessionFactory.openSession();

}

public void save(Student transientInstance)

{

session.save(transientInstance);

}

public void delete(Student persistentInstance)

{

session.delete(persistentInstance);

}

public Student findById(java.lang.String id)

{

List list = session.createCriteria(Student.class)。add(Expression.eq(”id”, id))。list();

if (list.size()

0)

{

return (Student)list.get(0);

}

return null;

}

}

这里的构造函数是用来启动Hibernate,并获取session。打开一个session就相当于打开了一个数据库连接,然后我们就可以对这个session进行操作,完成数据库操作,完全不用写SQL语句。我这里Hibernate的启动方式写的很不规范,系统应该只需要完成一次Hibernate启动就可以在不同的DAO中使用,我把它写在构造函数里面纯粹是为了简化演示代码。

你可以看到save和delete方法都很简单直接对对象操作,而findById就有些麻烦,因为这里有一个查询过程在里面。Hibernate里面查询可以用Criteria这个类来完成,我们也常用Hibernate独有的HQL(Hibernate Query Language)来完成查询。当然Hibernate也是支持原生SQL的。关于查询的详细信息请参考其他文章或书籍,我只是演示一个流程,介绍一些概念。

3. Student.hbm.xml

代码片段6:

hibernate-mapping

class name=”Student” table=”STUDENT”

id name=”id” type=”string”

column name=”ID” length=”10″ /

generator class=”assigned” /

/id

property name=”name” type=”string”

column name=”NAME” not-null=”true” /

/property

set name=”courseSelections” inverse=”true”

key

column name=”STUDENT_ID” length=”10″

not-null=”true” /

/key

one-to-many class=”CourseSelection” /

/set

/class

/hibernate-mapping

这个文件定义了Student类和Student表是如何映射的。class元素定义了Sudent类和STUDENT表映射,然后就定义了各个属性是如何映射的。如果一个属性是数据库的key,那么会用id标签来定义,column定义了当前类的属性和数据库中的哪个字段对应,generator是id特有的。一般来说id是自增的,由于我的数据库是用的Oracle,它没有自增字段,要实现自增必须用Sequence,这超出了本文的范围,所以我就用assigned来简化示例代码。assigned表示id是用户给定的。

有一个比较特别的标签是set,它对应着数据库中的外键关系,上文我提到的通过Student对象可以获得所有相关的选课记录就是通过这里的定义实现的。name属性对应了Student类中的字段名,key表示哪个字段是外键,one-to-many表示Student和CourseSelection是一对多关系,这和事实相符。类似的还有many-to-one,many-to-many,不过这些都不常用,我不介绍了。Hibernate根据这个映射定义文件,在实例化一个POJO(比如Student)的时候,会自动的把定义过映射的属性用数据库中的数据填充,set也包括在内。

4. hibernate.cfg.xml

代码片段7:

hibernate-configuration

session-factory

property name=”connection.username”test/property

property name=”connection.url”

jdbc:oracle:thin:@10.85.33.199:1521:glee/property

property name=”dialect”

org.hibernate.dialect.Oracle9Dialect/property

property name=”connection.password”test/property

property name=”connection.driver_class”

oracle.jdbc.OracleDriver/property

mapping resource=”Student.hbm.xml”/mapping

mapping resource=”CourseSelection.hbm.xml”/mapping

mapping resource=”Course.hbm.xml”/mapping

/session-factory

/hibernate-configuration

这个文件我不解释了,自己看吧。结合上文StudentDAO的例子,我想你应该能看明白。

看了这么多,或许你会有点头皮发麻,POJO,DAO,配置文件好像要写的东西还是很多。值得庆幸的是现在Hibernate已经发展的比较成熟了,有很多工具来帮助我们完成这些工作,比如MiddleGen,Hibernate Synchronizer等等。我使用的开发工具是Eclipse+MyEclipse,我所要做的只是把数据库表建好,然后MyEclipse提供的工具会自动根据数据库表生成POJO,DAO,*.hbm.xml,甚至hibernate.cfg.xml都是自动完成的(前提是MyEclipse知道你的数据库连接信息)。我并不打算介绍如何用IDE来开发Hibernate,你可以参考IDE的帮助文档。

到这里为止,使用Hibernate进行开发的基本组成元素我都介绍好了,强烈建议你马上实践一遍,即使有些不理解,也先依葫芦画瓢一个。对了,别忘了把Hibernate的包down下来放到classpath里面。

三、Session与SessionFactory

Session可以说是Hibernate的核心,Hibernate对外暴露的接口就是Session。所以我这里讲一下有关Session的常用函数和特性。

在讲Session之前,我想先提一下SessionFactory,这个东西不复杂,只要配置好就行了。顾名思义,SessionFactory就是用来创建Session的。SessionFactory是线程安全的,也就是说对于同一个数据库的所有操作共享一个SessionFactory就行了。回头看代码片段5,我们可以看到SessionFactory的常用配置方式。

代码片段8:

Configuration cfg = new Configuration();

cfg.configure(”/hibernate.cfg.xml”);

SessionFactory sessionFactory = cfg.buildSessionFactory();

我们通过Configuration来读取配置文件,然后就可以创建SessionFactory,这段代码在 所有系统中都大同小异,一般就是xml配置文件的名字不一样,所以也没什么好说的。

当我们有了SessionFactory以后就可以获取Session了。调用SessionFactory.openSession()就会返回一个Session实例,然后我们操作这个Session来访问数据库。值得一提的是Session并不是线程安全的,也就是每一个线程都必须有自己的Session。所以我们一般通过以下方法来获取和关闭Session:

代码片段9:

public static Session currentSession() throws HibernateException

{

Session session = (Session) threadLocal.get();

if (session == null || !session.isOpen())

{

if (sessionFactory == null)

{

try

{

cfg.configure(CONFIG_FILE_LOCATION);

sessionFactory = cfg.buildSessionFactory();

}

catch (Exception e)

{

e.printStackTrace();

}

}

session = (sessionFactory != null) ?

sessionFactory.openSession(): null;

threadLocal.set(session);

}

return session;

}

public static void closeSession() throws HibernateException

{

hibernate 读取数据库的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于hibernate 读取数据库,使用Hibernate快速读取数据库数据,hibernate从数据库取不出数据问题,Hibernate上手指南的信息别忘了在本站进行查找喔。


数据运维技术 » 使用Hibernate快速读取数据库数据 (hibernate 读取数据库)