hibernate几种查询方式

Hibernate提供的查询方式有以下几种:

1.OID查询方式
    通过get()和load()方法加载指定OID的对象;   

    例如:

session.get(User.class,1);

后面的数字为数据库中对应的ID

    get和load的区别是,load支持类级别的懒加载,而get不支持,同时load支持缓存还有一点,load返回的是一个代理对象,当查询为空的时候,get返回的是null,而load则会报异常HubernateException

2.HQL查询方式
   HQL操作的是持久化的对象,而不是数据库
    --通过Query接口使用HQL语言进行查询

查询整个类即所有字段的属性,叫做实体查询,仅查询某几个字段的值,持久化的仅仅是查询到的字段,叫做属性查询,同时查询超过两个属性的时候,结果集的泛型是Object[]数组,按照查询的顺序,数组的每一个元素就是一个字段的值,当实体查询联合查询两个以上的实体类,即多表查询的时候,结果集的泛型也是数组,每个数组的元素就是一个实体类;

    例如:

 Query query = session.createQuery(" from User where id=:id");
 Query query = session.createQuery(" select u.id,u.name from User u");
 query.setInteger("id",1);
 query.setFirstResult((pageNo-1)*pageSize);
 query.setMaxResults(pageSize);

  别名User u / User as u,as可有可无

注意,hql语句中,要用对应的实体类和类属性名代替表明和字段名,因为hibernate是实现ORM(对象关系映射)的框架,它操作的是持久化的对象,而不是数据库,

设置参数,如果hql语句中为"where id = ?"的话,用query.setInteger(0,1);,第一个问号下标为0,当然,设置参数也可以用字符拼接的方式,但是安全性低,性能低,而且容易拼接错误,如果要分页的话,hibernate提供有分页的支持,只需要设置页码和每页最大显示条数即可
        
      
 List<User> list = query.list();
 Iterator iter = query.iterator();
 User user = query.uniqueResult()
  list和iterator效果相同,都是取得结果集,区别是,iterator先查询出来所有符合的id,等调用数据的时候,调用一条数据,就去缓存中寻找该条数据,如果存在,则直接将缓存中的数据读出来,如果不存在,就执行一条sql语句,查询出对应的值; 一般情况都使用list,如果对象包含大量数据,或者要加载的大部分数据都在缓存中已经存在的时候,就使用iterator
   如果确定结果是单一的对象,就用uniquerResult()方法

--实体的更新和删除:   

     此处的hql语句和sql语句一样,只是表名和字段名都要相应的替换为实体类,

 Query query = session.createQuery(hql);
 query.executeUpdate();
 String hql =" delete from User where id = 1";
 String hql =" update User set name='张三' where id = 1";

--分组查询,一般使用的聚合函数(统计函数),avg()、sum()、min()、max()、count()等等        

  String hql = " select count(*) from User";

 需要注意的是,hibernate中的统计函数,avg的返回值是Double型的,min和max返回的是Integer型的,而count和sum返回的都是Long型的,Long型无法强转成Integer型,如果确实想要用Integer型返回值,可以将查询结果强转为Number型,
--子查询    在hibernate中,子查询语句只能放在where之后,不能像sql中那样,可以放在任何地方

--连接查询(outer可以省略)    
   
inner join    
 String hql =" from Street s inner join s.district";//sql1999
 String hql = " from Street s,District d where s.district=d";sql1992
left outer join 
 String hql = " from Street s left join s.district";//左边对象所有数据都会读出来,不管右边对象有没有与之对应的值
 String hql = " from Street s,District d where s.district=d(+)";//同上,可以理解为右边对象值少,需要+null来与之对应

3.QBC查询方式(Query By Criteria)

    --使用Criteria等的接口和类进行查询,criteria查询又叫做对象查询,criteria本身只是查询容器

    例如: 

  

 Criteria criteria = session.createCriteria(User.class);
  Criteria crieteia = session.createCriteria("com.entity.User");
   //criteria也可以分页,也有.list()和.uniqueResult()方法,用法和query一样,但是criteria设置参数的方法和query不一样,
  criteria.add(Restrictions.sqlRestriction(" name like '%a%' and age=23"));
  criteria.add(Example.create(user));//user为一个实例化的对象,它的被赋值的属性将作为参数加入查询
  criteria.add(Restrictions.eq("isAdmin", 2));//等价于
  criteria.add(Restrictions.ge("age", 23));//大于
  criteria.add(Restrictions.le("id", 6));//小于
  criteria.add(Restrictions.or(Restrictions.eq("isAdmin", 1), Restrictions.between("age", 24, 33)));
  criteria.addOrder(Order.desc("age"));//排序
  criteria.setProjection(Projections.avg("age"));//分组查询,聚合函数
  criteria.setProjection(Projections.projectionList().add(Projections.count("id")).add(Projections.sum("age")).add(Projections.max("age")));//多个聚合函数

4.本地SQL查询方式


    --使用原生sql语言进行查询

    例如:   

 Query query = session.createSQLQuery(" select u.* from HOUSE_USERS u").addEntity("u",User.class);
 Query query = session.createSQLQuery(" select {d.*},{s.*} from HOUSE_District d,HOUSE_Street s where d.id=s.DISTRICT_ID").addEntity("d",District.class).addEntity("s",Street.class);
 List<Object[]> list = query.list();
 Object[] obj = list.get(0);
 District district = obj[0];
 Street street = obj[1];
 需要注意的是,对多个表进行综合查询的时候,如果两个表有某些字段的名字一样,则查询的结果会将该字段第二次出现的字段名称自动重命名,查询后封装数据的时候,会将第一个字段名字的值封装到两个对象之中,解决这种办法,就是在sql语句中对这两个对象查询的字段分别用花括号括住,如上这是hibernate提供的方法,数据库中并不支持这种查询

5.对象导航查询方式

    --通过已经加载的对象,导航到其关联对象

6.命名查询(类似mybatis)
    写在配置文件<class/>的标记下面
        Query query = session.getNamedQuery("login");  
<query name="login">
    <![CDATA[from User where name=:name and password=:password]]>
 </query>
<sql-query name="findUser">
    <![CDATA[select u.* from HOUSE_USERS u]]>
    <return alias="u" class="com.entity.User"></return>
</sql-query>
  使用原生sql查询,必须把表所有的列写全才可以,否则会出现‘列名无效'的错误 ,除非你使用return-scalar来设置字段类型
  或者写在<class/>上面,格式同方法一,但是java代码调用时需要指定(包+类+配置名)  
        Query query = session.getNamedQuery("com.entity.User.login");   

 7.定制sql    可以自己定制sql语句实现create、delete、update
    写在配置文件的<class/>的标记上,标签为<sql-insert></sql-insert>、<sql-update></sql-update>、<sql-delete></sql-delete>
   
<sql-insert>
    insert into HOUSE_USERS (name,password,username,isAdmin,age,id) values(?,?,?,?,?,?)
</sql-insert>
如果某一个字段不想参与对应操作,可以在该字段对应的配置属性<property insert="false"></property>中设置insert="false"就可以不用加该属性;
 同理,可以设置update="false",在调用session.save();session.delete();session.upload()方法的时候,会执行定制的sql语句,而不是hibernate封装的语句




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值