Hibernate数据查询-->简介
2013-12-08 21:31
253 查看
Hibernate数据查询 Hibernate Query Language(HQL) Criteria Query Native SQL 下面对其分别进行解释 Hibernate Query Language: HQL提供了是十分强大的功能,它是针对持久化对象,用取得对象,而不进行update,delete和insert等操作。而且HQL是面向对象的,具备继承,多态和关联等特性。 from子句: from子句是最简单的HQL,例如from Student,也可以写成 select s from Student s。它简单的返回Student类的所有实例。 值得注意的是除了JAVA类和属性的名称外,HQL语句对大小写不敏感。 select子句: 有时并不需要取得对象的所有属性,这时可以使用select子句进行属性查询,如select s.name from Student s。 例: public void HQLselectDEMO() { TRegister user = new TRegister(); Session session = HibernateUtil.currentSession(); Query query = session.createQuery("select u.userName from TRegister u"); List list = query.list(); for(int i = 0 ; i < list.size(); i++) { String name = (String)list.get(i); System.out.println(name); } }如果要查询两个以上的属性桧以数组的方式返回,如下: public void HQLselectDEMO() { TRegister user = new TRegister(); Session session = HibernateUtil.currentSession(); Query query = session.createQuery("select u.userName ,u.sex from TRegister u"); List list = query.list(); for(int i = 0 ; i < list.size(); i++) { Object obj[] = (Object[])list.get(i); System.out.println(obj[0]+" 的性别是:"+obj[1]); } } 在使用属性查询时,由于使用对象数组,操作和理解不太方便,如果将 一个object[]中所有成员封装成一个对象就方便多了。下面的程序做了示例: public void HQLselectDEMO() { Session session = HibernateUtil.currentSession(); Query query = session.createQuery("select new TRegister(u.userName,u.sex) from TRegister u"); List list = query.list(); for(int i = 0 ; i < list.size(); i++) { //Object obj[] = (Object[])list.get(i); TRegister user = (TRegister)list.get(i); System.out.println(user.getUserName()+" 的性别是:"+user.getSex()); } /** *//**要正确运行以上程序,需要在TRegister类中加入一个相应的构造函数 public TRegister(String userName,String sex) { this.userName = userName; this.sex = sex; } */ } 统计函数查询 可以在HQL中使用函数,经常使用的函数如下: count():统计记录条数。 min():求最小值。 max():求最大值。 sum():求和。 avg():求平均值。 例如,要取得Student实例的数量,可以编写如下HQL语句: select count(*) from Student 取得Student平均年龄的HQL语句: select avg(s.age) from Student as s 可以使用distinct去除重复的数据: select distinct s.age from Student as s where子句: HQL也支持子查询,它通过where子句实现这一机制。where子句可以让用户缩小要返回的实例的列表范围。例如下面语句会返回所有名字为"Bill"的Student实例: Query query = session.createQuery("from Student as s where s.name='Bill'"); where子句允许出现的表达式包括了SQL中可以使用的大多数情况。 数学操作:+,-,*,/ 真假比较操作:=, >=, <=, <>, !=, like 逻辑操作:and ,or, not 字符串连接:|| SQL标题函数 :如upper()和lower() 如果查询返回多条记录,可以用以下关键字来量化 all:表示所有的记录。 any:表示所有记录中的任意一条。 some:与any相同。 in:与any等价。 exists:表示子查询至少要返回一条记录。 例如,下面语句返回所有学生年龄都大于18的班级对象 from Group g where 18<all (select s.age from g.students s) 下列语句返回在所有学生中有一个学生的年龄等于22的班级: from Group g where 22 = any (select s.age from g.students s) 或者 from Group g where 22= some(select s.age from g.students s) 或者 from Group g where 22 in (select s.age from g.students s) order by子句 查询返回列表可以按照任何返回的类或者组件的属性排序 from Student s order by s.name asc 连接查询 与SQL一样,HQL也支持连接查询,如内连接,外连接和交叉连接: inner join:内连接 left outer join:左外连接 rigth outer join:右外连接 full join:全连接,但不常用 下面我重点介绍下内连接查询,左外连接和或外连接和内连接大同小异,而全连接几乎没有使用得到的地方。 inner join可以简写为join,例如在查询得到的Group对象时,内连接取得对应的Student对象,实现的程序代码如下: Student stu = null; Group group = null; Query query = session.createQuery("from Group g join g.students"); List list = query.list(); Object obj[] = null; for(int i = 0 ; i < list.size(); i++) { obj = (Object[])list.get(i); group = (Group)obj[0];//group是数组是第一个对象 stu = (Student)obj[1];//stu是数组的第二个对象 System.out.println(stu.getName()+"属于"+group.getName()); } Criteria Query方式 当查询数据时,往往需要设置查询条件。在SQL或HQL语句中,查询条件常常放在where子句中。此处Hibernate还支持Criteria查询,这种查询方式把查询条件封装为一个Criteria对象。在实际应用中,可以使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add方法加入到Criteria实例中。这样程序员可以在不使用SQL甚至HQL的情况下进行数据查询。如下: public void criteriaDEMO() { Session session = HibernateUtil.currentSession(); Criteria criteria = session.createCriteria(TRegister.class);//生成一个Criteria实例 criteria.add(Restrictions.eq("userName","fengyan"));//等价于where name = 'fengyan' List list = criteria.list(); TRegister user = (TRegister)list.get(0); System.out.println(user.getUserName()); }常用的查询限制方法 上面代码中 Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制 Restrictions.eq():equal,= Restrictions.allEq(): 参数为Map对象,使用key/value进行多个等于的对比,相当于多个 Restrictions.eq()的效果 Restrictions.gt():greater-than,< Restrictions.lt():less-than,< Restrictions.le:less-equal,<= Restrictions.between():对应SQL的between子句。 Restrictions.like():对应SQL的like子句。 Restrictions.in():对应SQL的in子句。 Restrictions.and():and 关系。 Restrictions.or():or 关系。 Restrictions.isNull():判断属性是否为空,为空返回true,否则返回false。 Restrictions.isNoyNull():与上面的相反。 Order.asc():根据传入的字段进行升序排序。 Order.desc():与上相反 MatchMode.EXACT:字符串中精确匹配,相当于like 'value' MatchMode.ANYWHERE:字符串在中间位置,相当于like'%value%' MatchMode.START:字符串在最前面,相当于like'value%' MatchMode.END:字符串在最后,相当于like'%value' 下面是几个查询限制的例子: 查询学生名字以t开关的所有Student对象 Criteria criertia = session.createCriteria(Student.class); criteria.add(Restrictions.like("name", "t%")); List list = criteria.list(); Student stu = (Student)list.get(0); 或者: Criteria criertia = session.createCriteria(Student.class); criteria.add(Restrictions.like("name", "t",MatchMode.START)); List list = criteria.list(); Student stu = (Student)list.get(0); 查询学生姓名在Bill,Jack和Tom之间所有的Student对象 String[] names = {"Bill","Jack","Tom"}; Criteria criertia = session.createCriteria(Student.class); criteria.add(Restrictions.in("name", names)); List list = criteria.list(); Student stu = (Student)list.get(0); 查询学生年龄(age)等于22或为空(null)的所有学生对象 Criteria criertia = session.createCriteria(Student.class); criteria.add(Restrictions.eq("age", new Integer(22))); criteria.add(Restrictions.isNull("age")); List list = criteria.list(); Student stu = (Student)list.get(0); 查询学生姓名以字母F开头的所有Student对象,并按姓名升序排序 Criteria criertia = session.createCriteria(Student.class); criteria.add(Restrictions.like("name", "F%")); criteria.addOrder(Order.asc("name")); List list = criteria.list(); Student stu = (Student)list.get(0); 注意调用Order.asc的方法应该是Criteria.addOrder()方法。 连接限制 Criteria查询中使用FetchMode来实现连接限制。在HQL语句中,可以通过fetch关键字来表示预先抓取(Eager fetching),如下: from Group g left join fetch g.students s where g.name like '%2005' 可以使用Criteria的API完成同样的功能,如下: Criteria criertia = session.createCriteria(Group.class); criteria.setFetchMode("students", FetchMode.EAGER); criteria.add(Restrictions.like("name", "2005",MatchMode.END)); List list = criteria.list();以上两种方式编写的代码都使用相同的SQL语句来完成它们的功能,如下: select g.*, s.* from Group g left outer join Student s on g.id = s.group_id where g.name like '%2005' Native SQL查询 本地SQL查询指的是直接使用本地数据库的SQL语言进行查询。这样做对于将 原来的SQL/JDBC程序迁移到Hibernate应用很有用 创建一个基于SQL的Query Native SQL查询是通过SQLQuery接口来控制的,它通过调用Session.createSQLQuery()方法来获得。如: String sql = "select {s.*} from t_student s where s.age>22"; //{}用来引用数据表的别名,{s.*}表示使用s来做为t_student表的别名 SQLQuery sqlQuery = session.createSQLQuery(sql); sqlQuery.addEntity("s",Student.class); List list = sqlQuery.list(); for(int i = 0 ; i < list.size(); i++) { Student stu = (Student)list.get(i); } //createSQLQuery(String sql)利用传入的sql参数构造一个SQLQuery实例。使用该方法时,还需要传入查询的实体类,因此在配合使用SQLQuery的addEntity()方法一起使用。 命名SQL查询 与HQL的命名查询相似,也可以将 本地的SQK查询语句定义在映射文件中,然后像调用一个命名HQL查询一样专题报道调用命名SQL查询。 如: </class> <sql-query name="QueryStudents"> <![CDATA[ select {s.*} from t_student s where s.age > 22 ]]> <return alias="s" class="Student" /> </sql-query> </hibernate-mapping>配合以上配置我们可以如下编写代码来查询 Query query = session.getNamedQuery("QueryStudents"); List list = query.list(); for(int i = 0 ; i < list.size();i++) { Student stu = (Student)list.get(i); }也可以在命名查询是设定参数,如下: <sql-query name="QueryStudents"> <![CDATA[ select {s.*} from t_student s where s.age > :age ]]> <return alias="s" class="Student" /> </sql-query> </hibernate-mapping>程序代码: Query query = session.getNamedQuery("QueryStudents"); query.setInteger("age",22); List list = query.list(); for(int i = 0 ; i < list.size();i++) { Student stu = (Student)list.get(i); }自定义insert , update和delete语句: Hibernate 3.x的映射文件中新添加<sql_insert>,<sql_update>,<sql-delete>3个标记。可以使用这3个标记自定义自己的insert ,update,delete语句,如: </class> <sql-insert> insert into t_student(name,age,id) values(?,?,?) </sql-insert> <sql-update> update t_student set name=?,age=? where id=? </sql-update> <sql-delete> delete from t_student where id = ? </sql-delete> </hibernate-mapping>对于以上自定义的SQL语句,要注意以下几点 1:insert 和update语句中定义的字段必须和映射文件声明的属性相应,一个都不能少。 2:在insert 和update语句中,属性出现的顺序必须和映射文件中的顺序一样。 3:在insert语句中,主键id总是放在最后。 在程序中实现以上自定义的insert语句如下: Student stu = new Student(); stu.setName("Bill"); stu.setAge(22); session.save(stu);如果不想在insert或update语句中包括所有属性,则可以在属性定义时 加上insert ="false"或update="false"如下: <property name = "name" type="string" insert = "false" update="false"/> <sql-insert> insert into t_student(age,id) values(?,?) </sql-inert>
相关文章推荐
- JavaEE--------> Hibernate入门 -->使用Hibernate实现数据的删改
- mysql like 查询 有单引号的处理办法。org.hibernate.QueryException: expecting ''', found '<EOF>' [SELECT DISTINCT
- rownum 的使用,不能对rownum用">",删除查询特定条数据
- SQL简介&数据表分析&数据查询
- Extjs和Asp.NET后台的数据交互(一) => Newtonsoft.Json 使用简介
- JSP EL表达式<c:forEach> 页面获取hibernate联级对象数据
- Android实战简易教程<二十五>(基于Baas的数据表查询下拉刷新和上拉加载实现!)
- java查询mysql的char字段List<Object[]>数据被截断
- mybatis查询如何返回List<Map>类型数据
- hibernate关联映射关系带来的弊病---> 无意义的查询
- hibernate_查询简介: 分页, 数据总数, 结果集的包装, 位置参数的设置
- Hibernate查询任意字段,通过LinkedList<Object[]>取值
- Android sqlite 数据库查询,插入,删除,更新demo<第3章>---测试验证插入数据
- vc传输字符===>java servlet====>hibernate====>mysql乱码问题
- <c:forEach varStatus="status">中 varStatus的属性简介
- List<T> 直接绑定到datagridview上不显示数据.
- Android 读取<meta-data>元素的数据
- 数据挖掘学习指引<一>
- Hibernate 查询Criterion数据