先简单给大家介绍下关于hibernate重点额检索方式吧~
整体是分为5种方式,分别为
1.oid检索
2.导航对象检索
3.本地sql
4.qbc
5.hql
其中HQL在实际开发中比较常用,所以先给大家整理一份关于HQL的相关资料吧~
其实关于HQL,我是基于下面3个方向来演示
1.标准hql
2.hql命名检索
3.hql多表
ok.话不多说,往下看吧~
首先我们要玩转hibernate,那么核心的对象就是SessionFactory对象了~
那么关于HQL使用步骤呢?我整理了下,大概可以分为5步:
a)通过SessionFactory获取session对象
b)编写HQL语句
c)通过session.createQuery(hql)获取一个query对象
d)为query对象设置参数
e)执行对应方法 query.list()返回一个集合/query.uniqueResult()返回一个结果
1.标准HQL
1)基本检索 from 类名
eg:
[Java] 纯文本查看 复制代码 //关键字不区分大小写,类名区分
String hql = "from Customer";
Query query = session.createQuery(hql).list();
2)排序检索 from 类名 order by 属性 asc/desc
eg:
[Java] 纯文本查看 复制代码 String hql = "from Order order by money desc"; // desc 降序 默认是asc 升序
List<Order> list = session.createQuery(hql).list();
3)条件检索
方式一:from 类名 where 属性=? and 属性=?
eg:
[AppleScript] 纯文本查看 复制代码 String hql = "from Order where money>? and name=?";
List<Order> list = session.createQuery(hql)
.setParameter(0,2000)
.setParameter(1,"张三")
.list();
方式二:from 类名 where 属性 = :名称
注意:名称随意,要和后面setParameter中的key对应起来
eg:
[Java] 纯文本查看 复制代码 String hql = "from Order where money>:mmmoney and name=:nnname";
List<Order> list = session.createQuery(hql)
.setParameter("mmmoney",2000)
.setParameter("nnname","张三")
.list();
4)分页检索 query.setFirstResult(开始位置)和query.setMaxResults(多少条)
eg:
[Java] 纯文本查看 复制代码 Query query = session.createQuery("from Order");
// 每页显示6条件 ,我们要得到第二页数据
query.setFirstResult((2 - 1) * 6); // 设定开始位置
query.setMaxResults(6); // 设置条数
List<Order> list = query.list();
5)分组统计检索
统计: select 统计函数(属性) from 类名
eg:
[Java] 纯文本查看 复制代码 String hql="select count(*) from Order";
Object count = session.createQuery(hql).uniqueResult();
分组: select 统计函数(属性) from 类名 group by 属性
eg:
[Java] 纯文本查看 复制代码 String hql="select count(*) from Order group by mCostomer";
Object count = session.createQuery(hql).uniqueResult();
6)投影检索(将查询结果封装到po中) select new 类名(属性1,属性2) from 类名
eg:
[Java] 纯文本查看 复制代码 //必须在PO类中提供无参和对应参数的构造方法
String hql = "select new Customer(id,name) from Customer";
List<Customer> cs = session.createQuery(hql).list();
2.hql命名检索
方式一: XXX.hbm.xml文件配置hql命名
a)定义Order实体类
[Java] 纯文本查看 复制代码 public class Order {
private Integer id;
private Double money;//金额
private String receiverInfo; // 收货地址
private Customer mCustomer;// 订单与客户关联
//省略get/set方法
......
}
b)定义Order.hbm.xml
[Java] 纯文本查看 复制代码 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package属性代表javabean所在的包 -->
<hibernate-mapping package="com.b3a4a.domain">
<class name="Order" table="t_order" catalog="db_hibernate_study">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="20"></property>
......
</class>
<query name="HQL名称 (eg:findOrderByCustomer)">
HQL语句 (eg: from Order where mCustomer:mmmmmCustomer)
</query>
</hibernate-mapping>
c)配置核心文件hibernate.cfg.xml
[Java] 纯文本查看 复制代码 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
......
<mapping resource="com/b3a4a/domain/Order.hbm.xml" />
</session-factory>
</hibernate-configuration>
d)测试用例
[Java] 纯文本查看 复制代码 @Test
public void test() {
Session mSession = new Configuration().configure()
.buildSessionFactory()
.openSession();
mSession.beginTransaction();
//----------------关键代码----------------
// 1.我要查询张三这个客户的订单
Customer c = mSession.get(Customer.class, 1);
Query query = mSession.getNamedQuery("findOrderByCustomer"); // from Order where c=:c
// 2.现在hql它的参数是一个实体
List<Order> list = query.setEntity("mmmmmCustomer", c).list();
//----------------------------------------
mSession.getTransaction().commit();
mSession.close();
}
方式二: PO注解配置hql命名
a)定义Order实体类,使用注解配置hql命名
[Java] 纯文本查看 复制代码 @Entity
@Table(name = "t_order")
//name:HQL名称
//query:HQL语句
@NamedQuery(name="findOrderByCustomer",query="from Order where mCustomer=:mmmmmCustomer")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;//主键
private Double money;//金额
private String receiverInfo; // 收货地址
@ManyToOne(targetEntity = Customer.class)
@JoinColumn(name = "c_customer_id")
@Cascade(CascadeType.SAVE_UPDATE)
private Customer mCustomer;// 订单与客户关联
//省略get/set方法
......
}
b)测试用例
[Java] 纯文本查看 复制代码 @Test
public void test() {
Session mSession = new Configuration().configure()
.buildSessionFactory()
.openSession();
mSession.beginTransaction();
//----------------关键代码----------------
// 1.我要查询张三这个客户的订单
Customer c = mSession.get(Customer.class, 1);
Query query = mSession.getNamedQuery("findOrderByCustomer"); // from Order where c=:c
// 2.现在hql它的参数是一个实体
List<Order> list = query.setEntity("mmmmmCustomer", c).list();
//----------------------------------------
mSession.getTransaction().commit();
mSession.close();
}
3.hql多表
hql多表常用的方式分为内连接,外链接
注意:
a)HQL中with就相当于SQL中的on
b)fetch不可以与单独条件的with一起使用
内链接
显式内链接: from 类名 别名 inner join 别名.从表对象 where 条件 (with 条件)
eg:
[Java] 纯文本查看 复制代码 // sql连接 select * from t_customer inner join t_order on 条件
String hql = "from Customer c inner join c.orders with c.id=1";
Query query = session.createQuery(hql);
// Object[]中装入的是Customer与Order对象。
List<Object[]> list = query.list();
隐式内链接: from 类名 别名 where 别名.从表对象.从表属性 = 条件
eg:
[Java] 纯文本查看 复制代码 // sql连接 select * from t_customer,t_order where 条件
String hql = "from Order o where o.c.id=1";
Query query = session.createQuery(hql);
List list = query.list();
迫切内链接: from 类名 别名 inner join fetch 别名.从表对象 where 条件
eg:
[Java] 纯文本查看 复制代码 // 迫切内连接 inner join fetch 注意:使用迫切连接结果可能出现重复,所以要使用distinct来去重复
String hql = "select distinct c from Customer c inner join fetch c.orders";
// 底层也是执行的inner join 只不过结果封装到对象中。
Query query = session.createQuery(hql);
List<Customer> list = query.list();
外连接
左外连接: from 类名 别名 left outer join 别名.从表对象 where 条件
eg:
[Java] 纯文本查看 复制代码 List<Object[]> list = session
.createQuery("from Customer c left outer join c.orders").list();
右外连接
迫切左外连接
eg:
[Java] 纯文本查看 复制代码 // 注意:fetch不可以与单独条件的with一起使用
List<Customer> list = session
.createQuery("select distinct c from Customer c left outer join fetch c.orders where c.id=1").list();
|