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() { ...
随机推荐
- Windows下Unity安装
安装教程: https://www.paws3d.com/lesson/us-0101/ 问题1: 安装并完成注册后,在网页上能登录,但打开Unity时不能启动成功,一直停留在如下界面 解决方案:断网 ...
- 阅读《JavaScript设计模式》第一章心得
1.明白自己 明白了自己写的代码为什么难懂且臃肿,不方便阅读且效率低.最主要的是为什么整套流程下来只能我一个人写,因为这样的代码根本没有团队力,协同能力差.对js理解的不过透彻. 2.真正的学会对象与 ...
- 洛谷——P3906 Geodetic集合
P3906 Geodetic集合 题目描述 图G是一个无向连通图,没有自环,并且两点之间至多只有一条边.我们定义顶点v,u最短路径就是从v到u经过边最少的路径.所有包含在v-u的最短路径上的顶点被称为 ...
- img标签和background-image的区别和具体使用时机
最近在使用图片过程中,纠结到底使用img标签还是使用background-image属性,翻阅资料和百度后作出下列理解. 简单来说img是内容部分的东西,background-image是修饰性的东西 ...
- <embed> 标签
<embed> 标签定义嵌入的内容,比如插件. <embed quality="high" bgcolor="#FFF" wmode=&quo ...
- MongoDB整库备份与还原以及单个collection备份、恢复
备份前的检查> show dbsMyDB 0.0625GBadmin (empty)bruce 0.0625GBlocal (empty)test 0.0625GB> use MyDBsw ...
- PatentTips - Mechanisms for strong atomicity in a transactional memory system
BACKGROUND Advances in semi-conductor processing and logic design have permitted an increase in the ...
- 洛谷——P1505 苹果摘陶陶
题目背景 根据2005年的Noip普及组第一题衍生出的一题. 但是有一点点的恶搞成分在里面..... 题目描述 话说去年苹果们被陶陶摘下来后都很生气,于是就用最先进的克隆技术把陶陶克隆了好多份> ...
- ZooKeeper的原理(转)
一.ZooKeeper的角色 领导者(Leader),负责进行投票的发起和决议,更新系统状态. 学习者(Learner),包括跟随者(Follower)和观察者(Observer),Follower用 ...
- linux 进程通信之 共享内存
共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法.一个进程向共享内存区域写入了数据,共享这个内存区域的全部进程就能够立马看到当中的内容. 关于共享内存使用的API k ...