前言
Hibernate属于ORM框架,至于什么是ORM框架,搜索一下都有很多的。简而言之:
- 实现java对象和数据库表之间的映射。
- 提供对数据操作的方法。
- 减少开发人员使用SQL和JDBC处理数据。
- 能够使开发人员面向业务模型/商业逻辑编程。
- 减少特定数据库厂商的SQL的差异。
介绍
Hibernate中对象的介绍
SessionFactory(org.hibernate.SessionFactory)
SessionFactory
本身在Hibernate当中起到了缓冲区的作用,缓冲了Hibernate自动生成的SQL语句和他的映射语句,还缓冲了一些可能重复利用的数据。同时为了能够创建SessionFactory
对象,在Hibernate
初始化的时候创建一个Configuration
类的实例并将已经写好的配置文件hibernate.cfg.xml
交给其处理,这样Configuration
就可以创建SessionFactory
对象了,当SessionFactory
创建完成后,Configuration
对象就没有用了,可以将其抛弃。此外,SessionFacory
还用到了工厂模式,使得程序能够从SessionFactory
当中获得Session
实例,能够在整个程序当中共享使用,通常一个项目当中只需要一个SessionFactory
就够了。
1 | Session session=sessionfactory.openSession(); |
Session(org.hibernate.Session)
上面说到了SessionFactory
能够创建Session
,处理之外还有什么方式可以或得到呢?sessionFactory.opensession()
一般的CRUD我们都是使用的这个操作,只有增删改需要使用事务,查询不需要,在查询时候食用事务,会将修改的数据提交更新数据库。sessionFactory.getCurrentSession()
如果存在多个拥有session
的方法之间相互调用,这个时候就存在多个session对象和事务了,保证不了CRUD操作只在一个session对象和事务中操作,那么这个时候就需要使用这个方法获得session对象了。
1 | Session session=sessionfactory.getCurrentSession(); |
注意:如果使用sessionFactory.getCurrentSession()
需要注意以下内容:在hibernate的配置文件当中必须加上<property name="current_session_context_class">thread</property>
这个配置。不需要写session.close()
在事务提交的内部已经关闭。CRUD操作都需要事务,保证了业务操作的安全性,在整个方法当中一个session和一个事务。
配置Hibernate
加入jar包,编写 hibernate.cfg.xml
文件
- 引入jar包
我在这里使用的是hibernate4.3.11
的版本,下面是我的使用jar包的截图。
注意需要加入MySQL的驱动jar包。
- 编写
hibernate.cfg.xml
配置文件
多的不说,先将配置文件放上来 ,再来解释解释吧!
1 | <?xml version="1.0" encoding="UTF-8"?> |
这里是最基本的配置,数据库相关配置,控制台格式化打印SQL语句,实体类映射,在这里使用的是注解,就不需要为每一个实体类配置一个xml文件了。
编写实体类
在上面hibernate.cfg.xml
的配置文件当中有一个mapping
的映射配置,现在我们就编写上面说到的那个实体类Student
。
1 | /** |
如上面配置所示,@Entity
表示当中为一个实体类,对应映射数据库表为@Table(name = "student")
中的student
表,主键自增,配置相应生成策略,该实体类当中属性和表中对应字段关联。
好了,到目前为止,所有的配置都已经完成。下面我们就来编写一个Main
主方法来使用Hibernate
。
使用Hibernate
新建一个Main
主方法来获得Configuration
对象,然后获得SessionFactory
,通过SessionFactory
获得我们所需的session
对象,然后通过这个session
对象来对数据进行CRUD的操作。
1 | /** |
注意此处的config.getProperties()
是用来加载上面配置的hibernate.cfg.xml
文件,配置文件放在src根目录下,或者在IDEA
中新建resources
文件夹使其Make Directory as
成为Resources Root
根目录。
运行上面的程序,我们将获得一个session
对象。
1 | SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]]; |
此时都已经配置好了hibernate
了,下面我们就来根据这个session
来对数据库进行CRUD操作。
CRUD操作
查询
HQL查询所有记录
在hibernate
当中我们可以使用HQL
语句来查询出我们需要的结果。
1 | /** |
对上面的Query query = session.createQuery("from Student");
语句进行说明:from Student
的这个Student
为实体类的类名,而不是表明,使用HQL语句是对实体类进行操作,而不是对数据库表进行操作,这就是对象关系映射(ORM).
查询结果如下:
1 | Hibernate: |
第一部分为hibernate.cfg.xml
当中配置的show_sql
和format_sql
,然后第二部分就是我们使用HQL语句查询出来的student的信息(我在实体类当中重写了toString()方法,所以为这种输出格式)。
根据表主键ID查询单条记录
很多情况下我们需要通过ID主键查询该表当中唯一的一条记录,那么就需要使用到session当中的get()
方法。具体使用方法如下:
1 | /** |
控制台当中显示的结果如下:
1 | Hibernate: |
SQL语句查询——查询字段和实体类完全匹配
上面第一个说到了使用HQL语句查询记录,但是很多情况下我们还是会使用SQL语句查询的,这样的场景hibernate
还是支持的。但是有一点需要注意,使用SQL语句查询时候如果查询字段和实体类完全匹配,仍然可以返回实体类进行使用,如果不完全匹配,看下一个例子。
1 | /** |
上面select * from student
查询的是表明而不是实体类名,同时返回的结果集当中字段和实体类完全匹配,就可以直接使用addEntity()
方法将结果集放入实体类对象当中。控制台打印如下:(sql 语句为自己书写的SQL语句)
1 | Hibernate: |
SQL语句查询——查询字段和实体类不完全匹配
上面的例子说了,SQL语句查询的结果集和实体类完全匹配的情况,但是很多时候,我们查询只需要我们需要的字段,而不需要所有的字段,就不能使用上面那种方式了,不能讲查询结果集放入实体类了,返回的结果是对象集合Object[]
了。
1 | /** |
如上面所示返回的结果是一个Object[]
数组。
1 | Hibernate: |
HQL查询时候使用事务
通常情况下使用查询时候不需要事务的,但是在查询的时候使用事务会将查询后修改的数据同步到数据库。
1 | /** |
执行上面的程序,在数据库当猴子那个所有记录的pwd
字段的值都被修改成123456
,同时同步到数据库当中。通过控制台输出的SQL语句可以看出,这段程序执行了查询后,又执行了更新操作。
1 | Hibernate: |
HQL查询时使用参数
通常情况下使用查询语句时候,都是需要使用参数的。有两种方式进行操作:
- 使用
?
作为占位符
1 | /** |
注意hibernate
当中是从 0
开始的,跟jdbc不同。直接结果为查询loginName = xiaohong
的学生信息。
1 | Hibernate: |
- 使用
变量
作为占位符。
1 | /** |
此时使用的是loginName = :name
这样一个name
变量占位符,下面的query.setString("name", "xiaohong");
当中同样使用name
这个变量。注意使用变量时候需要在前面添加一个:
.
结果如上不变。
新增
由于之前我们配置实体类当中生命了主键的生成策略,因此在这里使用时候不需要设置主键。同时进行新增
操作时候需要使用事务。
1 | /** |
通过控制台打印日志新增数据成功。
1 | Hibernate: |
修改
进行修改操作时候,可以先将数据查询出来,然后进行修改。这是使用update(Object o)
时候的操作,数据已经存在于数据库当中。还可以使用saveOrUpdate(Object o)
当数据不存在时候进行save操作,存在时进行update操作。
- 使用对象进行操作
1 | /** |
上述操作先进行查询get()
,然后再进行saveOrUpdate()
当中的update()
操作。从控制台日志查看SQL记录。
- 使用HQL进行操作
1 | /** |
删除
删除操作,直接通过主键进行删除。同时提交事务。
1 | /** |
上述代码块,先通过主键查询到对象,然后再进行删除。控制台记录如下:
1 | Hibernate: |
后序
通过上面的配置和学习,了解了hibernate
的基本配置和使用。下一节将总结一下hibernate
当中的分页、级联操作、关联查询
等问题。同时从上面的操作中看出session
对象伴随着CRUD
操作,那么之后也会说明hibernate
当中对象的各种状态、生命周期以及它们之间是如何转换的。
学习之路,任重道远,加油。
联系
聪聪的独立博客 ,一个喜欢技术,喜欢钻研的95后。如果你看到这篇文章,千里之外,我在等你联系。