1.延迟加载(懒加载)

概念

需要用到该数据的时候才要加载

种类

类的延迟加载

案例

说明:注意:使用的是Load方法

1、  执行22行代码的时候,不发出sql语句,说明类的延迟加载和主键没有关系

2、  执行23行代码的时候,发出sql语句,说明只有在得到具体属性的时候才要发出sql语句。

3、  Session.load方法返回的对象是

而该对象是由javassist的jar包生成的,从代码结构可以看出该代理对象是持久化类的子类。

4、  在Classes.hbm.xml文件中

Lazy的属性默认为true

5、如果把上述的lazy改成false,则类的延迟加载不起作用了,默认为延迟加载。

集合的延迟加载

案例1

值说明

默认情况是true,当遍历集合的时候发出sql语句

Lazy的值为false,当加载classes的时候就把student加载出来了

Extra是更进一步的延迟加载策略,如果求大小、平均数、和等

案例2

案例3

当执行到上述的student.size()的时候,发出了如下的sql语句:

该sql语句只加载了大小,并没有加载具体的数据

Many-to-one的延迟加载

No-proxy 延迟加载   默认值

Proxy是加强版的延迟加载

因为是通过多的一方加载一的一方,所以对效率影响不大,所以一般情况下用默认值即可。

总结

延迟加载是通过什么时候发出sql语句来优化性能的。

 <?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">
<hibernate-mapping>
<class name="com.itheima09.hibernate.domain.Classes" lazy="true">
<id name="cid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
<property name="description" length="100"></property>
<!--
fetch 抓取策略
join 通过做外链接
select 默认值
subselect
-->
<set name="students" cascade="all" fetch="subselect" lazy="extra">
<!--
key代表外键
用来关联classes表和student表,用于在hibernate低层生成sql语句
-->
<key>
<column name="cid"></column>
</key>
<!--
建立类与类之间的关联,用于客户端的编码
-->
<one-to-many class="com.itheima09.hibernate.domain.Student"/>
</set>
</class>
</hibernate-mapping>

Classes.hbm.xml

 package com.itheima09.hibernate.domain;

 import java.io.Serializable;
import java.util.Set; public class Classes implements Serializable{
private Long cid;
private String name;
private String description;
private Set<Student> students;
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}

Classes.java

 <?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">
<hibernate-mapping>
<class name="com.itheima09.hibernate.domain.Student">
<id name="sid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
<property name="description" length="100"></property>
<!--
column 为外键
-->
<many-to-one name="classes" column="cid"
class="com.itheima09.hibernate.domain.Classes" cascade="save-update" lazy="false">
</many-to-one>
</class>
</hibernate-mapping>

Student.hbm.xml

 import java.io.Serializable;

 public class Student implements Serializable{
private Long sid;
private String name;
private String description;
private Classes classes; public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

Student.java

 package com.itheima09.hibernate.lazy;

 import java.util.List;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.itheima09.hibernate.domain.Classes;
import com.itheima09.hibernate.domain.Student;
import com.itheima09.hibernate.utils.HibernateUtils; public class LazyTest extends HibernateUtils{
/**
* 类的延迟加载
*/
@Test
public void testload(){
Session session = sessionFactory.openSession();
Classes classes = (Classes)session.load(Classes.class, 1L);
System.out.println(classes.getCid());//不发出sql
session.close();
System.out.println(classes.getName());//发出sql
} @Test
public void testSet(){
Session session = sessionFactory.openSession();
Classes classes = (Classes)session.get(Classes.class, 1L);
Set<Student> students = classes.getStudents();
for(Student student:students){
System.out.println(student.getName());
}
} @Test
public void testSet_Extra(){
Session session = sessionFactory.openSession();
Classes classes = (Classes)session.get(Classes.class, 1L);
Set<Student> students = classes.getStudents();
System.out.println(students.size());
session.close();
}
}

LazyTest.java

 import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; public class HibernateUtils {
public static SessionFactory sessionFactory;
static{
Configuration configuration = new Configuration();
configuration.configure();
sessionFactory = configuration.buildSessionFactory();
}
}

HibernateUtils.java

抓取策略和延迟加载的结合

研究对象

Set集合

1、  当fetch为join时,lazy失效

2、  当fetch为select时

如果lazy为true/extra

当遍历集合的时候,发出加载集合的sql语句

如果lazy为false

当获取班级的时候,发出加载集合的sql语句

3、  当fetch为subselect时和上面的情况一致。

二级缓存

概念

1、  是sessionFactory级别的缓存

2、  存放的是公有数据:共享数据

3、  二级缓存的生命周期是随着hibernate容器启动就开了,hibernate销毁,结束。

4、  Hibernate本身对二级缓存没有提供实现,是借助第三方插件实现的。

特点

公有数据的特征:

1、  一般情况下保持不变

2、  所有的人都能访问

3、  访问的频率比较高

4、  安全性不是特别高的数据

配置(重点)

1、  在hibernate的配置文件中

2、二级缓存分为类的二级缓存和集合的二级缓存

3、开启classes类的二级缓存

案例1

说明:

当第二次执行session.get方法的时候,并没有发出sql语句

案例2

说明:session.save方法不进二级缓存

案例3

说明:

Update方法不能让一个对象进入到二级缓存中。

案例4

说明:

执行55行代码的时候,把classes表中的所有的对象进入到了二级缓存中

执行59行代码的时候,重新从数据库中查找记录

所以createQuery(hql).list方法能把一个对象放入到二级缓存中,但是不利用二级缓存获取对象。

案例5

在classpath的根目录下放置一个ehcache.xml文件

从上述的配置可以看出,classes对象在内存中存放的数量最多为5个,多余的对象将存在磁盘上。

查找classes表中所有的对象,在内存中放置5个对象,剩余的对象将被存在磁盘上。

案例6

相当于开启了classes类中的set集合的二级缓存

把集合放入到了二级缓存中。

读写策略

Usage

Ready-only

只能把一个对象放入到二级缓存中不能修改

Read-write

能把一个对象放入到二级缓存中,也能修改

 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="e:\\TEMP1"/>
<defaultCache
maxElementsInMemory="12"
eternal="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200"
overflowToDisk="false"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/> <Cache
name="com.itheima09.hibernate.domain.Classes"
maxElementsInMemory="5"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>

ehcache.xml

 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
一个session-factory代表一个数据库
-->
<session-factory>
<!--
链接数据库的用户名
-->
<property name="connection.username">root</property>
<!--
链接数据库的密码
-->
<property name="connection.password">root</property>
<!--
链接数据库的驱动
-->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!--
链接数据库的url
-->
<property name="connection.url">
jdbc:mysql://localhost:3306/itheima09_hibernate
</property>
<!--
方言
告诉hibernate用什么样的数据库
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
validate 加载hibernate时,验证数据库的结构
update 加载hibernate时,检查数据库,如果表不存在,则创建,如果存在,则更新
create 每次加载hiberante,都会创建表
create-drop 每次加载hiberante,创建,卸载hiberante时,销毁
-->
<property name="hbm2ddl.auto">update</property>
<!--
显示sql语句
-->
<property name="show_sql">true</property>
<!--
格式化sql语句
-->
<property name="format_sql">true</property>
<!--
session要从当前线程中产生
-->
<property name="current_session_context_class">thread</property>
<!--
开启二级缓存
-->
<property name="cache.use_second_level_cache">true</property>
<!--
二级缓存的供应商
-->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!--
开启hibernate的统计机制
-->
<property name="hibernate.generate_statistics">true</property>
<!--
加载映射文件
-->
<mapping resource="com/itheima09/hibernate/domain/Classes.hbm.xml" />
<mapping resource="com/itheima09/hibernate/domain/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>

hibernate.cfg.xml

 <?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">
<hibernate-mapping>
<class name="com.itheima09.hibernate.domain.Classes" lazy="true">
<cache usage="read-only"/>
<id name="cid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
<property name="description" length="100"></property>
<!--
fetch 抓取策略
join 通过做外链接
select 默认值
subselect
-->
<set name="students" cascade="all" fetch="select" lazy="true">
<cache usage="read-only"/>
<!--
key代表外键
用来关联classes表和student表,用于在hibernate低层生成sql语句
-->
<key>
<column name="cid"></column>
</key>
<!--
建立类与类之间的关联,用于客户端的编码
-->
<one-to-many class="com.itheima09.hibernate.domain.Student"/>
</set>
</class>
</hibernate-mapping>

Classes.hbm.xml

 <?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">
<hibernate-mapping>
<class name="com.itheima09.hibernate.domain.Student">
<id name="sid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
<property name="description" length="100"></property>
<!--
column 为外键
-->
<many-to-one name="classes" column="cid"
class="com.itheima09.hibernate.domain.Classes" cascade="save-update" lazy="false">
</many-to-one>
</class>
</hibernate-mapping>

Student.hbm.xml

 import java.util.Iterator;
import java.util.List;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import org.omg.CORBA.TRANSACTION_MODE; import com.itheima09.hibernate.domain.Classes;
import com.itheima09.hibernate.domain.Student;
import com.itheima09.hibernate.utils.HibernateUtils; public class SessionFactoryCacheTest extends HibernateUtils{
@Test
public void testGet(){
Session session = sessionFactory.openSession();
Classes classes = (Classes)session.get(Classes.class, 1L);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());//输出的值为1
session.close();//一级缓存已经关闭了
session = sessionFactory.openSession();//该session是一个新的session
classes = (Classes)session.get(Classes.class, 1L);//没有发出sql语句
session.close();
} @Test
public void testSaveClasses(){
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Classes classes = new Classes();
classes.setName("aaa");
session.save(classes);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());//输出为0
transaction.commit();
} @Test
public void testUpdateClasses(){
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Classes classes = new Classes();
classes.setCid(1L);
classes.setName("aa");
session.update(classes);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());//输出为0
transaction.commit();
} @Test
public void testQuery() throws Exception{
Session session = sessionFactory.openSession();
//把classes表中的所有的数据放在了二级缓存中
List<Classes> classesList = session.createQuery("from Classes").list();
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
session.close();
session = sessionFactory.openSession();
List<Classes> list = session.createQuery("from Classes where cid in(1,2,3,4)").list();
for(Classes classes1:list){
Set<Student> students = classes1.getStudents();
for(Student student:students){
System.out.println(student.getName());
}
}
session.close();
Thread.sleep(1000l);
} @Test
public void testOverToDisk() throws Exception{
Session session = sessionFactory.openSession();
//把classes表中的所有的数据放在了二级缓存中
List<Classes> classesList = session.createQuery("from Classes").list();
session.close();
Thread.sleep(1000l);
} @Test
public void testSet(){
Session session = sessionFactory.openSession();
Classes classes = (Classes)session.get(Classes.class, 1L);
Set<Student> students = classes.getStudents();
for(Student student:students){
System.out.println(student.getName());
}
//输出为1
System.out.println(sessionFactory.getStatistics().getCollectionLoadCount());
session.close();
}
}

SessionFactoryCacheTest.java

查询缓存

概念

1、  查询缓存就是数据缓存

能够按照需求加载数据

2、  一级缓存和二级缓存都是对象缓存

在表中的一行有多少个字段,就会加载多少个数据

配置

1、  建立在二级缓存基础之上的

2、  开启查询缓存

案例1

说明:

当执行24行代码的时候,发出sql语句

当执行30行代码的时候,没有发出sql语句,因为利用了查询缓存

案例2

说明:

1、  当两次query.list的时候,都会发出sql语句

2、  原因是两次的查询hql语句不一样。

3、  从这里可以看出查询缓存的命中率比较低

案例3

从list的内存快照中可以看出,list里存放的不是持久化对象,而是name属性的值。

一级缓存和二级缓存存放的是持久化对象,如果集合中存放的不是持久化对象,则不能进入二级缓存中,但是能够进入查询缓存中。

数据缓存和对象缓存

1、  一级缓存和二级缓存是对象缓存,只能缓存持久化对象

2、  对象缓存的特别就是要把数据库表中所有的字段全部查询出来

3、  查询缓存是数据缓存,可以查询一个对象的部分属性,而且可以把部分属性放入到查询缓存中,查询缓存也支持对象。

 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
一个session-factory代表一个数据库
-->
<session-factory>
<!--
链接数据库的用户名
-->
<property name="connection.username">root</property>
<!--
链接数据库的密码
-->
<property name="connection.password">root</property>
<!--
链接数据库的驱动
-->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!--
链接数据库的url
-->
<property name="connection.url">
jdbc:mysql://localhost:3306/itheima09_hibernate
</property>
<!--
方言
告诉hibernate用什么样的数据库
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
validate 加载hibernate时,验证数据库的结构
update 加载hibernate时,检查数据库,如果表不存在,则创建,如果存在,则更新
create 每次加载hiberante,都会创建表
create-drop 每次加载hiberante,创建,卸载hiberante时,销毁
-->
<property name="hbm2ddl.auto">update</property>
<!--
显示sql语句
-->
<property name="show_sql">true</property>
<!--
格式化sql语句
-->
<property name="format_sql">true</property>
<!--
session要从当前线程中产生
-->
<property name="current_session_context_class">thread</property>
<!--
开启二级缓存
-->
<property name="cache.use_second_level_cache">true</property>
<!--
二级缓存的供应商
-->
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!--
开启hibernate的统计机制
-->
<property name="hibernate.generate_statistics">true</property>
<!--
开启查询缓存
-->
<property name="cache.use_query_cache">true</property>
<!--
加载映射文件
-->
<mapping resource="com/itheima09/hibernate/domain/Classes.hbm.xml" />
<mapping resource="com/itheima09/hibernate/domain/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>

hibernate.cfg.xml

 <?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">
<hibernate-mapping>
<class name="com.itheima09.hibernate.domain.Student">
<id name="sid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
<property name="description" length="100"></property>
<!--
column 为外键
-->
<many-to-one name="classes" column="cid"
class="com.itheima09.hibernate.domain.Classes" cascade="save-update" lazy="false">
</many-to-one>
</class>
</hibernate-mapping>

Student.hbm.xml

 <?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">
<hibernate-mapping>
<class name="com.itheima09.hibernate.domain.Classes" lazy="true">
<cache usage="read-only"/>
<id name="cid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
<property name="description" length="100"></property>
<!--
fetch 抓取策略
join 通过做外链接
select 默认值
subselect
-->
<set name="students" cascade="all" fetch="select" lazy="true">
<cache usage="read-only"/>
<!--
key代表外键
用来关联classes表和student表,用于在hibernate低层生成sql语句
-->
<key>
<column name="cid"></column>
</key>
<!--
建立类与类之间的关联,用于客户端的编码
-->
<one-to-many class="com.itheima09.hibernate.domain.Student"/>
</set>
</class>
</hibernate-mapping>

Classes.hbm.xml

 import java.util.Iterator;
import java.util.List;
import java.util.Set; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import org.omg.CORBA.TRANSACTION_MODE; import com.itheima09.hibernate.domain.Classes;
import com.itheima09.hibernate.domain.Student;
import com.itheima09.hibernate.utils.HibernateUtils; public class QueryCache extends HibernateUtils{
@Test
public void testQueryCache(){
Session session = sessionFactory.openSession();
Query query = session.createQuery("from Classes");
//允许把查询出来的集合放入到查询缓存中
query.setCacheable(true);
query.list();
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
session.close();
session = sessionFactory.openSession();
query = session.createQuery("from Classes where cid=1");
//允许从查询缓存中提取数据
query.setCacheable(true);
query.list();
session.close();
} @Test
public void testSessionFactory(){
Session session = sessionFactory.openSession();
Query query = session.createQuery("select name from Classes");
//允许把查询出来的集合放入到查询缓存中
query.setCacheable(true);
query.list();
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
session.close();
session = sessionFactory.openSession();
query = session.createQuery("select name from Classes");
//允许从查询缓存中提取数据
query.setCacheable(true);
query.list();
session.close();
}
}

QueryCache.java

Hql语句

单表

操作

案例1

案例2

说明:List中含有Object[],该数组中有两个元素,第一个元素为Long类型,第二个元素为String类型。

案例3

在持久化类中,必须有两个构造器

案例4

案例5

案例6

案例7

一对多

案例1

案例2

采用了左外链接,但是出来的结构不是很好。

案例3

说明:在join后面跟fetch,就为迫切左外链接。

案例4

案例5

说明:

如果用select,则不能用fetch,如果用fetch,则不能用select。

多对多

案例1

案例2

一对多和多对多

案例1

List<Classes>

Classes<Set<Student>>

Student<Set<Course>>

 import java.util.Map.Entry;
import java.util.Set; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.metadata.ClassMetadata;
import org.junit.Test; import com.itheima09.hibernate.domain.Classes;
import com.itheima09.hibernate.domain.Student;
import com.itheima09.hibernate.manytomany.domain.Course;
import com.itheima09.hibernate.utils.HibernateUtils; public class HqlTest extends HibernateUtils{ @Test
public void testCreateTable(){ } @Test
public void testQueryClasses(){
Session session = sessionFactory.openSession();
List<Classes> classesList = session.createQuery("from Classes").list();
session.close();
} @Test
public void testQueryClasses_Properties(){
Session session = sessionFactory.openSession();
List classesList = session.createQuery("select cid,name from Classes").list();
session.close();
} @Test
public void testQueryClasses_Constructor(){
Session session = sessionFactory.openSession();
List classesList = session.createQuery("select new com.itheima09.hibernate.domain.Classes(cid,name) from Classes").list();
session.close();
} /*
* 查询classes表中所有的数据的个数
*/
@Test
public void testQueryCount(){
Session session = sessionFactory.openSession();
Long count = (Long)session.createQuery("select count(*) from Classes").uniqueResult();
System.out.println(count);
session.close();
} /**
* 带参数的查询
*/
@Test
public void testQuery_Parameter_1(){
Session session = sessionFactory.openSession();
Query query = session.createQuery("from Classes where name=?");
query.setString(0, "aa");
List<Classes> classesList = query.list();
System.out.println(classesList.size());
session.close();
} @Test
public void testQuery_Parameter_2(){
Session session = sessionFactory.openSession();
Query query = session.createQuery("from Classes where name=:name");
query.setString("name", "aa");
List<Classes> classesList = query.list();
System.out.println(classesList.size());
session.close();
} @Test
public void testQuery_Dynamic_Parameter(){
/**
* key代表持久化类中属性的名称
* value代表属性的值
*/
Map<String, String> map = new HashMap<String, String>();
map.put("name","aa");
this.queryDynamic(map, Classes.class);
} private void queryDynamic(Map<String, String> map,Class className){
Session session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
/**
* classes持久化类的元数据
*/
ClassMetadata classMetadata = sessionFactory.getClassMetadata(className);
//得到持久化类的名称
buffer.append("from "+classMetadata.getEntityName());
buffer.append(" where 1=1");
//得到map中所有的key值
Set<String> keys = map.keySet();
//拼接hql语句:查询条件
Iterator<String> iterator = keys.iterator();
for(int i=0;i<keys.size();i++){
String temp = iterator.next();
buffer.append(" and "+temp+"=:"+temp);
}
Query query = session.createQuery(buffer.toString());
/**
* 给所有的查询条件赋值
*/
for(Entry<String, String> entry:map.entrySet()){
query.setString(entry.getKey(), entry.getValue());
}
List<Classes> classesList = query.list();
System.out.println(classesList.size());
session.close();
} /**
* 一对多
*/
/**
* 等值链接
* 内链接
* 左外链接
* 迫切内链接
* 迫切左外链接
*/
@Test
public void testQueryClassesAndStudent_EQ(){
Session session = sessionFactory.openSession();
List list = session.createQuery("from Classes c,Student s where c.cid=s.classes.cid").list();
session.close();
} @Test
public void testQueryClassesAndStudent_LeftJoin(){
Session session = sessionFactory.openSession();
List list = session.createQuery("from Classes c left join c.students s").list();
session.close();
} /**
* 迫切左外链接
*/
@Test
public void testQueryClassesAndStudent_LeftJoin_fetch(){
Session session = sessionFactory.openSession();
List list = session.createQuery("from Classes c left outer join fetch c.students s").list();
session.close();
} /**
* 迫切内连接
*/
@Test
public void testQueryClassesAndStudent_Innerjoin_fetch(){
Session session = sessionFactory.openSession();
List list = session.createQuery("from Classes c inner join fetch c.students s").list();
session.close();
} /**
* 查询classes中的name和student中的name
*/
@Test
public void testQueryClassesPropertyAndStudentProperty(){
Session session = sessionFactory.openSession();
List list = session.createQuery("select new com.itheima09.hibernate.domain.ClassesView(c.name,s.name) " +
" from Classes c inner join c.students s").list();
session.close();
} /**
* 多对多的迫切内连接
*/
@Test
public void testQueryCourseAndStudent_1(){
Session session = sessionFactory.openSession();
List<Course> list = session.createQuery("from Course c inner join fetch c.students s").list();
session.close();
}
@Test
public void testQueryCourseAndStudent_2(){
Session session = sessionFactory.openSession();
List<Student> list = session.createQuery("from Student s inner join fetch s.courses c").list();
session.close();
} /**
* 多对多迫切左外链接
*/
@Test
public void testQueryCourseLeftouterjoin_fetch(){
Session session = sessionFactory.openSession();
List<Course> list = session.createQuery("from Course c left outer join fetch c.students s").list();
session.close();
} /**
* 一对多和多对多的结合
*
* 如果用迫切内链接做,最好查找核心表
*/
/**
* 内连接
*/
@Test
public void testQueryManyToManyToOne_1(){
Session session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append("from Student s inner join fetch s.courses c inner join fetch s.classes cc");
List list = session.createQuery(buffer.toString()).list();
session.close();
} @Test
public void testQueryManyToManyToOne_2(){
Session session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
//from Course c inner join fetch c.students s inner join fetch s.classes cc
buffer.append("from Classes c inner join fetch c.students s inner join fetch s.courses cc");
List list = session.createQuery(buffer.toString()).list();
session.close();
} @Test
public void testList(){
Session session = sessionFactory.openSession();
List list = session.createQuery("select new list(cid,name) from Classes").list();
session.close();
} @Test
public void Map(){
Session session = sessionFactory.openSession();
/**
* n:ads
c:1
n:adsf
c:2
*/
//别名为map中的key值,value值为属性的值
List<Map<String, Object>> list = session.createQuery("select new map(cid as c,name as n) from Classes").list();
for(Map<String, Object> map:list){
for(Entry<String, Object> entry:map.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
session.close();
} /**
* 分页
*/
@Test
public void testDispage(){
Session session = sessionFactory.openSession();
Query query = session.createQuery("from Classes");
query.setFirstResult(1);//当前页的第一行在集合中的位置
query.setMaxResults(2);//当前页有多少行
List<com.itheima09.hibernate.onetomanytomany.Classes> classesList = query.list();
for(com.itheima09.hibernate.onetomanytomany.Classes classes:classesList){
System.out.println(classes.getCid());
}
session.close();
}
}

HqlTest.java

Hibernate内部的list

Hibernate内部的map

分页

原生态的sql查询

接口回调

https://blog.csdn.net/liangxw1/article/details/50701205

参考这里的文章

 public List findByPage(final String hql,
final int offset, final int pageSize)
{
//通过一个HibernateCallback对象来执行查询
List list = getHibernateTemplate()
.executeFind(new HibernateCallback()
{
//实现HibernateCallback接口必须实现的方法
public Object doInHibernate(Session session)
throws HibernateException, SQLException
{
//执行Hibernate分页查询
List result = session.createQuery(hql)
.setFirstResult(offset)
.setMaxResults(pageSize)
.list();
return result;
}
});
return list;
}

第5行:获取Hibernatetemplate对象

第6行:执行Hibernatetemplate的 executeFind ()方法,并且传入HibernateCallback接口的实例化对象(匿名内部类)

这里的Hibernatetemplate对象 就类似  参考文章  的B的对象;而Hibernatetemplate对象中有一个方法是接收HibernateCallback接口的实例化对象,所以直接调用HibernateCallback接口的实例化对象的方法

interface AA{
public String method1();
public int method2();
} public class InterFaceCallBack {
public static void main(String[] args){ BB bb=new BB();
bb.Method(new AA() {
@Override
public String method1() {
return "I am AAImpl Method1";
}
@Override
public int method2() {
return 1+1;
}
}); }
}
class BB{ public int Method(AA aa){ String a1=aa.method1();
System.out.println("a1="+a1);
int a2=aa.method2();
System.out.println("a2="+a2);
return 0;
}
}

Hibernate笔记二的更多相关文章

  1. hibernate笔记(二)

    目标: 关联映射(hibernate映射) 1. 集合映射 2. 一对多与多对一映射 (重点) 3. 多对多映射 4. inverse/lazy/cascade 1. 集合映射 开发流程: 需求分析/ ...

  2. JDBC学习笔记二

    JDBC学习笔记二 4.execute()方法执行SQL语句 execute几乎可以执行任何SQL语句,当execute执行过SQL语句之后会返回一个布尔类型的值,代表是否返回了ResultSet对象 ...

  3. Hibernate笔记一

    背景 jdbc的优缺点 A:直接操作底层,提供了简单,便捷的访问数据库方法,跨平台比较强,灵活,可以写很多赋值的SQL语句:是最底层的数据库操作,所以效率比较高,Sql语句可以自己选择写,采用效率最高 ...

  4. 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  5. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  6. 框架Hibernate笔记系列 基础Session

    标题:框架Hibernate笔记 资料地址: 1. www.icoolxue.com 孔浩 1.背景简介 Hibenate是JBoss公司的产品.它是数据持久化的框架.Usually,我们使用JDBC ...

  7. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  8. Python 学习笔记二

    笔记二 :print 以及基本文件操作 笔记一已取消置顶链接地址 http://www.cnblogs.com/dzzy/p/5140899.html 暑假只是快速过了一遍python ,现在起开始仔 ...

  9. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

随机推荐

  1. shell批量创建数据表的一个方法

    #!/bin/bash #批量新建数据表 #删除`符号,具体原因我也没搞懂 for i in {1..30};do mysql 地址 -u账号 -p密码 -e "use 库名;CREATE ...

  2. 【原】linux增加开机自启动脚本

    在rc.local脚本中添加开机自启动程序

  3. 素问 - 信贷和GDP

    摘自<小韭的学习圈> Q:近期看到2019年金融统计数据,全年人民币贷款增加16.81万亿元,同比多增6439亿元.这里有个问题我储备好久了,没有高人指点俺.请问2019年全年GDP近10 ...

  4. Go非缓冲/缓冲/双向/单向通道

    1. 非缓冲和缓冲 package main import ( "fmt" "strconv" ) func main() { /* 非缓冲通道:make(ch ...

  5. 委托与事件--delegate&&event

    委托 访问修饰符 delegate 返回值 委托名(参数); public delegate void NoReturnNoPara(); public void NoReturnNoParaMeth ...

  6. html - html5 audio 音乐自动播放,循环播放等

    转自:http://blog.csdn.net/u012246458/article/details/50618759 audio播放音乐 <audio id="audio" ...

  7. Linux上临时路由、永久路由配置

    Linux下查看路由条目 查看路由表命令 route -n 示例 [root@cobbler_vm ~]# route -n Kernel IP routing table Destination G ...

  8. 连通数[JSOI2010]-洛谷T4306

    咕咕咕 tarjan+拓排应该是正解吧 然而我上去就打了个tarjan和dijkstra (由于我抄题解抄多了,代码能力极差,于是我就gg了) 题解中有大佬直接用dfs过了8个点,再吸口氧就AC了 ( ...

  9. 吴裕雄 python 机器学习——数据预处理嵌入式特征选择

    import numpy as np import matplotlib.pyplot as plt from sklearn.svm import LinearSVC from sklearn.li ...

  10. mybatis 源码分析--日志分析

    1. MyBatis 没有提供日志实现,需要接入第三方的日志组件,但是第三方的日志组件都各自的Log级别,而不相同 实现方式:适配器模式   Slf4jImpl 2. 自动扫描日志实现,并且第三方日志 ...