hibernate操纵数据库常用方法 及 hibernate对象的三种状态
在dao层使用hibernate语言来与数据库进行访问,hibernate作为面向对象思想开发的dao层框架其理解也需要以面向对象的思想来看待 使用。hibernate不仅支持使用者使用他提供的对象来操作 还支持使用者使用HQL语言访问数据库。
下面介绍简单的增删改:
public class test {
Configuration conf = new Configuration().configure();
// 根据配置信息,创建 SessionFactory对象
SessionFactory sessionFactory = conf.buildSessionFactory();
Session session=sessionFactory.openSession();
//2开启事务
Transaction tx = session.beginTransaction();
User u=new User();
user.setUser_id(2);
tx.commit();
session.close();
}
上述代码创建sessionFactory很麻烦而且代码重复 所以可以使用hibernateSessionFactory 提供的getSession()方法
public class testUpdate {
Session session = HibernateSessionFactory.getSession();
//设置主键指定update
user.setId(2);
user.setUser_name("dabai");
Transaction trans = session.beginTransaction();
session.update(news);
trans.commit();
HibernateSessionFactory.closeSession();
}
这里要说一下 hibernate的update方法比较效率低 先查在更新 因为它提供一个方法叫saveorupdate 如名所示 当存在它更新不存在它创建一条记录,怎么实现?先查在做后续操作,查到了主键就更新否则就添加,那如果不设置主键,再使用saveorupdate()呢,这里就牵扯到hibernate的持久化对象了,稍后会作解答。先看删除操作
public class testUpdate {
Session session = HibernateSessionFactory.getSession();
//设置主键指定delete
user.setId(2);
user.setUser_name("dabai");
Transaction trans = session.beginTransaction();
session.delete(user);
trans.commit();
HibernateSessionFactory.closeSession();
}
查询:查询方法很多很多很多
public class testUpdate {
Session session = HibernateSessionFactory.getSession();
// 此处from的不是table名 是实体类
Query query = session.createQuery("from User");
//2 调用query的方法得到结果
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
trans.commit();
HibernateSessionFactory.closeSession();
}
上述query不是from表名是实体名 虽然hibernate官方说要from实体名 但是!!我试过表名同样有效
接下来介绍下hql 和使用jdbcConnection比较类似 什么模糊查询啊 limit查询啊都能用 order by count sum avg min max 查询啊 就写sql就完事了 同样不能from表名 我也试了下还是能用 不过尽量不要写表名 编码规范
public class testHql {
Session session = HibernateSessionFactory.getSession();
// 此处from的不是table名 是实体类
String hql = "from User u where u.username = ?";
Query query = session.createQuery(hql);
// 参数设置方法可以参照jdbc的写法 hibernate从0开始 jdbc的参数从一开始 可以设置多个参数 嫌麻烦的话后面有简单的
query.setParameter(0,"dabai");
//3 调用方法得到结果
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
trans.commit();
HibernateSessionFactory.closeSession();
}
可以看出来query返回的都是list形式的 而且都经过封装成对象返回过来,于是就牵扯到一个问题,当只需要查询某个字段或几个字段时 且字段组合无法构成Java实体怎么操作?也很简单 返回的东西给它成object就完事了不过遍历要麻烦一些,因为返回结果写成List<Object[]> 形式遍历时一个object就是查询出来的一个元组 用Arrarys.toString可以看到打印的内容是查询的字段的一行(题外话 实体类最好覆写一下toString方法 这有助于调试 测试 反正写了不吃亏)
下面是个很重要的内容Criteria 和DetachedCriteria 放在最后那就注定了Criteria一家的不平凡。其中后者是离线的 前者是在线的 DetachedCriteria可以在web层创建 当作参数传到dao层 ,这意味着你使用DetachedCriteria可以没有session。两个Criteria都提供方法.forClass().以求保证查询对象是哪一个。Criteria 和 DetachedCriteria 都能使用 Criterion 和 Projection 设置查询条件。

上面是Criteria的一个方法 getHibernateTemplate是hibernate提供的一个方便abstract类中的一个对象具体看下图
通常我们会这样写 这样就能在BaseDaoImpl中使用提供的各种方法了
public class BaseDaoImpl extends HibernateDaoSupport {
@Resource
public void setmySessionFactory(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
}


总而言之就是getHibernateTemplate很好用 你可以用 我们继续谈Criteria 和DetachedCriteria 两个我只讲DetachedCriteria 因为Criteria能做的Detached Criteria也能 然后我主要说一下我认为比较重要的方法
关于创建:
通过forClass和entityname讲道理没什么不同不稀奇
关于setProjection:这里是service层的一个方法
dc是web层传来的一个DetachedCriteria 这里dc.setProjection(Projections.rowCount());是告诉hibernate不要查字段值查这个Class对应的table中有多少条记录,否则hibernate会查所有的字段然后再统计count给你,很影响性能。最后dc.setProjection(null);是清除前面设置的rowCount()否则你后续使用这个DetachedCriteria查询所有的结果都是空,当然你可以选择再创建一个DetachedCriteria dcc;
关于Criteria的混合使用
DetachedCriteria dc =DetachedCriteria.forClass(User.class);
dc.setProjection(Projections.rowCount());
dc.setProjection(Projections.groupProperty("name"));
List results = dc.list();
上述代码可以计算各name的user的个数 我也是从别的老哥那里看到的。hibernate方法使用很灵活 有时候多到我想写hql,徘徊于用哪个方法。
还想提一点的就是前面介绍的getHibernateTemplate还能写hql 太好用了!具体参照代码 注意参数变成了final类 否则会报错 uniqueResult顾名思义就是告诉hibernate就一个返回值强转就完事了 ,当不知道返回的会是几个值时建议用query.list()不然会报错的;
query.list()只限于使用查询,当hql语句是update insert delete之类的有关事务的操作时 使用query.executeUpdate()
public User checkUser(final User u) {
//hql 查询
return getHibernateTemplate().execute(new HibernateCallback<User>() {
@Override
public User doInHibernate(Session session) throws HibernateException {
String hql="from User where username=? and password=?";
Query query=session.createQuery(hql);
query.setParameter(0, u.getUsername());
query.setParameter(1, u.getPassword());
User returnu = (User)query.uniqueResult();
return returnu;
}
});
}
还有getHibernateTemplate.find()方法,参数可以设置两个 一个时hql语句,后一个接参数
如getHibernateTemplate().find(" from Institution"); 及查询Institution对应的表中所有数据 返回值是list 可以指定list的数据类型List<Institution>,需要强转
最后说 hibernate中对象的三种状态:
临时状态 (Transient)、持久状态(Persistent)、游离状态(Detached)。持久状态对象也叫PO (PersistentObject) 临时状态和游离状态的对象也叫VO(ValueObject)
一、临时状态
临时状态对象是通过实例化的方式注入到内存中,也就是通过New的方式来开辟内存。
临时对象是孤立在内存上的,它不与数据库中的数据有任何关系。比如:
UserEntity userEntity=new UserEntity();
这个时候,userEntity对象就称之为临时对象。如果没有任何引用,jvm将其进行GC回收。
二、持久状态
持久状态的对象是该对象和数据库中的数据存在关联关系,并且拥有持久化的标识。
通过session.get()或者session.load()等获取的数据对象,就是持久化状态的对象。
值得注意的是:如果对持久化对象进行了修改,并没有执行事务提交,这时持久化对象的数据不会同步到数据库中的。
三、游离状态
当某个持久化对象与session断开之后,那么此时,该持久化对象就称之为游离对象。
通常通过session.get()或者session.load()等方式获取的数据后,执行了 session.close()等操作,那么此时获取的持久化对象就转换为游离对象了。
上述是文字解释不形象这样说:对于一个User对象,user对象由new关键字创建,此时还未与Session进行关联,它的状态称为瞬时态;在执行了session save(user)操作后,book 对象纳入了Session 的管理范围,这时的user对象变成了持久态对象,此时Session的事务还没有被提交:程序执行完commit()操作并关闭了Session 后,customer对象与Session的关联被关闭,此时customer对象就变成了脱管态。
关于hibernate给对象设置主键在瞬时还是持久 我看了下有的觉得是这个过程中赋予id的我比较认同,因为在添加到数据库时必须给出id,所以瞬时到持久态间转换赋予id比较合适
hibernate操纵数据库常用方法 及 hibernate对象的三种状态的更多相关文章
- 【Java EE 学习 45】【Hibernate学习第二天】【对象的三种状态】【一对多关系的操作】
一.对象的三种状态. 1.对象有三种状态:持久化状态.临时状态.脱管状态(游离状态) 2.Session的特定方法能使得一个对象从一个状态转换到另外一个状态. 3.三种状态的说明 (1)临时状态:临时 ...
- Hibernate 系列 07 - Hibernate中Java对象的三种状态
引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...
- hibernate对象的三种状态
对于hibernate,我想不在这里讲解了,我们就直接进入主题 在这里我将要说的是"hibernate对象的三种状态",对象是我们十分熟悉的,对吧!而对于对象它有三种状态 分别是瞬 ...
- Hibernate之对象的三种状态
Hibernate之Java对象的三种状态 一.简述 本博文大部分的思想和内容引子CSND上名为 FG2006 这位大神的文章,连接地址为:http://blog.csdn.net/fg2006/ar ...
- Hibernate(六)__对象的三种状态
瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象. 持久(persistent):数据库中有数据与之对应,当前 ...
- Hibernate 对象的三种状态
hibernate对象的三种状态: (一) 瞬时(临时)状态: 对象被创建时的状态,数据库里面没有与之对应的记录! (二) 持久状态: 处于session的管理中,并且数据库里面存在与之对应的 ...
- HIbernate学习笔记(二) hibernate对象的三种状态与核心开发接口
1.在hibernate中持久化对象有三个状态,这个面试时可能会问到: (1)transient瞬时态:在数据库中没有与之匹配的数据,一般就是只new出了这个对象,并且在session缓存中也没有即此 ...
- Hibernate持久化对象的三种状态深入理解
关于OID hibernate缓存是一个map,他会根据OID作为缓存对象的key,我们的映射文件中<id>标签指定的属性值会作为OID 持久化对象的三种状态 为了方便理解,Hiberna ...
- 【SSH系列】-- Hibernate持久化对象的三种状态
在上一篇博文中,小编主要简单的介绍了[SSH系列]--hibernate基本原理&&入门demo,今天小编来继续介绍hibernate的相关知识, 大家知道,Java对象的生命周期,是 ...
随机推荐
- EOS智能合约授权限制和数据存储
EOS智能合约授权限制和数据存储 在EOS合约中,调用合约需要来自账户的授权,同时还要指定需要调用的动作.当然,有的合约并不是所有账户都可以调用的,这就需要用到授权限制.接下来我们就来看看如何限制合约 ...
- MySQL服务使用
MySQL服务使用 1. 启动服务 启动服务: service mysql start 或者 sudo /etc/init.d/mysql start 2. 关闭服务 关闭服务: service my ...
- LeetCode算法题-Binary Tree Level Order Traversal II(Java实现)
这是悦乐书的第165次更新,第167篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第24题(顺位题号是107).给定二叉树,返回其节点值的自下而上级别顺序遍历(即从左到右 ...
- 平方根的C语言实现(一) —— 浮点数的存储
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7203254.html 作者:窗户 Q ...
- C - 继续畅通工程 最小生成树
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经 ...
- 利用碎片化时间Get Linux系统
利用碎片化时间Get Linux系统 起初,我做着一份与IT毫无关系的工作,每月领着可怜的工资,一直想改变现状,但无从下手,也就是大家熟知的迷茫.我相信,每一个人都会或多或少的经历过迷茫,迷茫每一个选 ...
- -bash: _docker_machine_ps1: 未找到命令
场景:在安装完docker-machine,设置docker-machine命令自动补齐的时候,出现以下错误: -bash: __docker_machine_ps1: 未找到命令 解决办法:在~/. ...
- Redis主从数据库同步
Redis主从同步原理-SYNC和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采 ...
- (四)JavaScript 注释
JavaScript 不会执行注释. 我们可以添加注释来对 JavaScript 进行解释,或者提高代码的可读性. 单行注释以 // 开头. 本例用单行注释来解释代码: JavaScript 多行注释 ...
- sqlachemy 获取新创建对象的id,flush与commit
for account_info in valid_account_detail: try: account = account_info.get('account') password = acco ...