hibernate 数据库查询

hibernate提供了多种方式进行数据库数据的查询

HQL查询

代码如下

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3         Session session = HibernateFactory.currentSession();
 4         Transaction tx = session.beginTransaction();
 5
 6         Query query = session.createQuery("from Student student where student.name like :name order by student.id asc");
 7         query.setParameter("name", "student%");
 8         //实现分页
 9         query.setFirstResult(0);
10         query.setMaxResults(2);
11         List<Student> students = query.list();
12         for(Student student : students) {
13             System.out.println(student.getName());
14         }
15
16         tx.commit();
17         HibernateFactory.closeSession();
18     }
19 }

如果结果是单一的对象而不是集合,可以使用query. uniqueResult()

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3         Session session = HibernateFactory.currentSession();
 4         Transaction tx = session.beginTransaction();
 5
 6         Query query = session.createQuery("select count(*) from Student");
 7         Long count = (Long)query.uniqueResult();
 8
 9         tx.commit();
10         HibernateFactory.closeSession();
11     }
12 }

也可以直接访问对象中的对象属性(String hql = "from Student where grade.name= ‘grade1‘";) 这样相当于两张表的联合查询

如果一次查询多个对象,可以使用以下方式

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3
 4         Session session = HibernateFactory.currentSession();
 5         Transaction tx = session.beginTransaction();
 6
 7         Query query = session.createQuery("from Student s,Grade g where s.id=g.id and s.name like :name");
 8         query.setParameter("name", "student%");
 9         List list = query.list();
10         for(int i = 0;i < list.size();i++) {
11             Object[] obj = (Object[]) list.get(i);
12             Student student = (Student) obj[0];
13             Grade grade = (Grade)obj[1];
14             System.out.println(student.getName() + "|" + grade.getName());
15         }
16
17         tx.commit();
18         HibernateFactory.closeSession();
19     }
20 }

Criteria方式查询

代码如下

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3         Session session = HibernateFactory.currentSession();
 4         Transaction tx = session.beginTransaction();
 5
 6         Criteria criteria = session.createCriteria(Student.class);
 7         criteria.add(Restrictions.like("name", "student%"));
 8
 9         criteria.setFirstResult(0);
10         criteria.setMaxResults(2);
11         criteria.addOrder(Order.desc("name"));
12
13         List<Student> students = criteria.list();
14         for(Student student : students) {
15             System.out.println(student.getName());
16         }
17
18         tx.commit();
19         HibernateFactory.closeSession();
20     }
21 }

使用criteria方式查询有以下三个步骤

1.使用Session实例 的createCriteria()方法创建Criteria对象

2.使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组

3.使用Criteria对象的list()方法进行查询并返回结果

例子查询

例子查询将一个对象的非空属性作为查询条件进行查询,代码如下

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3                 //建立一个例子对象,它的非空属性作为删选条件
 4         Student studentExample = new Student();
 5         studentExample.setName("student1");
 6
 7         Session session = HibernateFactory.currentSession();
 8         Transaction tx = session.beginTransaction();
 9
10         Criteria criteria = session.createCriteria(Student.class);
11         criteria.add(Example.create(studentExample));
12
13         List<Student> students = criteria.list();
14         for(Student student : students) {
15             System.out.println(student.getName());
16         }
17
18         tx.commit();
19         HibernateFactory.closeSession();
20     }
21 }

离线查询

离线查询建立一个DetachedCriteria对象,将查询的条件等指定好,然后在session.beginTransaction()后将这个对象传入,代码如下

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3         DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
 4         dc.add(Restrictions.like("name", "student%"));
 5
 6         Session session = HibernateFactory.currentSession();
 7         Transaction tx = session.beginTransaction();
 8
 9         Criteria criteria = dc.getExecutableCriteria(session);
10         List<Student> students = criteria.list();
11         for(Student student : students) {
12             System.out.println(student.getName());
13         }
14
15         tx.commit();
16         HibernateFactory.closeSession();
17     }
18 }

load/get方式

Student student = (Student) session.get(Student.class, 1);

Student student = (Student) session.load(Student.class, 1);

两者区别

1.get()采用立即加载方式,而load()采用延迟加载;get()方法执行的时候,会立即向数据库发出查询语句, 而load()方法返回的是一个代理(此代理中只有一个id属性),只有等真正使用该对象属性的时候,才会发出sql语句

2.如果数据库中没有对应的记录,get()方法返回的是null.而load()方法出现异常ObjectNotFoundException

命名查询

1.配置hbm文件,将sql或者hql语句写入hbm,并给与一个唯一标示这个查询语句的name

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping >
 6     <class>...</class>
 7
 8     <query name="hqlquery">
 9         <![CDATA[
10             from Student where name like :name
11         ]]>
12     </query>
13
14     <query name="sqlquery">
15         <![CDATA[
16             select s from Student s where name like ?
17         ]]>
18     </query>
19 </hibernate-mapping>

2.通过name在代码中调用事先写好的查询语句

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3
 4         Session session = HibernateFactory.currentSession();
 5         Transaction tx = session.beginTransaction();
 6
 7         Query query = session.getNamedQuery("hqlquery");
 8         query.setParameter("name", "student%");
 9         List<Student> students = query.list();
10         for(Student student : students) {
11             System.out.println(student.getName());
12         }
13
14         Query sqlquery = session.getNamedQuery("sqlquery");
15         sqlquery.setParameter(0, "student%");
16         List<Student> students2 = query.list();
17         for(Student student : students2) {
18             System.out.println(student.getName());
19         }
20
21
22         tx.commit();
23         HibernateFactory.closeSession();
24     }
25 }

SQL查询

hibernate支持原生的sql查询语句,具体的代码如下

返回单表的查询

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3         Session session = HibernateFactory.currentSession();
 4         Transaction tx = session.beginTransaction();
 5
 6         List<Student> students = session.createSQLQuery("select * from student").addEntity(Student.class).list();
 7         //或者采用以下语句
 8         // List<Student> students = session.createSQLQuery("select s.* from student as s").addEntity("s",Student.class).list();
 9
10         for(Student student : students) {
11             System.out.println(student.getName());
12         }
13
14         tx.commit();
15         HibernateFactory.closeSession();
16     }
17 }

返回多个表的查询

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3         Session session = HibernateFactory.currentSession();
 4         Transaction tx = session.beginTransaction();
 5
 6         SQLQuery query = session.createSQLQuery("select s.*,g.* from student as s,grade as g where s.gradeid=g.id");
 7         query.addEntity("s",Student.class).addEntity("g",Grade.class);
 8
 9         List list = query.list();
10         //list的每一条数据都由Object数组组成,数组的每个约束对应一个对象
11         for (int i = 0; i < list.size(); i++) {
12             Object[] obj = (Object[]) list.get(i);
13             Student student = (Student) obj[0];
14             Grade grade = (Grade) obj[1];
15         }
16
17         tx.commit();
18         HibernateFactory.closeSession();
19     }
20 }

Query.iterator与Query.list的比较

iterator的使用方法如下

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3
 4         Session session = HibernateFactory.currentSession();
 5         Transaction tx = session.beginTransaction();
 6
 7         Query query = session.createQuery("from Student");
 8         Iterator iterator = query.iterate();
 9         while(iterator.hasNext()) {
10             Student student = (Student)iterator.next();
11             System.out.println(student.getName());
12         }
13
14         tx.commit();
15         HibernateFactory.closeSession();
16     }
17 }

iterator方式查询产生的sql语句如下

 1 Hibernate: select student0_.id as col_0_0_ from student student0_
 2
 3 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
 4
 5 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
 6
 7 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
 8
 9 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
10
11 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
12
13 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
14
15 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?
16
17 Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.gradeid as gradeid3_1_0_ from student student0_ where student0_.id=?

通过list方式查询产生的sql语句如下

1 Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.gradeid as gradeid3_1_ from student student0_

两者相比较,list()只发一条语句将符合条件的数据全部查出,而iterator()却现将id查出来,然后根据id再将符合条件的数据查出,这就构成了N+1的问题;既然list更高效,为什么hibernate还将iterator存在呢?

执行以下程序

 1 public class HibernateTest {
 2     public static void main(String[] args) {
 3
 4         Session session = HibernateFactory.currentSession();
 5         Transaction tx = session.beginTransaction();
 6         String hql = "from Student";
 7
 8         Query listQuery = session.createQuery(hql);
 9         List<Student> list = listQuery.list();
10         for(Student student : list) {
11             System.out.println(student.getName());
12         }
13
14         Query iteratorQuery = session.createQuery(hql);
15         Iterator iterator = iteratorQuery.iterate();
16         while(iterator.hasNext()) {
17             Student student = (Student)iterator.next();
18             System.out.println(student.getName());
19         }
20
21         tx.commit();
22         HibernateFactory.closeSession();
23     }
24 }

最终产生的sql语句如下

1 Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.gradeid as gradeid3_1_ from student student0_
2 Hibernate: select student0_.id as col_0_0_ from student student0_

将list()和iterator()放在一起使用,这时的iterator只执行了一条SQL,原因在于hibernate的缓存机制

list()方法将执行Select SQL从数据库中获取所有符合满足条件的记录并构造相应的实体对象,实体对象构建完毕后,就将其纳入缓存;

这样等到iterator()执行时,首先会执行一条SQL来查询符合条件数据的id,随即,iterator方法首先在本地缓存内根据id查找对应的实体对象是否存在,如果缓存中已经存在对应的数据,则直接以此数据对象作为查询结果;如果没有找到,则再次执行Select语句获得对应数据库中的表记录(如果iterator在数据库中查到并构建了完整的数据对象,也会将其纳入缓存中);

list()方法无法读取缓存,但它可以写入缓存,在上面这个实例中,list()将读取的数据放入缓存中,iterator()直接可以用于是出现了以上的结果;

如果目标数据只读或者读取相当频繁,可以使用iterator()来减少性能上的消耗;

hibernate 数据库查询

时间: 2024-10-05 20:13:40

hibernate 数据库查询的相关文章

Hibernate通过什么方法可以把私有成员变量赋值成数据库查询到的值然后返回POJO对象呢?

public void setAccessible(boolean flag) throws SecurityException将此对象的 accessible 标志设置为指示的布尔值.值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查.值为 false 则指示反射的对象应该实施 Java 语言访问检查.参考博文:http://www.cnblogs.com/sunxucool/p/3552985.html Hibernate通过什么方法可以把私有成员变量赋值成数据库查询到

对象序列化和反序列--Hibernate的查询和新增极其相似

Hibernate几个关键字持久化,ORM(关系对象映射)(数据库中关系称作是一张表) 应用在项目中,刘一从写的查询代码,每次都挂掉,想要弄出测试数据,自己想着把查询出来的复杂数据弄到文件里自己要是去造那些复杂数据很麻烦public class Object1 { public static void main(String args[]){ HashMap<String, Object> obj=new HashMap<String,Object>(); obj.put(&quo

Hibernate HQL查询:

Hibernate HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装.完整的HQL语句形势如下:Select/update/delete…… from …… where …

NHibernate 有好几种数据库查询方式

NHibernate 有好几种数据库查询方式 1.原生SQL var employeeQuery = Database.Session .CreateSQLQuery("select * from Employee where FirstName = 'John'") .AddEntity(typeof(Employee)); var employees = employeeQuery.List<Employee>(); 2.Hibernate Query Language

IDEA中使用Hibernate数据库框架指导

1.   创建工程 通过idea创建一个支持hibernate数据库的project,在创建工程的时候需要有一些必须的操作, 下面逐步进行说明 第一步:创建Idea Project 注意,这里要勾选Hibernate. 指定工程的目录. 第二步:配置数据库 通过右边栏中的Database选项卡创建一个MySQL的DataBase的实例. 这里填写本地MySQL的信息,包括使用的数据库,这里提前在MySQL数据库中创建了一个名称是test的Database.填写完成之后,点击中间右侧的Test C

Hibernate HQL查询语句总结

Hibernate HQL查询语句总结 1. 实体查询:有关实体查询技术,其实我们在先前已经有多次涉及,比如下面的例子:String hql="from User user ";List list=session.CreateQuery(hql).list();上面的代码执行结果是,查询出User实体对象所对应的所有数据,而且将数据封装成User实体对象,并且放入List中返回.这里需要注意的是,Hibernate的实体查询存在着对继承关系的判定,比如我们前面讨论映射实体继承关系中的E

转: 在hibernate中查询使用list,map定制返回类型

在使用hibernate进行查询时,使用得最多的还是通过构建hql进行查询了.在查询的过程当中,除使用经常的查询对象方法之外,还会遇到查询一个属性,或一组聚集结果的情况.在这种情况下,我们通常就需要对返回的结构进行处理.    一般情况下,我们通过构建hql,并通过设置query的resultTransformer来定制返回结果的类型,一般设置为map属性,如下所示: 1 Query query = session.createQuery("hql"); 2 query.setResu

Hibernate createSQLQuery 查询char类型结果为一个字符解决方法汇总

在使用Hibernate的原生态SQL对Oracle进行查询时,碰到查询char类型的时候始终返回的是一个字符,开始认为应该是Hibernate在做映射的把数据类型给映射成char(1),在经过查找网上的一些资料,得知产生这个问题的主要原因确实是Hibernate再查询Oracle的时候,将char自动映射成character(varchar的子集)类型,oracle的char字段在hibernate里映射为character类型,是varchar的子集. 现有以下几种解决方法: 1:将你要查询

hibernate学习(查询)

数据查询是hibernate的一个亮点,hibernate为程序猿提供了多种的查询方式,分为以下三种: 1.hibernate语言查询,也就是我们今天需要说的hql查询,这种查询是完全面向对象的方式来查询,将查询语句封装为对象来进行操作.符合面向对象的思维来维护数据库. 2.hibernate标准化查询:(criteria query)将查询语句封装成对象进行操作. 3.原声sql查询:直接使用标准sql语言来进行查询. hql查询所有 在学习hql查询之前,我先插入一些记录到userinfo表