http://blog.csdn.net/yerenyuan_pku/article/details/65103203

可在度娘上摘抄如下文字:

Hibernate的核心类和接口一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。这6个核心类和接口在任何开发中都会用到。

还记得上一篇文章讲的是《Hibernate的配置详解》,本文继续在其基础之上讲解Hibernate常用的API。

Configuration

Configuration类主要是用于加载Hibernate的核心配置文件。 
为了和之前写的单元测试类——HibernateTest1.java相区分,我们这儿在cn.itheima.test包下再创建一个单元测试类——HibernateTest2.java。像之前写的这样的代码:

public class HibernateTest2 {@Testpublic void test1() { // 创建Configuration来加载配置文件 Configuration config = new Configuration().configure(); ....... } }

主要是加载src目录下的hibernate.cfg.xml配置文件。 
如果现在有人标新立异,他不是将Hibernate的核心配置文件命名为hibernate.cfg.xml,而是将其命名为比如说是my.xml,假设该文件同样是位于src目录下。那么应该像这样加载该文件:

public class HibernateTest2 {@Testpublic void test1() { // 创建Configuration来加载配置文件 Configuration config = new Configuration().configure("my.xml"); // 加载指定名称的配置文件 ....... } }

可归纳为:

Configuration config=new Configuration().config(核心配置文件名称); // 加载指定名称的配置文件

但我们又何必这么写昵?你说是不是? 
由于我们将实体类(Customer.java)的映射配置文件配置在Hibernate的核心配置文件中:

<hibernate-configuration><session-factory>......<!-- 配置hibernate的映射文件所在的位置 --> <mapping resource="cn/itheima/domain/Customer.hbm.xml" /> </session-factory> </hibernate-configuration>

所以在编写程序代码的时候,勿须手动加载映射配置文件——Customer.hbm.xml。映射配置文件一般情况下是放置在实体类所在包下的,但是不这样做也是可以的,因为可以指定路径。所以即使在Hibernate的核心配置文件中没有映射文件的配置,也是可以手动加载映射配置文件的。

public class HibernateTest2 {// 测试手动加载映射配置文件@Testpublic void test1() { // 1.创建Configuration来加载配置文件 Configuration config = new Configuration().configure(); // 手动加载映射 config.addResource("cn/itheima/domain/Customer.hbm.xml"); // 直接加载映射配置文件 // 2.得到SessionFactory SessionFactory sessionFactory = config.buildSessionFactory(); // 3.得到Session Session session = sessionFactory.openSession(); // 开启事务 session.beginTransaction(); Customer c = session.get(Customer.class, 1); System.out.println(c); // 事务提交 session.getTransaction().commit(); // 关闭Session session.close(); // 关闭SessionFactory sessionFactory.close(); } }

当然了,我们还可以这样做:

public class HibernateTest2 {// 测试手动加载映射配置文件@Testpublic void test1() { // 1.创建Configuration来加载配置文件 Configuration config = new Configuration().configure(); // 手动加载映射 config.addClass(Customer.class); // 这种方式它会直接在实体类所在包下查找规范的映射配置文件 // 2.得到SessionFactory SessionFactory sessionFactory = config.buildSessionFactory(); // 3.得到Session Session session = sessionFactory.openSession(); // 开启事务 session.beginTransaction(); Customer c = session.get(Customer.class, 1); System.out.println(c); // 事务提交 session.getTransaction().commit(); // 关闭Session session.close(); // 关闭SessionFactory sessionFactory.close(); } }

只是这种情况下,Customer.hbm.xml映射配置文件须放置在实体类所在包下。 
我们之前也说过对于Hibernate的核心配置文件它有两种方式:

  1. hibernate.cfg.xml
  2. hibernate.properties

假如Hibernate的核心配置文件采用的是hibernate.properties这种方式,那么如何加载该配置文件昵?

public class HibernateTest2 {@Testpublic void test1() { Configuration config = new Configuration(); ....... } }

结论:

Configuration config=new Configuration(); // 主要加载的是src目录下的hibernate.properties配置文件

那么问题来了,我们是在hibernate.cfg.xml文件中有(映射)了xxx.hbm.xml文件的位置。但如果我们使用的是hibernate.properties这种核心配置文件,那么它又如何加载映射配置文件昵?不用我说,大家应该都知道了。

SessionFactory

首先SessionFactory它的获取是通过Configuration得到:

// 1.创建Configuration来加载配置文件
Configuration config = new Configuration().configure(); // 2.得到SessionFactory SessionFactory sessionFactory = config.buildSessionFactory();

可在度娘上摘抄如下有关SessionFactory的文字:

SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。

下面我们来着重分析以上这段话,我是从这几句话入手的。

它充当数据存储源的代理,并负责创建Session对象。

我们通过查看Hibernate的帮助文档,可发现通过SessionFactory可以得到Session有两种方式:

  1. 通过SessionFactory获得Session方式一: 

    注意:这是从连接池中获取一个连接。
  2. 通过SessionFactory获得Session方式二: 

    注意:这是获取一个与线程绑定的Session(即线程安全的Session)。

需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够

我的理解——SessionFactory它不是轻量级的,所以不要频繁创建关闭它。在一个项目中有一个SessionFactory就可以了,通过SessionFactory来获取Session进行操作。那么问题来了,怎样可以保证在一个项目中所使用的SessionFactory是同一个哪? 
可在cn.itheima.utils包下创建一个工具类——HibernateUtils.java,其代码为:

public class HibernateUtils {private static Configuration config;private static SessionFactory sessionFactory; static { config = new Configuration().configure(); sessionFactory = config.buildSessionFactory(); } public static Session openSession() { return sessionFactory.openSession(); } }

好了,来测试HibernateUtils工具类的使用吧!

public class HibernateTest2 {// 测试HibernateUtils工具使用@Testpublic void test2() { // 得到Session Session session = HibernateUtils.openSession(); // 开启事务 session.beginTransaction(); Customer c = session.get(Customer.class, 1); System.out.println(c); // 事务提交 session.getTransaction().commit(); // 关闭Session session.close(); // 注意:SessionFactory不要关闭,它开启就别关了,除非说你的项目结束了,否则,我们就不关闭它 } }

SessionFactory内部还维护了一个连接池,如果我们要想使用c3p0连接池,应该怎样做昵?也即在Hibernate中如何使用c3p0连接池?

  1. 我们要导入c3p0的相关jar包。 
    在lib/options下有关于c3p0连接池所需jar包,如下: 
  2. 在hibernate.cfg.xml文件中配置c3p0连接池。

    <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- C3P0连接池的配置 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 最大连接数 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 最小连接数 --> <property name="hibernate.c3p0.timeout">120</property> <!-- 超时时间 --> <property name="hibernate.c3p0.idle_test_period">3000</property> <!-- 空闲连接(等待)时间,以秒为单位 -->

    注意:有些童鞋可能忘记了这样的配置:

    <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
  3. 这当然是不可取的,以上配置是在设置连接池提供者,如没设置,默认为org.hibernate.connection.DriverManagerConnectionProvider,它会帮助我们从Hibernate本身维护的连接池里面获取连接。但是现在我们要用C3P0连接池,所以这样的设置是必不可少的,这样的话,Hibernate才知道你现在要用的是C3P0连接池!

当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。

我觉得这是要涉及分布式数据库的节奏,对此我也是小白。只是知道怎么配置而已,大概类似于一下配置吧!

<hibernate-configuration><session-factory> ...... </session-factory> <session-factory name="xxx"> ...... </session-factory> </hibernate-configuration>

Session

从度娘摘抄如下:

Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。

那么问题来了,我们如何解决session的安全问题?我们只需要在方法内部来使用Session就可以。 
那么问题又来了,Session如何获取到昵?在讲SessionFactory接口时,我们就介绍了通过SessionFactory获得Session的两种方式,虽然这两种方式都可以获取到一个Session对象,那么这两种方式有什么区别呢?

  • SessionFactory.openSession();:相当于直接通过SessionFactory创建一个新的Session,使用完成后要手动调用close()方法来关闭。
  • SessionFactory.getCurrentSession();:获取一个与线程绑定的Session,当我们提交事务或事务回滚后会自动关闭。

Session的常用方法

  • save():保存对象
  • update ():修改操作
  • delete():删除
  • get()/load():根据id进行查询
  • avenOrUpdate():执行save或update操作
  • createQuery():获取一个Query对象
  • CreateSQLQUery():获取一个可以操作SQL的SQLQuery对象
  • createCriteria():取一个Criteria对象,它可以完成条件查询

以上的许多方法,我们都已接触过,不过后面随着我们学习的精进,还会对他们越来越熟悉。

Transaction

Transaction接口主要用于管理事务,它是Hibernate的事务接口,对底层的事务进行了封装。使用它可以进行事务操作。例如:

  • 事务提交:commit()
  • 事务回滚:rollback()

问题一:如何获取一个Transaction对象昵?可通过如下代码获得:

Transaction transaction = session.beginTransaction();

问题二:如果在程序中没有开启事务,是否存在事务?存在事务,默认session的每一个操作就会开启一个事务。并且默认情况下事务是不会自动提交的。相当于在Hibernate的核心配置文件中又如下配置:

<!-- 用于设置事务提交方式,默认是不自动提交的 -->
<property name="hibernate.connection.autocommit">false</property>

如果我们将其修改为:

<property name="hibernate.connection.autocommit">true</property>

则此时事务就会自动提交。

Query

从度娘上可摘抄到这样的文字:

Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。

我们主要通过Query完成查询操作。通过Query即可以执行hql语句,如下:

Query query = session.createQuery("hql语句");

又可以执行本地sql语句:

SQLQuery sqlQuery = session.createSQLQuery("本地sql语句");

注意:SQLQuery是Query的子类。

查询所有操作——使用HQL

为了和之前写的单元测试类——HibernateTest1.java和HibernateTest2.java相区分,我们这儿在cn.itheima.test包下准备再创建一个单元测试类——HibernateTest3.java。 
使用HQL语句完成查询所有客户的操作,代码如下:

public class HibernateTest3 {// 使用hql完成查询所有操作@Testpublic void test1() { Session session = HibernateUtils.openSession(); Query query = session.createQuery("from Customer"); // from后面是类名 List<Customer> list = query.list(); System.out.println(list); session.close(); } }

注意:from后面是类名。

分页查询

在执行分页查询时,我们试着向t_customer表中插入100条记录。代码如下:

public class HibernateTest3 {// 向表中插入100条记录@Testpublic void test2() { Session session = HibernateUtils.openSession(); // 不要忘记开事务 session.beginTransaction(); for (int i = 0; i < 100; i++) { Customer c = new Customer(); c.setName("姓名" + i); c.setSex("男"); c.setAddress("北京"); session.save(c); } session.getTransaction().commit(); session.close(); } }

接下来,就来分页查询,要求:一页显示10条,但我们要得到第二页的数据。

public class HibernateTest3 {// 分页查询// 一页显示10条,要得到第二页数据@Testpublic void test3() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 一页显示10条,要得到第二页数据 Query query = session.createQuery("from Customer"); query.setFirstResult(10); // 从第几条开始,即开始位置,从0开始计数 query.setMaxResults(10); // 本次查询结果回显的条数 List<Customer> list = query.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

查询指定列信息

如果想如下这样子查询指定列的信息:

public class HibernateTest3 {// 查询指定列信息@Testpublic void test4() { Session session = HibernateUtils.openSession(); session.beginTransaction(); Query query = session.createQuery("select name,address from Customer"); // 这时我们得到的不再是Customer对象,而是Object[] List<Object[]> list = query.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

可以发现select name,address from Customer得到的是List<Object[]>结果,我们可不可以得到List<Customer>这样的结果昵?我们要想得到这个结果,可以使用Hibernate中的投影查询。我们只须在Customer类中提供name与address作为参数的构造方法就可以了,注意无参数构造也要有。而且HQL语句要写成select new Customer(name,address) from Customer

public class HibernateTest3 {// 查询指定列信息@Testpublic void test4() { Session session = HibernateUtils.openSession(); session.beginTransaction(); Query query = session.createQuery("select new Customer(name,address) from Customer"); List<Customer> list = query.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

条件查询

条件查询,可以使用where关键字。 
例,需求:查询name=姓名0的客户。 
首先通过无名称参数来完成这个需求。

public class HibernateTest3 {// 条件查询,可以使用where关键字@Testpublic void test5() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 查询name=姓名0的信息 Query query = session.createQuery("from Customer where name=?"); // 这是一种无名称参数 // 要对参数进行赋值 query.setParameter(0, "姓名0"); List<Customer> list = query.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

虽然我们可以查询出来,但我们有没有想过name=姓名0的客户即使查出来也只有一个,我们有必要把它放在List集合中嘛?如果查询结果可以保证就是唯一 的,我们可以使用query. uniqueResult()来得到一个单独对象。

public class HibernateTest3 {// 条件查询,可以使用where关键字@Testpublic void test5() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 查询name=姓名0的信息 Query query = session.createQuery("from Customer where name=?"); // 这是一种无名称参数 // 要对参数进行赋值 query.setParameter(0, "姓名0"); // 如果能保证结果就是唯一的,那么可以使用另外一种方法 Customer customer = (Customer) query.uniqueResult(); System.out.println(customer); session.getTransaction().commit(); session.close(); } }

然后再通过有名称参数来完成这个需求。

public class HibernateTest3 {// 条件查询,可以使用where关键字@Testpublic void test5() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 查询name=姓名0的信息 Query query = session.createQuery("from Customer where name=:myname"); // 这是一种有名称参数 // 对有名称参数进行赋值 query.setParameter("myname", "姓名0"); // 如果能保证结果就是唯一的,那么可以使用另外一种方法 Customer customer = (Customer) query.uniqueResult(); System.out.println(customer); session.getTransaction().commit(); session.close(); } }

执行本地SQL

要想执行本地sql,可以这样子做:

SQLQuery sqlQuery=session.createSqlQuery(String sql);

需求一:执行本地sql,查询全部客户。 
我想初次写代码完成这个需求,许多人都会这么写吧!

public class HibernateTest3 {// 执行本地sql,查询全部@Testpublic void test6() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 执行 select * from t_customer; SQLQuery sqlQuery = session.createSQLQuery("select * from t_customer"); List<Object[]> list = sqlQuery.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

可以发现select * from t_customer得到的是List<Object[]>结果,我们可不可以得到List<Customer>这样的结果昵?可以,代码如下:

public class HibernateTest3 {// 执行本地sql,查询全部@Testpublic void test6() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 执行 select * from t_customer; SQLQuery sqlQuery = session.createSQLQuery("select * from t_customer"); // 想要将结果封装到Customer对象中 sqlQuery.addEntity(Customer.class); List<Customer> list = sqlQuery.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

需求二:执行本地sql,条件查询。例如查询name=姓名1的客户。

public class HibernateTest3 {// 执行本地sql,条件查询@Testpublic void test7() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 执行 select * from t_customer where name=?; SQLQuery sqlQuery = session.createSQLQuery("select * from t_customer where name=?"); // 对参数进行赋值 sqlQuery.setParameter(0, "姓名1"); // 想要将结果封装到Customer对象中 sqlQuery.addEntity(Customer.class); /* List<Customer> list = sqlQuery.list(); System.out.println(list); */ Customer customer = (Customer) sqlQuery.uniqueResult(); System.out.println(customer); session.getTransaction().commit(); session.close(); } }

Criteria

根据度娘所得:

Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。

首先我要想使用Criteria,必须得到Criteria。可这么做:

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

需求一:查询所有客户。

public class HibernateTest3 {// 测试Criteria@Testpublic void test8() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 得到Criteria Criteria criteria = session.createCriteria(Customer.class); // 查询所有 List<Customer> list = criteria.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

需求二:分页查询。 
分页查询操作与query的方法一样。通者自通。 
需求三:多条件查询。例如查询name=”姓名1”并且address=”上海”的客户。

public class HibernateTest3 {// 测试Criteria@Testpublic void test8() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 得到Criteria Criteria criteria = session.createCriteria(Customer.class); // 多条件查询 // 1.查询name='姓名1' criteria.add(Restrictions.eq("name", "姓名1")); // where name="姓名1"; // 2.查询address='上海' criteria.add(Restrictions.eq("address", "上海")); // where name="姓名1" and address="上海" Customer customer = (Customer) criteria.uniqueResult(); session.getTransaction().commit(); session.close(); } }

需求四:多条件查询。例如查询name=’姓名1’或者address=’上海’的客户。

public class HibernateTest3 {// 测试Criteria@Testpublic void test8() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 得到Criteria Criteria criteria = session.createCriteria(Customer.class); // 多条件查询 // 查询name='姓名1'或者address='上海' criteria.add(Restrictions.or(Restrictions.eq("name", "姓名1"),Restrictions.eq("address", "上海"))); List<Customer> list = criteria.list(); System.out.println(list); session.getTransaction().commit(); session.close(); } }

总结:我们使用Criteria可以更加面向对象地去操作,它非常适合进行多条件组合查询。但感觉没什么鸟用!

转载于:https://www.cnblogs.com/telwanggs/p/6963683.html

( 转)Hibernate常用API相关推荐

  1. Java程序员从笨鸟到菜鸟之(五十二)细谈Hibernate(三)Hibernate常用API详解及源码分析--csdn 曹胜欢...

    新接触一个框架的目的就是想利用这个框架来为我们做一些工作,或者是让他来简化我们的工作,利用这个框架无非就是要利用这个框架所给我们提供的API去操作我们的数据,所以利用一个框架的好坏很大一部分取决于你对 ...

  2. Hibernate一级缓存常用API

    一级缓存特点: 当我们通过session的save,update saveOrupdate进行操作时,如果一级缓存中没有对象,会将这些对象从数据库中查询到,存储到一级缓存. 当我们通过session的 ...

  3. 【java】简述CGLIB常用API

    1.概述 转载:简述CGLIB常用API 类似:[Spring]CGLIB动态代理 CGLIB,即Code Generation Library,是一个强大的.高性能的代码生成库.其被广泛应用于AOP ...

  4. c++ string replace_JAVA应用程序开发之String类常用API

    [本文详细介绍了JAVA应用开发中的String类常用API,欢迎读者朋友们阅读.转发和收藏!] 1 基本概念 API ( Application Interface 应用程序接口)是类中提供的接口, ...

  5. 常用API(Object、String、StringBuffer、用户登陆注册)

    常用API 今日内容介绍 u Object u String u StringBuilder 第1章 Java的API及Object类 在以前的学习过程中,我们都在学习对象基本特征.对象的使用以及对象 ...

  6. Selenium Web 自动化 - Selenium常用API

    Selenium Web 自动化 - Selenium常用API 2016-08-01 目录 1 对浏览器操作   1.1 用webdriver打开一个浏览器   1.2 最大化浏览器&关闭浏 ...

  7. 【Netty】NIO 网络通信 SelectionKey 常用 API 简介

    文章目录 I . SelectionKey 简介 II . SelectionKey 事件简介 III . SelectionKey 常用 API 简介 I . SelectionKey 简介 1 . ...

  8. JavaScript一些常用 API整理汇总

    JavaScript一些常用 API整理汇总 Array new Set() 数组去重 const arr = [3,4,4,5,4,6,5,7]; console.log(new Set(arr)) ...

  9. Math工具类常用API使用案例

    对基础API的使用能够熟练掌握,能极大提高开发效率.有些知识是很简单,但并不是我们不学习和掌握它们的借口,越是简单的东西,在关键时刻越是能起到至关重要的作用,就好比我们花很长时间解决的一个BUG,结果 ...

最新文章

  1. 三角网导线平差实例_第讲(三角网条件平差.ppt
  2. C#中的三种timer
  3. 华为手机asph啥机型_华为正式宣布!19款机型开启新系统内测,你的手机榜首有名吗?...
  4. 线上Java应用排查和诊断规范
  5. IOS登陆+注册+抽奖+排行榜
  6. 统计消息总数_2019年度我国出国留学人员总数为70.35万人
  7. kettle 提交数据量_Kettle数据同步速度调优记录
  8. 吴恩达神经网络和深度学习-学习笔记-11-Momentum梯度下降法
  9. 使用PL/SQL Developer 远程连接Oracle数据库出现 “无监听程序“错误 的解决办法
  10. 名正则言顺�谈服装品牌名称(三)
  11. @Profile 注解的介绍
  12. APP在后台被系统回收后,如何重新启动
  13. ETH:2018年06月03日《ETH技术及其应用大会》总结(转自CSDN灵钛科技)
  14. python图像轮廓识别_Python+OpenCV图像处理(十六)—— 轮廓发现
  15. java计算机毕业设计网上汽车售票系统源码+数据库+lw文档+系统+部署
  16. ScyllaDB 1.2 国内安装更新源发布
  17. 北京创客空间 BEIJING MAXPACE的小站
  18. Linux命令之dmidecode命令
  19. 在IB国际高中学IB哲学是种什么样的体验
  20. 指 针 含 义 详 细 解 读,看完要么收获满满,要么一头雾水,看你会处于哪种状态

热门文章

  1. Spark Streaming之容错机制以及事务语义
  2. (46)FPGA对数运算符(V代码实现)
  3. 1006.c++中结构体赋值碰到的bug
  4. Nginx基本数据结构之ngx_hash_t
  5. 创建一个路由节点struct fib_node
  6. KG—ARM-Thumb子程序调用规则—ATPCS
  7. 哈希表、冲突处理方法、查找长度
  8. Java学习日报 — 问题记录 — 2021/12/14
  9. Linux的常用指令
  10. ue java_Ue java 配置