目录
二、对象导航检索(根据一个已经查询到的对象,获得其关联的对象)
7.离线查询(DetachedCriteria脱离Session)
一、OID查询(根据对象的OID(主键)进行检索)
1.get(立即加载)
Customer customer = session.get(Customer.class,1l);
2.load(延迟加载)
Customer customer = session.load(Customer.class,1l);
二、对象导航检索(根据一个已经查询到的对象,获得其关联的对象)
LinkMan linkMan = session.get(LinkMan.class,1l);
Customer customer = linkMan.getCustomer();
Customer customer = session.get(Customer.class,2l);
Set<LinkMan> linkMans = customer.getLinkMans();
三、HQL查询(多表查询,但不复杂时使用)
HQL 查询语句是面向对象的, Hibernate 负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息, 把 HQL 查询语句翻译成相应的 SQL 语句。HQL 查询语句中的主体是域模型中的类及类的属性。
1.Query接口接收HQL语句
Query代表面向对象的一个Hibernate查询操作,在Hibernate中,通常使用如下方法接收一个HQL语句。
然后再调用Query的list或uniqueResult方法执行查询。
当uniqueResult返回值为数值时注意,返回类型默认为Long型,如果把返回结果值直接强转成Integer类型,会报错,可以先返回Long型,然后转为Integer型
Query query = session.createQuery("HQL语句"); //接收HQL语句
List<T> list = query.list(); //返回多条记录
T t = (T)query.uniqueResult(); //返回一条记录
2.完整查询
select ... from ... where ... group by ... having ... order by ... asc/desc
3.基本查询
在HQL语句中,本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。同时,在Hibernate中,查询的目标实体存在继承关系的判定,如果from User
将返回所有User以及User子类的记录。假设系统中存在User的两个子类:SysAdmin和SysOperator,那么该hql语句返回的记录将包含这两个子类的所有数据,即使SysAdmin和SysOperator分别对应了不同的库表
String hql = "from User";
4.条件查询(无参数绑定)where
Where子句: 如果我们想取出名为“mark”的用户记录,可以通过Where子句加以限定
String hql = "from User as user where user.name='mark'";
where子句中,我们可以通过比较操作符指定甄选条件,如: =, , <, >, <=, >=, between, not between, in ,not in, is, like等。同时,在where子句中可以使用算术表达式
String hql = "from User user where user.age<20";
String hql = "from User user where user.name is null";
String hql = "from User user where user.name like 'mk%'";
String hql = "from User user where (user.age % 2 = 1)";
String hql = "from User user where (user.age<20) and (user.name like '%mk')";
5.条件查询(参数绑定)
(1)顺序占位符 ?
String hql = "from User user where user.name = ? and user.age = ?";
Query query= session.createQuery(hql);
/*query.setString(0, "mark");
query.setInteger(1, 10);*/
//第一个参数为索引,第二个参数为索引值
query.setParameter(0, "mark");
query.setParameter(1, 10);
(2)引用占位符 :name
String hql = "FROM User user WHERE user.uName = :name AND user.uAge = :age";
Query query= session.createQuery(hql);
//第一个参数为引用名,第二个参数为值
query.setParameter("name", "mark");
query.setParameter("age", "mark");
6.投影查询(获取实体部分属性)
有时,我们需要的数据可能仅仅是实体对象的某个属性(库表记录中的某个字段信息)。我们指定了只需要获取User的name属性。此时返回的list数据结构中,每个条目都是一个String类型的name数据
String hql = "select user.name from User user";
List<Object> list = session.createQuery(hql).list();
String hql = "select user.name,user.age from User user";
List<Object[]> list = session.createQuery(hql).list();
//User需要提供有参构造函数
String hql = "select new User(user.name,user.age) from User user";
List<User> list = session.createQuery(hql).list();
7.聚合查询
我们也可以在HQL的select子句中使用统计函数或者利用DSITINCT关键字,剔除重复记录
String hql = "select count(*),min(user.age) from User user";
String hql = "select distinctuser.name from User user";
8.分组与排序
Order by子句,默认情况下是按照升序排序,当然我们可以指定排序策略
String hql = "from User user order by user.name";
String hql = "from User user order by user.name desc";
通过Group by可进行分组统计,如果下例中,我们通过Group by子句实现了同龄用户的统计
String hql = "select count(user),user.age from User user group by user.age";
通过该语句,我们获得了一系列的统计数据。对于Group by子句获得的结果集而言,我们可以通过Having子句进行筛选。例如,在上例中,我们对同龄用户进行了统计,获得了每个年龄层次中的用户数量,假设我们只对超过10人的年龄组感兴趣,可用以下语句实现
String hql ="select count(user),user.age from User user group by user.age having count(user) > 10";
9.分页查询
String hql ="from Student";
Query query = session.createQuery(hql);
//设置获取第一个记录的位置,从第几条记录开始查询,默认从0开始
query .setFirstResult(0);
//设置结果集的最大记录数
query .setMaxResults(2);
10.多表查询
(1)内连接(返回的数据以数组的方式封装)
//linkmans是Customer中对另一个对象Linkman的Set封装
String hql = "from Customer c inner join c.linkmans";
(2)迫切内连接fetch(返回的数据以对象的方式封装)
//linkmans是Customer中对另一个对象Linkman的Set封装
String hql = "from Customer c inner join fetch c.linkmans";
(3)左外连接
//linkmans是Customer中对另一个对象Linkman的Set封装
String hql = "from Customer c left join c.linkmans";
(4)右外连接
//linkmans是Customer中对另一个对象Linkman的Set封装
String hql = "From Customer c right join c.linkmans";
四、QBC查询(单表条件查询,更加面对对象)
Criteria是一个完全面向对象,可扩展的条件查询API,通过它完全不需要考虑数据库底层如何实现,以及SQL语句如何编写,它是Hibernate框架的核心查询对象,Criteria查询,又称为QBC查询(Query By Criteria),它是Hibernate的另一种对象检索方式
1.Criteria接口接收语句
Criteria criteria = session.createCriteria(Customer.class);
2.基本查询
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
3.条件查询
Restrictions的静态方法创建Criterion条件对象,Restrictions类中提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件
Criteria criteria = session.createCriteria(Customer.class);
//添加条件
criteria.add(Restrictions.eq("name","mark"));
criteria.add(Restrictions.eq("age","20"));
List<Customer> list = criteria.list();
4.分组统计查询
Projections类的常用方法(统计和分组)
返回值类型 | 方法名称 | 描述 |
AggregateProjection | Projections.avg | 求平均值 |
CountProjection | Projections.count | 统计某属性的数量 |
CountProjection | Projections.countDistinct | 统计某属性不同值的数量 |
PropertyProjection | Projections.groupProperty | 指定某个属性为分组属性 |
AggregateProjection | Projections.max | 求最大值 |
AggregateProjection | Projections.min | 求最小值 |
ProjectionList | Projections.projectionList | 创建一个ProjectionList对象 |
Projection | Projections.rowCount | 查询结果集中的记录条数 |
AggregateProjection | Projections.sum | 求某属性的合计 |
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.rowCount());
5.分页查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(3); //起始索引
criteria.setMaxResult(3); //显示记录条数
criteria.setProjection(Projections.rowCount()); //执行聚合函数,返回记录总条数
Long count = (Long)criteria.uniqueResult();
6.排序查询
Order类的常用方法(设置排序方式)
返回值类型 | 方法名称 | 描述 |
Order | Order.asc | 升序 |
Order | Order.desc | 降序 |
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Order.desc("cust_id")); //添加条件
7.离线查询(DetachedCriteria脱离Session)
DetachedCriteria可以脱离Session来使用的一种条件查询对象,Criteria对象必须由Session对象来创建,那么也就是说必须有Session才可以生成Criteria对象,而DetachedCriteria对象可以在其他层对条件进行封装
这个对象也是比较有用的,尤其在SSH整合以后经常会用到。它的主要优点是做一些特别复杂的条件查询的时候,往往会在Web层向业务层传递很多的参数,业务层又会将这些参数传递给DAO层,最后在DAO层拼接SQL完成查询。有了离线条件串对象后,我们可以在Web层将数据封装好,传递到业务层,再由业务层传递给DAO层完成查询
//Web|Service层
//1.创建DetachedCriteria并设置条件
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.idEq(6l));//拼装条件(全部与普通Criteria一致)
//2、执行查询(Criteria getExecutableCriteria(Session session))
Session session = HibernateUtil.getSession();
Criteria c = dc.getExecutableCriteria(session);
五、原生SQL查询(复杂的业务查询)
1.SQLQuery接口接收语句
SQLQuery接口用于接收一个sql语句进行查询,但是sql语句不会直接封装到实体对象中,需要我们调用addEntity进行封装,然后调用list或uniqueResult方法进行查询
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.addEntity(Customer.class);
2.记录查询
String sql = "SELECT * FROM customer ";
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.addEntity(Customer.class);
List<Customer> list = sqlQuery.list();
3.条件查询
使用?占位符
String sql = "SELECT * FROM customer WHERE cust_id = ?";
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.setParameter(0,1); //设置参数
sqlQuery.addEntity(Customer.class); //封装到实体类
List<Customer> list = sqlQuery.list(); //返回结果
使用:参数名 占位符
String sql = "SELECT * FROM customer WHERE cust_id = :custId";
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.setParameter("custId",1); //设置参数
sqlQuery.addEntity(Customer.class); //封装到实体类
List<Customer> list = sqlQuery.list(); //返回结果
4.分页查询
String sql = "SELECT * FROM customer limit ?,?";
SQLQuery sqlQuery = session.createSQLQuery(sql);
//设置起始参数
sqlQuery.setParameter(0,0);
sqlQuery.setParameter(0,1);
sqlQuery.addEntity(Customer.class); //封装到实体类
List<Customer> list = sqlQuery.list(); //返回结果