Hibernate的查询与更新技术

1.Criteria

我的理解:Criteria就是Hibernate生成的一个由根据一定约束条件查询session或数据库而得到的结果的List和一些添加约束条件的方法所组成的对象。

(1).创建criteria:Criteria crit = session.createCriteria(MyMessage.class)àList<MyMessage>对象

(2).设置结果集最大个数:crit.setMaxResults(2)

(3).查询、得到结果集:List<MyMessage> messages = crit.list(),list函数执行带有条件的对Criteria对象集合的查询。

注意:如果不使用crit.uniqueResult(),Criteria.list()返回的就是一个List<Object[]>

(4).添加约束:

Criteria.add(Criterion的实现类);

原理:org.hibernate.criterion.Restrictions利用其静态方法创建单个或多个(or、and)约束条件的组合形成SimpleExpression对象,再有Criteria的add方法添加到Criteria对象,最后有list方法执行条件查询返回查询结果。

org.hibernate.criterion.Restrictions静态方法如下:

1) 单个约束:

SimpleExpression extends Criterion;

public static SimpleExpression ne(String propertyName,Object value); //!=

public static SimpleExpression lt(String propertyName,Object value); //<

public static SimpleExpression gt(String propertyName,Object value); //>

public static SimpleExpression le(String propertyName,Object value); //<=

public static SimpleExpression ge(String propertyName,Object value); //>=

public static SimpleExpression like(String propertyName,Object value); //like

//说明:此处的value有4种情况:“%subString”、“subString%”、“%subString%”、“subString”

public static SimpleExpression like(String propertyName,Object subString, MatchMode); //like

//说明:subString表示匹配字符串,MatchMode也有4个常量值:

MatchMode.ANYWHERE //相当于“%subString%”

MatchMode.END; //相当于“subString%”

MatchMode.EXACT; //相当于“subString”

MatchMode.START; //相当于“%subString”

2) 多个约束:

LogicalExpression extends Criterion;

Conjunction extends Criterion;

Disjunction extends Criterion;

Criteria的add方法可以添加多个约束,默认情况下他们之间的关系是and,下面介绍多个约束之间关系不唯一的添加方法:

public static LogicalExpression and(Criterion s1, Criterion s2); //or

public static LogicalExpression or(Criterion s1, Criterion s2); //and

//说明:建立两个单个约束SimpleExpression之间的or、and关系,但是该方法不常用

//常用方式如下:

Conjunction conjunction =Restrictions.conjunction();

conjunction.add(SimpleExpression1);

conjunction.add(SimpleExpression2);

Disjunction disjunction=Restrictions.disjunction();

disjunction.add(conjunction);

disjunction.add(SimpleExpression3);

3) 直接使用sql语句

Retrictions.sqlRestriction(“{alias”.name like ‘%d%’”);

Retrictions.sqlRestriction(“{alias”.name like ?”,”%d%”,new.org.hibernate.type.StringType());

//说明:这样的做法不太常用,其中{alias}就代表表明,不用替换,name是表的某个字段名,第二个方法中根据?指定参数和参数类型,多于一个使用数组代替后两个参数。

(5).分页:

crit.setMaxResults(rows);

crit.setFirstResult((currentPage - 1) * rows);

特别说明:

public String execute() throws Exception {

Session session = HibernateSessionFactory.getSession();

Criteria crit = session.createCriteria(entity);

crit.setMaxResults(rows);

crit.setFirstResult((currentPage - 1) * rows);

List list = crit.list();

for (Object obj : list) {

records.add(obj);

}

session.close();

return SUCCESS;

}

上面这个函数可以作为通用的分页函数:

entity:表示实体全名package.Entity

rows:表示页大小

currentPage:表示当前页码(1,2,3...)

records:是查询得到的记录集,它的getter核setter方法类型既可以是List<List<String>也可以是List<Object>,客户端都可以使用row[field]读取。

field:未知表的字段值,可以建立一个fieldList的getter方法,返回String[] field.splid(“,”)。

详见std_example(pagination)

(6).持久化一个对象

crit.setMaxResults(1);

crit.add(Restrictions.eq("id", 1));

MyMessage message = (MyMessage) crit.uniqueResult();

必须保证查询结果集只有1条或者为null,否则将会抛出一个org.hibernate.NonUniqueResultException异常

(7).对查询结构进行排序:

crit.addOrder(org.hibernate.criterion.Order.desc("id"));

//desc表示降序,asc表示升序,都是静态方法

(8).多个Criteria之间的关联

Criteria crit1 = session.createCriteria("entity.Order");

Criteria crit2=crit1.createCriteria("customer");

存在关系的两个实体之间可以建立如上关系,单独操作!

(9).聚合和分组(集合映射操作)

Criteria.setProjection(org.hibernate.criterion.AggregateProjection对象);

org.hibernate.criterion.Projections类的静态方法可以创建AggregateProjection对象

例如:

crit.setProjection(Projections.rowCount());

Integer value=(Integer)crit.uniqueResult();

//统计记录总数

Projections.groupProperty("name")//按照name分组

Projections.max("id")//找最大值

Projections.sum("id")//计算总和 等等还有很多,具体使用时再具体统计

org.hibernate.criterion.ProjectionList//可以建立一个映射集合

ProjectionList projList=Projections.projectionList();

projList.add(Projections.groupProperty("name"));

projList.add(Projections.rowCount());

projList.add(Projections.max("id"));

crit.setProjection(projList);

List results=crit.list();

Object array[]=(Object[])results.get(0);

特别注意

1.如果不适用crit.uniqueResult(),Criteria.list()返回的就是一个List< Object[]>

2.约束条件添加的顺序次数不一样返回的结果也不一样,尤其是对于分组约

(10).QBE (Query By Example)

org.hibernate.criterion.Example implements Criterion;

原理:利用Example的静态方法create来生成一个实现了Criterion的Example对象,供Criteria查询,而前面是通过显式的约束类来生成Criterion对象,这里约束的生成多了一个通过事例提炼约束的过程。

MyMessage message = new MyMessage();

message.setName("gb2312中文");

Example example = Example.create(message);

example.enableLike();//验证没有通过的结论:所用String使用like查询

example.excludeProperty("id");//忽略字段id

example.excludeNone();//忽略默认值为0的字段= example.excludeZeroes();

crit.add(example);

2.Query

我的理解:

a.HQLàSQL

HQL(Hibernate Query Language),HQL就像SQL一样的查询语言,不同的是SQL是针对数据库中的表的而且不区分大小写;而HQL针对的是项目中的实体对象,查询的是实体对象的成员变量,其中变量名应准确描述,关键字和SQL基本一样,也不区分大小写;可以说HQL是面向对象的。

b.QueryàCriterria

Session通过createQuery(hql查询字符串)生成Query对象,Query和Critaria类似,他是Hibernate生成的一个由根据hql语句查询session或者数据库而得到的结果的List所组成的对象。他们的不同之处在于,Query把约束条件变成了HQL语句直接访问session得到查询结果,而Criteria是通过自身提供的方法和接口先构造出约束条件然后再访问session得到查询的结果。

(1).创建query: String hql="from MyMessage";

Query query=session.createQuery(hql); àList<Object> List<Object> results = query.list();

public Query createQuery(String queryString)throws HibernateException;

(2).HQL基本语法:

1)from子句 返回List<Entity>或者List<Entity[]>对象集合

from MyMessage // MyMessage:实体名,经过mapping的实体或其父类

from MyMessage as m //可以简化实体名为m,其中as可以省略,建议不要省略

from entity.MyMessage as m //如果类名有冲突可以使用package.className,当类没有经过mapping映射(如父类)那么必须使用package.calssName

from EntityBean as b1,EntityBean2 as b2 //from后面可以跟多个Bean,用逗号隔开

from java.lang.Object //from后面可以跟Bean的父类,查询结果是所有子类Bean集合

如果想让hibernate生成查询相关实体Bean的SQL语句可以为相关联的实体Bean建立一个父类。

2)select子句 返回List<Object>或者List<Object[]>属性集合

select name ,id from MyMessage

// select后面跟需要返回的实体属性名,多个属性之间用逗号隔开

3)where子句

select name from MyMessage where id>5

select name ,id from MyMessage where id>5 and not(name like '%e%')

//类似于sql的where子句,其中多个条件之间有or和and关系

4)使用命名参数(相当于sql语句中带有的?,sql也支持)

Address address = new Address();

address.setId(2);

sql = "from Employee as e where e.address=:address";

query = session.createQuery(sql);

query.setEntity("address", address);

如上所示,可以为加“:”参数设置指定类型的值,甚至可以使实体类型(此时使用的是实体的主键进行的查询)。

5) order by子句和group by子句(排序和分组)

例句:from MyMessage order by id desc,name asc

select count(*) ,name from MyMessage group by name order by id desc

6) 关联查询

HQL支持如下四种关联:

inner join //内关联

left outer join/left join //左外关联

right outer join/right join //右外关联

注意:当使用select语句时返回List<Object[]>(记录.字段数组),如果存在1:2会生成两条记录;

当仅使用from时返回对象集合List<entity[])(记录=对象),如果存在1:2会出现两条一样的记录;

例如:

7) 聚合函数

avg(...) //求属性平均值

sum(...) //求属性的总和

min(...) //求属性的最小值

max(...) //求属性的最大值

count(...或*或distict...) //求持久化对象数

8) Update,delete和insert语句

例句:update Customer set name='sun' where name='bea'

delete from Customer where name='sun'

insert into MyMessage(id,name) select 50 ,name from MyMessage where id=2

操作流程:

Transaction tx=session.beginTransaction();

String hql="update Customer set name='sun' where name='bea'" ;

Query query=session.createQuery(hql);

int count =query.executeUpdate();

tx.commit();

注意:1.对数据库的更删改操作需要开启一个事物

2.insert语句不支持values操作,因此必须制定插入的位置为select

(3).命名查询(避免hql或者sql语句硬编码到类中,利用配置文件)

这样做的好处

1).可以共享查询语句

2).避免修改类

3).容易整理和测试查询语句

例如:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<query name="myhql">

<![CDATA[select name from MyMessage where id=:id]]>

</query>

<sql-query name="mysql">

<![CDATA[select name from t_message where id=:id]]>

</sql-query>

</hibernate-mapping> //配置文件

Query query =session.getNamedQuery("myhql");

query.setInteger("id", 50);

Session成员:public Query getNamedQuery(String queryName) throws HibernateException;

也支持SQL的原理:当session.getNamedQuery(“mysql”)时根据标签<query> 返回Query对象,<sql-query>返回SQLQuery对象,然而SQLQuery是Query的子类,因此相当于执行了session.createSQLQuery("select name from t_message where id=:id")函数。

(4).使用SQL

原理

Session成员:public SQLQuery createSQLQuery(String queryString) throws HibernateException;该成员生成SQLQuery对象,之后操作与Query基本一样,不同在于query.list()默认返回当前记录的字段值(List<Object[])而不是对象,如果想让其返回对象,需要为sql语句查询的表alias对应实体Entity,工作成员如下:

Public SQLQuery addEntity(Class entityClass);

Public SQLQuery addEntity(String slias, Calss entityCalss);

另外如果使用聚合函数返回数值结果,需要使用以下成员:

Public void addScalar(String filedName,Object Hibernate.TYPE);

事例:

String sql="select * from t_message m";

SQLQuery query=session.createSQLQuery(sql);

query.addEntity("m",MyMessage.class); ...

sql="select count(*) as c from t_message";

query=session.createSQLQuery(sql);

query.addScalar("c",Hibernate.LONG);

Long count=(Long)query.uniqueResult(); ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值