简单使用hibernate处理增删改查

Hibernate在没有被Spring管理的时候,可以单独使用。
Hibernate中的增删改查操作都是通过session里的方法来进行的。
一 查询
session中用于查询的有两种方法:get和load。
这两种方法都是返回实体对象,不同的是,如果未能发现符合条件的记录,get方法返回null,而load 方法会抛出一个ObjectNotFoundException。
load()方法可返回实体的代理类实例,而get方法永远直接返回实体类。
load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。

二 保存
session中的save方法可以保存,如果你查出一个对象,修改它,再用save保存,那这就是修改,所以save具有保存、修改的作用。
Hibernate中还有update()和saveOrUpdate(),他们的作用又是什么。
先说一说VO和PO的概念,在Hibernate中,VO是指普通的数据Bean,一个和Hibernate没有关系的数据Bean,PO也是一个数据Bean,PO是被持久化的数据Bean,并且在Session生命周期内。其实VO也是PO的一种,在Hibernate中PO总共有三种状态,
1.未被持久化的VO。
2.已被持久化的PO,并且在Session生命周期内。
3.被持久化过,但现在不在Session的生命周期内,以VO的身份在运行。
update()和saveOrUpdate()是用来对跨Session的PO进行状态管理的。假设你的PO不需要跨Session的话,那么就不需要用到,例如你打开一个Session,对PO进行操作,然后关闭,之后这个PO你也不会再用到了,那么就不需要用update()。
看看下面的代码:
Foo foo=sess.load(Foo.class,id);
foo.setXXX(xxx);
sess.commit();
PO对象foo的操作都在一个Session生命周期内完成,因此不需要显式的进行sess.update(foo)这样的操作。 Hibernate会自动监测到foo对象已经被修改过,因此就向数据库发送一个update的sql。当然如果你非要加上sess.update (foo)也不会错,只不过这样做没有任何必要。

而跨Session的意思就是说这个PO对象在Session关闭之后,你还把它当做一个VO来用,后来你在Session外面又修改了它的属性,然后你又想打开一个Session,把VO的属性修改保存到数据库里面,那么你就需要用update了。
Cat cat = (Cat) firstSession.load(Cat.class, catId);
firstSession.save(cat);

// in a higher tier of the application
cat.setMate("Mate");

// later, in a new session
secondSession.update(cat); // update cat
cat对象是在第一个session中取得的,在第一个session关闭之后,它就成了PO的第三种状态,和Session已经分离的PO,此时他们的状态信息仍然被保留下来了。当他们进入第二个session之后,立刻就可以进行状态的更新。但是由于对cat的修改操作:cat.setMate(“Mate”); 是在Session外面进行的,Hibernate不可能知道cat对象已经被改过了,第二个Session并不知道这种修改,因此一定要显式的调用 secondSession.update(cat); 通知Hibernate,cat对象已经修改了,你必须发送update的sql了。
所以update的作用就在于此,它只会被用于当一个PO对象跨Session进行状态同步的时候才需要写。而一个PO对象当它不需要跨Session进行状态管理的时候,是不需要写update的。
再谈谈saveOrUpdate的用场:
当一个数据Bean,你不知道它是VO还是被持久化的VO,那么就不知道到底是该调用save还是该调用update,这时,调用saveOrUpdate会帮你解决这个问题,如果这个数据Bean是一个新对象,那么Hibernate会保存这个对象,如果是被持久化过的对象,Hibernate会在数据库中修改这个对象。

三 删除
单个删除直接用session.delete(object),如果是批量删除,使用session.createQuery(hql).executeUpdate()。
如:String hql = "delete User where name = 'wangning'";
Query query = session.createQuery(hql);
int count = query.executeUpdate();
也可使用session.createSQLQuery(sql).executeUpdate()。

看看Hibernate的其他操作。
下面说一说另一种操作Hibernate的方式Query.
String hql="from User";
Query query=session.createQuery(hql);
List list = query.list();
这是典型的Hibernate面向对象查询。
如果HQL写成select name from User where id=23,会出错。
如果HQL写成select user.name from User as user where id=23,也会出错。
因为得出的 Quey 结果并不是User对象,而只能是逐个取值的数组。
只有HQL写成from User as user where id=23.
这时的 Query q.list().get(0) 才是一个User类型的 PO 对象。
当遇到复杂查询的时候,比如从两张表里查询数据,比如:
String hql="from User u,User2 u2 where u.id=u2.id";
Query query=session.createQuery(hql);
这时怎么得到查询出的数据?
因为这时是两张表,涉及到两个对象,所以要按第一种方式显然行不通。
这样:
List list = query.list();
User u = (User)((Object[])list.get(0))[0];
User2 u2 = (User2)((Object[])list.get(0))[1];
从这里可以看出,查询结果被默认按照查询对象存放一个数组里面。
还有一种类似的方法createSQLQuery(),它执行的是sql语句。
String sql="from User u,User2 u2 where u.id=u2.id";
Query query = sess1.createSQLQuery(sql).addEntity(User.class).addEntity(User2.class);
List list = query.list();
User u = (User)((Object[])list.get(0))[0];
User2 u2 = (User2)((Object[])list.get(0))[1];
上面两种方法效果一样,只是一个使用HQL,一个使用SQL。
如果碰到复杂查询应该怎么解决呢,比如我们需要获得一个部门及其下面的所有员工,我们只需在设计部门对象的时候为其增加一个一对多关联,然后通过单表查询部门表,在每个部门值对象的员工属性中就有其所有的员工了。当然,在你不需要查询员工信息,而只需要部门信息的时候,你不去取员工的值,那么Hibernate就不会去数据库查询员工的信息(即延迟查询)。
在比如,我们需要在查询员工的时候显示各个员工所在部门的部门名称,只需要在员工值对象中建立员工到部门的多对一关系,在单表查询员工的时候,每个员工值对象中都有部门属性,对应的是部门值对象,包含了其所在部门的全部信息。
再比如员工与部门形成多对一、与项目形成多对多、与住址形成一对一,同时员工与工作计划、工作计划与绩效考核、绩效考核与考核工资等多表形成链状关联,都可以通过员工进行单表查询。
就是说我们可以用单表查询以及值对象关系来处理一些多表查询(使用hibernate提供的一对一、多对多、3种继承关系)。
如果碰到报表这种复杂的查询的时候,那就建议使用JDBC了。
下面说说JDBC查询的一个例子。
Session session = this.getSession();
String sql = "select * from user";
Connection con = session.connection();
Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery(sql);
现在来说说Hibernate中的Criteria。
Criteria crit=session.createCriteria(Event.class);
crit.add(Restrictions.like("title","e",MatchMode.ANYWHERE));
Event ee = (Event)crit.list().get(0);
上面是一个模糊查询,它相当于SQL语句:
select * from event where title like %e%;
like是模糊查询,MatchMode.ANYWHERE是任意的意思,相当于%e%,MatchMode.END相当于e%,
MatchMode.START相当于%e。
现在说说Restrictions中的方法,Restrictions.eq对应field=value的意思;
Restrictions.allEq对应多个field=value,它的参数是一个Map;
Restrictions.gt对应field>value;
Restrictions.ge对应field>=value;
Restrictions.lt对应field<value;
Restrictions.le对应field<=value;
Restrictions.between对应value1<field<value2;
比如Restrictions.between("id",new Integer(1),new Integer(10));
Restrictions.in对应field in (value1,value2,value3,....);
Restrictions.and对应于SQL语法中的and;
Restrictions.or对应于SQL语法中的or;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值