创建Query对象
Query query = session.createQuery("from Orders as o where o.oid = :oid");
动态绑定参数(如果需要)
query.setInteger("oid", 1);
执行查询,返回查询结果
List list = query.list();
使用where来设定查询条件
Where子句中给出的是对象的属性名,而不是字段名
如:查询名叫张三的学生from Student as s where s.name=‘张三’
检索年龄大于18的Customer对象
From Customer c where c.age>18
检索年龄不等于18的Customer对象
From Customer c where c.age<>18
检索姓名为空的Customer对象
From Customer c where c.name is null
检索姓名为Tom的Customer对象
From Customer c where lower(c.name)=‘tom’
检索姓名为tom,mike,jack的Customer对象
From Customer c where c.name in(‘tom’,’mike’,’jack’)
检索年龄在18~25之间的Customer对象
From Customer c where c.age between 18 and 25
检索年龄不在18~25之间的Customer对象
From Customer c where c.age not between 18 and 25
检索姓名以T开始的Customer对象
From Customer c where c.name like ‘T%’
检索姓名中包含字符串“om”的Customer对象
From Customer c where c.name like ‘%om%’
检索姓名以T开头,并且字符串长度为3的Customer对象
From Customer c where c.name like ‘T_ _’
检索姓名以T开头,并且以m结尾的Customer对象
From Customer c where c.name like ‘T%’ and c.name like ‘%m’
检索姓名以T开头,并且以m结尾,或者年龄不在18~25之间的Customer对象
From Customer c where (c.name like ‘T%’ and c.name like ‘%m’) or (c.age not between 18 and 25)
返回的List集合元素为Object[]
Query query = session.createQuery("select c.cname, c.csex from Customer c");
List list = query.list();
Iterator iter = list.iterator();
Object[] objs = null;
while(iter.hasNext()){
objs = (Object[]) iter.next();
for(int i = 0; i < objs.length; i ++){
System.out.println(objs[i]);
}
System.out.println("-------------------");
}
Query query = session.createQuery("from Customer c");
query.setFirstResult((当前页-1) * 页大小);//从哪儿开始取
query.setMaxResults(页大小);//最多取多少条记录
Iterator iter = query.list().iterator();
Customer c = null;
while(iter.hasNext()){
c = (Customer) iter.next();
System.out.print(c);
}
连接类型 HQL语法
内连接 inner join 或者 join
迫切内连接 inner join fetch 或者 join fetch
左外连接 left outer join 或者 left join
迫切左外连接 left outer join fetch 或者 left join fetch
右外连接 right outer join 或者 right join
Query query = session.createQuery("from Customer c left join fetch c.orders o");
Iterator iter = query.list().iterator();
说明:
关键字:left join fetch
返回结果为Customer类型,再通过Customer对象导航到Orders对象
返回结果可能包含重复元素,通过Set去掉重复行
结果见备注
Query query = session.createQuery("from Customer c left join c.orders o");
Iterator iter = query.list().iterator();
说明:
关键字:left join
返回的集合中,元素类型为Object[],该数组包含Customer和Orders对象,即:Object[0]=Customer,Object[1]=Orders
没有重复元素
结果见备注
Query query = session.createQuery("from Customer c inner join c.orders o");
Iterator iter = query.list().iterator();
说明:
关键字:inner join
返回的集合中,元素类型为Object[],该数组包含Customer和Orders对象,即:Object[0]=Customer,Object[1]=Orders
没有重复元素
结果见备注
和左外连接的处理方式相同
Query query = session.createQuery("from Customer c inner join fetch c.orders o");
Iterator iter = query.list().iterator();
说明:
关键字:inner join fetch
返回结果为Customer类型,再通过Customer对象导航到Orders对象
返回结果可能包含重复元素,通过Set去掉重复行
结果见备注
处理方式和迫切左外连接相同
Query query = session.createQuery("from Customer c right outer join c.orders o");
Iterator iter = query.list().iterator();
说明:
关键字:right outer join
返回的集合中,元素类型为Object[],该数组包含Customer和Orders对象,即:Object[0]=Customer,Object[1]=Orders
没有重复元素
结果见备注
和左连接、内连接的处理方式相同
//总结一下:如果有fetch这个关键字,那么返回的就是一个对象,而且这个set包含的对象可能存在重复行,如果没有,那么返回的就是一个Object的数组,没有重复行
Query query = session.createQuery("select c.cid, c.cname, o.odate from Customer c right outer join c.orders o");
Iterator iter = query.list().iterator();
说明
投影即只返回一部分字段
返回的结果集中,元素类型为Object[],数组中元素个数即为select语句后的字段个数
结果见备注
对客户按性别分组
select c.csex, count(*) from Customer c group by c.csex
说明:
返回的结果集中,元素类型为Object[],数组元素个数即为返回的字段个数
统计出每个客户的订单数量
select c.cname, count(o) from Customer c left join c.orders o group by c.cname
找出年龄最大的客户
Query query = session.createQuery("select max(c.cage) from Customer c");
Object obj = query.uniqueResult();
通过uniqueResult()保证只返回一个结果
代码见备注
找出年龄大于平均年龄的客户
select c.cname, c.cage from Customer c where c.cage > (select avg(c.cage) from Customer c)
结果见备注
子查询可以和all,any,some,in,exists使用
找出至少有一份订单的客户
from Customer c where exists (from c.orders)
代码见备注
查询策略
1. 懒加载lazy
表内:get/load
表外:映射lazy=false/proxy(默认)
2. 缓存
3. pojo对象三种状态
4. inverse 主动权
5. cascade
6. fetch
查询方式
1. HQL(批量)
2. 主键查(单个,已知主键)
3. SQL
4. QBC(Query by criatia)
5. 配置文件查
HQL-Hibernate Query Language
一.特点:
1.功能强,能进行增删改查crud
select ...
update...
delete
insert into 类 select a from 类 a
2.跨平台(数据库)
3.最灵活,要求最高
二.什么情况下使用hql
批量操作时.
三.注意
1.表名写类名,字段名写属性名,这些区分大小写.
from 类
2.不能有select * from 类或表
3.多表连接要取别名
4.非查询还是要事务
5.hql不支持级联
四.原理
hibernate会根据方言(oracel,sqlserver)翻译最终sql语句。
五.下列位置可以写hql语句
1.工程里面new-->file后缀名如 a.hql,可以直接执行
2.在映射文件中(项目要求)还要配合代码
3.写代码(平时)
六.如何写
//查所有部门
from Dept
from Dept d
select d from Dept d
//排序
from Dept order by depid
from Dept order by depid asc
from Dept order by depid desc
from Dept order by depid desc,depname asc
//条件查询
from Dept where depid = ?
from Dept where depid < ?
from Dept where depid = ? or depid = ? //not,and,or
from Dept where depid in (1,2,5); //相当or
from Dept where depid is null; //编号为空
from Dept where depid is not null; //编号不为空
from Dept where depname like ?
//分页
query.setFirstResult((页数-)*条数).setMaxResults(条数);
//日期函数
year得年
* month得月
* date得日
* day得星期
* hour时
* minute分
* second秒
*
* current_date当前日期
//投影
select depid,depname from Dept
七.如何执行
Query接口
1.创建
Query query = session.createQuery(hql); //hql翻译时sql
Query query = session.getNameQuery("name");映射文件
2.常用方法
query.list(); //查出来结果放到list集合
query.setParameter(0, value); //设?
query.setParameter(1, value);
query.executeUpdate() ;//增删改,要事务
query.uniqueResult();唯一结果(一条),取聚集查询
//分页
query.setFirstResult(从哪开开始查,默认0);
query.setMaxResult(最多返回多少条记录);
如果每页10条,显示第8页
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<query name="Dep.getAllDep">
from Dep
</query>
<query name="Temp.id">
select max(id) from Temp where id like ?
</query>
</hibernate-mapping>
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import com.pojos.Dep;
import com.util.HibernateSessionFactory;
public class HQL语句写在映射文件中 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session =HibernateSessionFactory.getSession();
Query query = session.getNamedQuery("Dep.getAllDep");
List<Dep> list = query.list();
for (Dep dep : list) {
System.out.println(dep.getDepName());
}
}
}
import org.hibernate.Session;
import com.util.HibernateSessionFactory;
public class 增删改 {
/**
* 1. 要事务
* 2. 不支持级联
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
String sql = "delete from Dep";
int n = session.createQuery(sql).executeUpdate();
System.out.println(n);
}
}
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import com.pojos.Dep;
import com.util.HibernateSessionFactory;
public class 查整张表 {
/**
* Query by Criteria
*/
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Criteria c = session.createCriteria(Dep.class);
List<Dep> list = c.list();
for (Dep dep : list) {
System.out.println(dep.getDepName());
}
}
}
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Expression;
import com.pojos.Dep;
import com.util.HibernateSessionFactory;
public class 条件查询 {
/**
* Query by Criteria
* 跨平台,不支持删除操作
*/
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Criteria c = session.createCriteria(Dep.class);
//c.add(Expression.between("depId", 1, 3));
c.add(Expression.or(Expression.eq("depId", 1), Expression.eq("depId", 3)));
List<Dep> list = c.list();
for (Dep dep : list) {
System.out.println(dep.getDepName());
}
}
}
import java.util.List;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import com.pojos.Dep;
import com.util.HibernateSessionFactory;
public class 本地sql查询 {
/**
* 不跨平台
*/
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
//本地sql语句不区分大小写
String sql = "select * from dEp";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Dep.class); //放一条记录转换Dep对象
List<Dep> list = query.list();
for (Dep dep : list) {
System.out.println(dep.getDepName());
}
}
}
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.util.HibernateSessionFactory;
public class 本地sql删除 {
/**
* @param args
*/
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tr = session.beginTransaction();
String sql = "delete from emp where empid=151";
SQLQuery query = session.createSQLQuery(sql);
int n = query.executeUpdate();
tr.commit();
}
}
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.Session;
import org.hibernate.connection.C3P0ConnectionProvider;
import com.mysql.jdbc.Statement;
import com.util.HibernateSessionFactory;
public class 调用存储过程 {
/**
* @param args
* @throws SQLException
*
* int aaa(int x, int y)
* {
* return x+y;
* }
*
*/
public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
Session session =HibernateSessionFactory.getSession();
Connection con = session.connection();
String sql = " {call aaa(?,?,?)}";
CallableStatement cs = con.prepareCall(sql);
cs.registerOutParameter(3, Types.INTEGER); //返回类型int
cs.setObject(1, 100);
cs.setObject(2, 200);
cs.execute();
int n = cs.getInt(3);
System.out.println(n);
// C3P0ConnectionProvider
}
}
查询与优化
一.连接查询
sql:
select * from Emp,Dep where ...
select * from Emp join dept on 条件
二.懒加载lazy/立即加载
get/load区别
1. get是立即加载,load延时加载(代理对象)
2. get没有找到,返回null,load没有找到,报异常。
lazy配置关联表, 不能为false(立即加载),lazy=true懒加载(默认)
三.迫切查询
用代码控制立即加载.
join fetch
四.连接池
c3p0
dbcp
1.复制开发包
2.总的配置文件
connection.provider_class
值 ,略
五.乐观锁
A:1000 转3000
B:2000 0
version版本控制
实现
1.表中加一个数字类型字段ver
2.pojo类多一个属性
3.映射文件配置两个地方
a)字段名映射改version(要放在id后面)
<version name="ver" type="java.lang.Long">
<column name="VER" precision="22" scale="0" />
</version>
b) class后面加optimistic-lock="version"
六.缓存
七.主键优化
uuid