Hibernate(4)——三种查询方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_45044097/article/details/102689056

1 Hibernate 的三种查询方式:HQL、Criteria、Sql

1.1 HQL

HQL(hibernate Query Languge,Hibernate 查询语言)查询是一种面向对象的查询语言,其中没有表和字段的概念,只有类、对象和属性的概念,HQL 是应用较为广泛的方式:
语法:[ select/update/delete……] from Entity [where……] [group by……] [ having……] [order by……]

(1). 没使用spring框架的写法:

sessionFactory = new Configuration().configure().buildSessionFactory();
    session = sessionFactory.openSession();
    String hql = “from Street”;
    Query query = session.createQuery(hql);
    List<Street> list = query.list();

(2).使用Spring框架的写法:

String queryString = "select form entity ....";
List list=getHibernateTemplate().find(queryString);

1.2 Criteria

Criteria 查询采用面向对象方式封装查询条件,又称为对象查询;就是对SQL 语句进行封装,采用对象的方式来组合各种查询条件。
由Hibernate 自动产生SQL 查询语句
(1).没使用Spring框架的写法;

SessionFactory sessionFactory = new Configuration().configure()
              .buildSessionFactory();
Session session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(User.class);
List result = criteria.list();
Iterator it = result.iterator();

(2)使用Spring框架的写法:

import org.hibernate.criterion.DetachedCriteria;
DetachedCriteria criteria=DetachedCriteria.forClass(ObjectEntity.class);
criteria.add(Restrictions.eq("propertyName", propertyValue));
List result=getHibernateTemplate().findByCriteria(criteria);

1.3 Sql

Spring框架的写法

List list = getHibernateTemplate().executeFind(new HibernateCallback() {
          public Object doInHibernate(Session session) throws HibernateException, SQLException {
              StringBuffer hqlBuffer = new StringBuffer("");
              hqlBuffer.append("select column_Name  from ...");//里面是SQL语句
              SQLQuery sqlQuery = session.createSQLQuery(hqlBuffer.toString());
              sqlQuery.addScalar("propertyName",Hibernate.STRING);//该propertyName是        ObjectVO实体的一个属性
              sqlQuery.setResultTransformer(Transformers.aliasToBean(ObjectVO.class));    
              List list = sqlQuery.list();
              return list;//此处list集合中存放的是ObjectVO对象
           }
});

返回结果放到list中的:

final String queryString = "";//sql语句
List resultList=getHibernateTemplate().executeFind(new HibernateCallback() {
	public List doInHibernate(Session session) throws HibernateException, SQLException {
		SQLQuery sqlQuery = session.createSQLQuery(queryString);
        List list=sqlQuery.executeUpdate();
        return list;
    }
});

无返回结果:

final String queryString = "";//SQL语句
getHibernateTemplate().executeFind(new HibernateCallback() {
      public Object doInHibernate(Session session) throws HibernateException, SQLException {
      	SQLQuery sqlQuery = session.createSQLQuery(queryString);
        sqlQuery.executeUpdate();
        return null;
     }
});

参考文章 原文链接:https://blog.csdn.net/kingmax54212008/article/details/61196046
https://blog.csdn.net/u012222212/article/details/85010145

2 Hibernate悲观锁和乐观锁

悲观锁( Pessimistic Locking ),对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,大部分时候都是依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

标准的数据库悲观锁调用:
select * from user where name=”think” for update
上面的sql中,通过for update锁定了user表中所有符合检索条件(name=”think”)的记录。本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。Hibernate 的悲观锁,也是基于数据库的锁机制实现。

Hibernate中的悲观锁的实现:

String hql ="from User as user where user.name='think'";
Query query = session.createQuery(hql);
query.setLockMode("user",LockMode.UPGRADE); // 悲观锁
List userList = query.list();// 执行查询,获取数据

query.setLockMode对查询语句中,特定别名所对应的记录进行加锁(我们为User 类指定了一个别名“user”),这里也就是对返回的所有 user 记录进行加锁。

乐观锁( Optimistic Locking )采取了更加宽松的加锁机制。乐观锁,大多是基于数据版本( Version )记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个“version”字段来实现。
乐观锁的原理是:读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则允许更新,否则认为是过期数据(乐观锁的这种机制是可以被伪造的)。
在现实场景中,银行系统对应的存取款,可以使用乐观锁实现。
在entity中,增加一个version属性,并且设置对应的set和get方法,然后在get方法上添加@Version

需要注意的是:此种方式,hibernate会在数据库中对应添加version字段,当每一次操作此表数据时,version字段会更新。

UserEntity stu1 = (UserEntity)session.createQuery("from UserEntity s where s.username='haha3'").uniqueResult();
System.out.println("version="+stu1.getVersion());
stu1.setUsername("enen3");
session.beginTransaction().commit();
System.out.println("version="+stu1.getVersion());

3 Hibernate 批处理–吞吐量

hibernate默认批量添加数据为15条,官方认为这样处理是最高效的,在实际大型服务器上测试结果,应该在50~100之间是峰值。所以每个相对倍数时,应该及时提交数据。
clear():清空缓存中所有持久化对象,
flush():使缓存与数据库同步。

UserEntityuserEntity = null;
for (inti = 0; i<10000; i++) {
	userEntity = new UserEntity();
	userEntity.setUsername("user" + i);
	session.save(userEntity);
	if ((i + 1) % 15 == 0) {
		session.flush();
		session.clear();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_45044097/article/details/102689056