Hibernate多表查询、查询优化策略(四)
多表HQL
private static void innerJoin(){
//sql内连接 隐式内连接 select * from A,B where b.aid = a.id
// 显示内连接 select * from A inner join B on b.aid = a.id
//hql内连接 =>类似原生sql 返回合并的
Query query = session.createQuery("from Category c inner join c.products");
List<Object> objs = query.list();
for(Object o : objs){
System.out.println(o);
}
}
private static void innerJoinfetch(){
//迫切hql内连接 =>帮我进行封装
Query query = session.createQuery("from Category c inner join fetch c.products");
List<Category> categorys = query.list();
for(Category o : categorys){
System.out.println(o.getCname());
for(Product p : o.getProducts()){
System.out.println(p.getPname());
}
}
}
private static void leftJoin(){
//外连接 左外连接 select * from A left [outer] join B on b.aid = a.id
//hql 左连接
Query query = session.createQuery("from Category c left join c.products");
List<Object> objs = query.list();
for(Object o : objs){
System.out.println(o);
}
}
private static void leftJoinfetch(){
//hql 左连接 迫切
Query query = session.createQuery("from Category c left join fetch c.products");
List<Category> categorys = query.list();
for(Category o : categorys){
System.out.println(o.getCname());
for(Product p : o.getProducts()){
System.out.println(p.getPname());
}
}
}
private static void rightJoin(){
//外连接 右外连接 select * from A right [outer] join B on b.aid = a.id
//hql右连接
Query query = session.createQuery("from Category c right join c.products");
List<Object> objs = query.list();
for(Object o : objs){
System.out.println(o);
}
}
private static void rightJoinfetch(){
//外连接 右外连接 select * from A right [outer] join B on b.aid = a.id
//hql右连接 迫切
Query query = session.createQuery("from Category c right join fetch c.products");
List<Category> categorys = query.list();
for(Category o : categorys){
System.out.println(o.getCname());
for(Product p : o.getProducts()){
System.out.println(p.getPname());
}
}
}
Criteria(QBC)离线查询对象
//传统criteria是依赖于session的
Criteria criteria = session.createCriteria(Category.class);
criteria.add(Restrictions.eq("cid",1));
Category c = (Category) criteria.uniqueResult();
System.out.println(c.getCname()); //离线的criteria 凭空创建
//service/web层
DetachedCriteria dc = DetachedCriteria.forClass(Category.class);
dc.add(Restrictions.gt("cid",0));
//dao层
Criteria criter = dc.getExecutableCriteria(session);
List<Category> categories = criteria.list();
for(Category ca : categories){
System.out.println(ca.getCname());
for(Product p : ca.getProducts()){
System.out.println(p.getPname());
}
}
查询优化策略
懒加载(延迟加载):使用hibernate查询一个对象的时候,查询其关联对象,应该如何查询。是hibernate的一种优化手段。
类级别查询
session对象的load方法默认就是延迟加载, 可以在对象对应的配置文件中 class节点中配置lazy属性控制是否启用。如果false则会跟get没有任何区别。
public static void main(String[] args) {
Session session = HibernateUtils.openSession();
//get方法:立即加载,执行时立即发送sql语句
Category c = session.get(Category.class,1);
System.out.println(c);
//延迟加载:仅仅获得没有使用,不会查询 返回代理对象
Category c1 = session.load(Category.class,2);
//在使用对象的属性时才会进行查询
System.out.println(c1.getCname());
}
关联级别查询
集合关联级别
public static void main(String[] args) {
Session session = HibernateUtils.openSession();
//只返回Category表
Category c = session.get(Category.class,1);
System.out.println(c.getCname());
//懒加载 与此Category表相关联的Product表 使用时 才去加载
Set<Product> ps = c.getProducts(); //集合关联级别
for(Product p : ps){
System.out.println(p.getPname());
}
}
附上配置文件Category.hbm.xml
<hibernate-mapping package="com.hibernate.domain">
<class name="Category" table="Category" lazy="true">
<id name="cid" column="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<!--lazy:集合关联级别 是否懒加载 true(默认) false extra(极其懒惰-如果只获得集合的size,他会用count去查询)
fetch(加载策略-使用什么类型的sql语句加载集合数据):
select(默认):单表查询加载
join:使用多表查询加载集合(无论是否启用懒加载,都一下多表查询回来)
subselect:使用子查询加载集合(调用集合时,使用子查询语句)
-->
<set name="products" inverse="true" lazy="true" fetch="select">
<key column="cpid"></key>
<one-to-many class="Product"></one-to-many>
</set>
</class>
</hibernate-mapping>
关联属性级别
public static void main(String[] args) {
Session session = HibernateUtils.openSession();
Product p = session.get(Product.class,1);
//根据产品去获得分类信息 执行如下时才会去数据库获取
Category c = p.getCategory(); //属性关联级别
System.out.println(c.getCname());
}
配置xml解析
<hibernate-mapping package="com.hibernate.domain">
<class name="Product" table="Product">
<id name="pid">
<generator class="native"/>
</id>
<property name="pname"/> <!--fetch(加载的sql语句):
select(默认):使用单表查询
join:使用多表查询
lazy(加载时机):
proxy(默认):由Category的类级别加载策略(Category中 class元素中 lazy)决定
false:立即加载
-->
<many-to-one name="category" class="Category" column="cpid" fetch="" lazy=""></many-to-one>
</class>
</hibernate-mapping>
批量抓取
public static void main(String[] args) {
Session session = HibernateUtils.openSession();
Query query = session.createQuery("from Category");
List<Category> categories = query.list();
for(Category c : categories){
for(Product p : c.getProducts()){ //categories数量为几 这里就要执行几次sql查询c.getProducts()
System.out.println(p.getPname());
}
}
}
category.hbm.xml
<hibernate-mapping package="com.hibernate.domain">
<class name="Category" table="Category" lazy="true">
<id name="cid" column="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<!--batch-size:查询集合时一次查询多少个 默认1个 所以每次都会生成sql语句 -->
<set name="products" inverse="true" lazy="true" fetch="select" batch-size="10">
<key column="cpid"></key>
<one-to-many class="Product"></one-to-many>
</set>
</class>
</hibernate-mapping>
Hibernate多表查询、查询优化策略(四)的更多相关文章
- hibernate多表查询,结果封装在自己定义的一个实体类当中(在自己定义的类中增加构造函数)
hibernate的hql查询直接返回java对象时出现问题3 向大家请教一个问题,现在有三张表,表之间没有关联,我需要将三张表里面的所有东西查询出来存储到一个新的对象中,该如何实现,使用hibern ...
- Java面试题:Hibernate的二级缓存与Hibernate多表查询
我们来看两个有关Java框架之Hibernate的面试题,这是关于Hibernate的常考知识点. 1.请介绍一下Hibernate的二级缓存 解题按照以下思路来回答: (1)首先说清楚什么是缓存: ...
- hibernate多表查询
一对多进行查询(用懒加载的模式) 查找区域所对应的街道: Dao: public Qu selQu(String dno){ Session session=HibernateSessionFacto ...
- hibernate 多表查询
Hibernate主要支持两种查询方式:HQL查询和Criteria查询.前者应用较为广发,后者也只是调用封装好的接口. 现在有一个问题,就是实现多表连接查询,且查询结果集不与任何一个实体类对应,怎么 ...
- hibernate多表查询封装实体
以前用sql实现联合查询 是非常简单的事,只需要写sql语句就可以,第一次遇到hibernate要实现多表联合查询的时候还楞了一下.最后看了下资料,才恍然大悟,hibernate实现多表联合查询跟SQ ...
- Hibernate多表查询连接操作
SQL多表操作分类; 1.交叉连接:select*from t_customer cross Join t_order; 2.显示内连接: select*from t_customer c inner ...
- Hibernate 检索(查询)策略
1.立即检索 (查询) 立即检索就是在调用get方法的时候,会直接向数据库发出sql语句查询,并将结果放到session缓存中,在查询的时候会将级联的对象一对查出,(发出多条sql语句): 明显的缺点 ...
- Hibernate 多表查询 - Criteria添加子字段查询条件 - 出错问题解决
Criteria 查询条件如果是子对象中的非主键字段会报 could not resolve property private Criteria getCriteria(Favorite favori ...
- 【Hibernate 多表查询】
HibernateManyTable public class HibernateManyTable { //演示hql左连接查询 @Test public void testSelect12() { ...
随机推荐
- 20190625 Oracle优化查询(一)
与其惴惴不安,不如定心应变 前提:我的Oracle服务器是安装在Windows环境中的,没有上到Linux 查看表结构 查询全表 查找空值, 使用“=”是没有结果的,应该使用IS NULL
- java 导入导出的 命令
$exp lddba/ld_321@192.168.1.3/testora file=E:\db_bak\ld20170219_1testora.dmp log=E:\db_bak\ld2017021 ...
- C++项目作业 学生管理系统
/*Student.h*/#pragma once #include<string.h> using namespace std; #include<string> class ...
- Scrapy实战:使用IDE工具运行爬虫
一般我们运行爬虫程序都是使用命令行,比如:scrapy crwal sobook.不过这多少有些不方便,可以使用下面的方法使用IDE的方式运行爬虫 我这边使用的是pycharm软件,在pycharm里 ...
- Linux之网络文件共享服务(FTP)
一.FTP概念 •File Transfer Protocol 早期的三个应用级协议之一 •基于C/S结构 •双通道协议:数据和命令连接 •数据传输格式:二进制(默认)和文本 •两种模式:服务器角度 ...
- BZOJ 1602 USACO 2008 Oct. 牧场行走
[题解] 要求出树上两点间的距离,树上的边有边权,本来应该是个LCA. 看他数据小,Xjb水过去了...其实也算是LCA吧,一个O(n)的LCA... #include<cstdio> # ...
- 3 Java的基本程序设计结构
本章主要内容: 一个简单的Java应用程序 注释 数据类型 变量 运算符 字符串 输入输出 控制流 大数值 数组 本章主要介绍程序设计的基本概念(如数据类型.分支以及循环)在Jav ...
- vue 中全局filter过滤器的配置及使用
在项目中使用到的经常用到过滤器,比如时间,数据截取等过滤器,如果在每个.vue中都可以复制同一个过滤器,这可以达到目的,但是遇到方法有bug时就需要诸葛修改进入不同的页面修改,这样既费时又费力,优先可 ...
- 【codeforces 768D】Jon and Orbs
[题目链接]:http://codeforces.com/contest/768/problem/D [题意] 你有一个水晶; 它每天都会产生一个球??(球有k种) 然后每种球产生的可能性是相同的-& ...
- [bzoj2743][HEOI2012]采花_树状数组
采花 bzoj-2743 HEOI-2012 题目大意:给定n朵花,每朵花有一个种类,m次询问:一段区间中至少出现两朵花的种类的个数. 注释:$1\le n,m\le10^6$. 想法:这个题超级像H ...