第一.概念
Shift+第一个+最后一个=全部选中jar包
1.数据库和tomcat服务器不在一台电脑上,一级缓存是保存在服务器的内存中,二级缓存保存在服务器的硬盘上(因此我们可以设置溢出时保存到哪个硬盘),二级缓存也是在tomcat服务器上的,因此减少了与数据库的交互次数(因为保存到服务器的话不用跟其他的电脑进行交互)。
2.hibernate的一级缓存是session级别的缓存。sessionFactory级别的缓存是二级缓存。
3.二级缓存要指定hibernate的二级缓存插件(插件是个现成的程序,需要我们指定用这个插件),需要开启
4.hibernate主配置文件中的设置都是给某个类进行赋值,是个sessionFactory类(session工厂)中的属性赋值。sessionFactory是个接口,实现类是sessionFactoryimpl
资源文件Properties 继承了hashtable,因此Properties 是个键值对。
来自JDK1.6说明文档:Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
5.在properties文件中#表示注释
6,使用二级缓存的步骤:
---1.开启二级缓存
---2.指定缓存插件(功能是把内容写到磁盘中,当开启二级缓存之后就该想到我们将来要把内容存到哪里)
--3.写配置文件说明二级缓存的大小,在src下配置缓存文件
--4.指定需要缓存的对象和缓存策略
7.statics是对二级缓存进行统计,输出来的内容create(可瑞的)是该对象的属性。在主配置文件中配置。
他是查看二级缓存或查询缓存区域的内容,但是如果想查看二级缓存,需要在主配置文件中进行配置。查看二级缓存是SessionFactory类中的的方法Statistics ss=HibernateSessionFactory.getSessionFactory().getStatistics();
其实不难理解为什么是SessionFactory类中的方法,因为SessionFactory表示的是二级缓存。而session表示一级缓存。
8.适合放入二级缓存中的数据:1.不经常做修改的数据,2.安全性不高的数据。
9.先查询已经缓存,一级缓存中如果没有在查询二级缓存,如果二级缓存中也没有,就查询数据库。
10.session(一级)和sesionFactroy(二级)的线程安全问题
session是线程不安全的:ThreadLocal是给每个来的线程都给他一个副本,用这种方式来解决多线程问题。sessionFactroy是线程安全的。
注意:在hibernate主配置文件中,二级缓存的配置要放到映射文件配置的前面
11.session和sessionFactory都有evict方法,该方法的参数是个对象或者类,表示让该对象与一级缓存或者二级缓存断开联系:sessionFactory.evict(Cat.class, catId); sessionFactory.evict(Cat.class);
/**
关于二级缓存:二级缓存就是给大家共享的,每个线程都能够使用,因此就出现了多线程并发的现象。
第一步(1):在hibernate主配置文件中写:
<!--设置二级缓存 -->
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!--默认是使用二级缓存的,但是可以设置关闭 -->
<property name="hibernate.cache.use_second_level_cache">
false
</property>
<!-- 使用查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
第一步(2):在映射文件中写二级缓存的并发策略。usage表示并发策略。
<cache usage="read-write"/>
第二步:指定二级缓存的插件(有好多种插件都能实现二级缓存,其实就是把某个xml文件放到src目录下(放在src下就会随着项目的启动而启动二级缓存)。现在要指定插件,在老师给的hibernate-3.2下的ect目录下)
第三步:配置上面的插件(可以只配置缓存的大小)
----------------------------------
注意:现在我们只导入了hibernate的jar包,在配置好二级缓存之后运行的时候报错Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory。
这是找不到这个jar包(也就是说明二级缓存要使用这个jar包),因此我们可以找一个这样的jar包放到项目中,也可以直接把struts框架的jar包生成,因为struts2框架的jar包就有这个jar包
并发策略有好多种,看张老师的,可是我们常用的只有两种只读模式和读写模式,当我们设置读写模式的时候就不能设置事务的隔离级别了,因为这两个是互相矛盾的。
**/
11.主键生成策略:
increment(k瑞特门):自动增长因用于mysql,
identity自增用于mysql,server,db2,
sequence是oracle中的自增
native(内t我):根据数据库自动匹配(相当于综合各种数据库),由数据库底层自己决定。
assigned:程序员自己指定
uuid:是个算法
12.hql的多表关联(多表关联有三种,一种是hql的多表关联,一个createCriteria(也就是QBC查询),一个是本地sql查询)
inner默认是内连接,inner join。左是left join
内左外右外连接查询:查询结果是个object类型的数组,因为这个查询结果中包含两个或者两个以上的表(类),因此不能是具体类型,只能是object类型。因为包含多个表,表中又有属性,因此每个表都是一个数组。
迫切查询:返回值是个对象
13.createCriteria多表关联
两个参数,第一个是类名,第二个是别名,单词是alias
两个参数,第一个参数表示地址,第二个参数是数据类型(在Criteria里面的常量)
14,hibernate的源码在hibernate-3.2这个老师给的文件中的src中,如果找二级缓存的资源文件在这个文件夹中的ect中。
一级缓存session的声明周期是与数据库的一次交互过程,当我们把session放到action层的时候,它的声明周期是一次请求和响应的过程(可能多次与数据库交互)
而二级缓存是:不但在一级缓存的map结构中存放(),还在二级缓存中存放(在二级缓存存放的内容是共享的)。
一级缓存的作用域相当于是hibernate主配置文件中的map标签里,而二级缓存的作用域相当于是整个hibernate主配置文件。
------------------
书17章:三种检索(查询)方式
1.hql语句检索:session.createQuery(hql);
2.QBC检索:session.createCriteria(XXX.class)
3.本地SQL检索:session.createSQLQuery(sql)
第二:代码
1、hibernate主配置文件
<?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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<!-- 注意:hibernatefactory里面配置的所有标签其实就是hibernatefactory接口中的属性,该接口的实现类是hibernatefactoryImpl,下面的所有配置 都是该实现类中的属性。 -->
<session-factory>
<property name="dialect">
org.hibernate.dialect.Oracle9Dialect
</property>
<property name="connection.url">
jdbc:oracle:thin:@localhost:1521:ORCL
</property>
<property name="connection.username">chu1</property>
<property name="connection.password">1234</property>
<property name="connection.driver_class">
oracle.jdbc.OracleDriver
</property>
<property name="myeclipse.connection.profile">chu</property>
<property name="format_sql">true</property>
<property name="show_sql">true</property>
<!--设置二级缓存,指定缓存插件,是个类,是个jar包里面的类 -->
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!--默认是使用二级缓存的,但是可以设置关闭。打开二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">
true
</property>
<!-- 使用查询缓存,查询缓存有利于提高查询速度,也是个jar包里的类 -->
<property name="hibernate.cache.use_query_cache">true</property>
<!--表示允许查看二级缓存里面放的数据-->
<property name="generate_statistics">true</property>
<mapping resource="com/model/pojo/Student6.hbm.xml" />
</session-factory>
</hibernate-configuration>
2.basedao公共类
package com.comm;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class BaseDao
{
public static SessionFactory sf;
static
{
Configuration cfg=new Configuration().configure("/hibernate.cfg.xml");
sf = cfg.buildSessionFactory();
System.out.println(sf);
}
public Session getSession()
{
return sf.openSession();
}
public Serializable save(Object obj)
{
Transaction tr=null;
Session session=null;
Serializable ser=null;
try
{
session = this.getSession();
tr= session.beginTransaction();
ser=session.save(obj);
tr.commit();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
session.close();
}
return ser;
}
public static void main(String[] args) {
new BaseDao();
}
}
3.dao层
package com.model.dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.stat.Statistics;
import com.comm.BaseDao;
import com.comm.HibernateSessionFactory;
import com.model.pojo.Student6;
public class StudentDao extends BaseDao{
//一级缓存。此时不开启二级缓存。在主配置文件中设置成false
public void search(){
Session session=super.getSession();
Student6 stu=(Student6) session.get(Student6.class, 168);
System.out.println(stu.getSname()+"\t"+stu.getSsex());
//session.evict(stu);//将当前对象与session断开
//session.clear();//清空session
session.close();//关闭session
Session session2=super.getSession();
System.out.println("session是打开的?"+session.isOpen());
//System.out.println("当前session"+session.hashCode());
System.out.println(stu.getSname()+"\t"+stu.getSsex());//无论什么操作,这里都会输出值,因为这里跟缓存无关,由于限制存在一个完整的stu对象,所以理所当然的能够输出他的属性值。
}
//自己的session关闭之后其他session来访问相同的内容(id相同的学生),由于第一个session把查询结果放在了二级缓存中了,因此第二个session查询相同的学生的时候不会访问数据库而是直接去二级缓存中取,因此控制台输出一条sql语句
public void search2(){
Session session=HibernateSessionFactory.getSession();
Student6 stu=(Student6) session.get(Student6.class, 168);
System.out.println(stu.getSname()+"\t"+stu.getSsex());
//session.clear();//清空一级缓存
session.close();
Session session2=HibernateSessionFactory.getSession();
Student6 stu2=(Student6) session2.get(Student6.class, 168);//会查看二级缓存中有没有,当我们开启二级缓存的时候,使用二级缓存,因此不会再输出select语句了
System.out.println(stu2.getSname()+"\t"+stu2.getSsex());//
Statistics ss=HibernateSessionFactory.getSessionFactory().getStatistics();//getSessionFactory()是获得sesionFactory也就是获得二级缓存,getStatistics是获得二级缓存中的统计信息
System.out.println(ss);
}
public static void main(String[] args) {
StudentDao sdao = new StudentDao();
//sdao.search();
sdao.search2();
//sdao.search3();
}
}
第三:多表连接查询,对象查询的代码
1.员工表的映射文件
<?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 package="com.model.pojo">
<class name="Emp" table="HIB_EMP" schema="CHU1">
<id name="eid" type="int">
<column name="EID" precision="10" scale="0" />
<generator class="assigned" />
</id>
<many-to-one name="dept" class="Dept" fetch="select">
<column name="DID" precision="10" scale="0" />
</many-to-one>
<property name="ename" type="string">
<column name="ENAME" length="40" />
</property>
<property name="job" type="string">
<column name="JOB" length="40" />
</property>
</class>
</hibernate-mapping>
2.部门表的映射文件
<?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 package="com.model.pojo">
<class name="Dept" table="HIB_DEPT" schema="CHU1">
<id name="did" type="int">
<column name="DID" precision="10" scale="0" />
<generator class="assigned" />
</id>
<property name="dname" type="string">
<column name="DNAME" length="40" />
</property>
<set name="emps" inverse="true">
<key>
<column name="DID" precision="10" scale="0" />
</key>
<one-to-many class="Emp" />
</set>
</class>
</hibernate-mapping>
3.连接查询和本地查询
package com.model.dao;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Query;
import org.hibernate.Session;
import com.comm.HibernateSessionFactory;
import com.model.pojo.Dept;
import com.model.pojo.Emp;
public class DeptDao {
public static void main(String[] args) {
DeptDao ddao=new DeptDao();
//ddao.selDept();
//ddao.selDept1();
//ddao.selDept2();
ddao.selDept3();
}
//通过这个方法我们发现内连接,左连接、右连接的查询结果是个object类型的数组
public void selDept(){
Session session=HibernateSessionFactory.getSession();
String hql="from Dept as d inner join d.emps";
Query query = session.createQuery(hql);
List list = query.list();
for(int x=0;x<list.size();x++){
System.out.print(list.get(x)+" ");//这个得到的是个数组,也就是说集合里面放的是数组。由此得出结论
System.out.println();
}
}
//通过这个方法我们知道,数组中的每个元素都表示多表关联中的每个表,也就是说有几个表数组中就会有几个元素
public void selDept1(){
Session session=HibernateSessionFactory.getSession();
String hql="from Dept as d inner join d.emps";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();//首先查询结果有很多,是个list集合(query.list的返回值就是个list)。每个查询结果又是个数组,数组中的每个元素表示一个表(由于内连接,左右连接都是两个或者两个以上的表在参与)
for(Object[] d:list){
System.out.println(d[0].getClass().getName()+"\t"+d[1].getClass().getName());
}
}
//迫切左外连接。集合的返回值得到的是对象类型的list集合
public void selDept2(){
Session session=HibernateSessionFactory.getSession();
String hql="from Dept as d left join fetch d.emps";
Query query = session.createQuery(hql);
List<Dept> list=query.list();
for(Dept d:list){
System.out.println(d.getDname());
Set<Emp> set=d.getEmps();
Iterator<Emp> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next().getEname());
}
}
}
//本地sql查询
public void selDept3(){
Session session=HibernateSessionFactory.getSession();
String sql="select * from dept";//创建sql语句
Query query = session.createSQLQuery(sql).addEntity(Dept.class);//addEntity是把sql变成hql,把表名变成类名
System.out.println(query);
int a=query.executeUpdate();
System.out.println(a);
}
}
4.对象查询
package com.model.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import com.comm.HibernateSessionFactory;
import com.model.pojo.Emp;
public class EmpDao {
public static void main(String[] args) {
EmpDao edao=new EmpDao();
edao.selEmp();
}
//QBC查询,也叫对象查询
public void selEmp(){
Session session=HibernateSessionFactory.getSession();
//第一个参数是个路径,第二个参数是别名(String associationPath, String alias)
Criteria c = session.createCriteria(Emp.class, "e");//创建QBC查询语句,并给则个对象起个别名e
//第一个参数是路径,第二个参数是连接类型(例如左外连接,内连接等)(String associationPath, int joinType)
//连接类型中的1是Criteria接口的实现类CriteriaSpecification(查看源代码)中的一个常量的值,
c.createCriteria("e.dept",1);//左连接
c.add(Restrictions.eq("e.ename","喜洋洋"));
List<Emp> elist = c.list();
for(Emp e:elist){
System.out.println(e.getEname());
System.out.println(e.getDept().getDname());
}
}
}
相关推荐
在本篇“Spring Hibernate 事务管理学习笔记(二)”中,我们将深入探讨Spring框架与Hibernate集成时如何实现高效、安全的事务管理。这是一篇关于源码分析和技术工具使用的文章,适合对Java开发和数据库操作有基础...
例如,`@Entity`注解标记一个类为实体,`@Table`注解指定了实体对应的数据库表名,`@Id`注解标识实体的主键字段,`@GeneratedValue`注解指示主键生成策略,而`@Column`注解则用于指定字段与表列的对应关系。...
Hibernate支持二级缓存,包括一级缓存(Session级别的缓存)和二级缓存(SessionFactory级别的缓存)。如使用EhCache作为二级缓存,可以显著提升系统性能。 9. 异构数据库支持: Hibernate具有强大的数据库无关性...
6.缓存机制:理解Hibernate的缓存层次,包括一级缓存(Session级别的缓存)和二级缓存(SessionFactory级别的缓存),以及第三方缓存集成,如EhCache和Redis。 7. 性能优化:学习如何提升Hibernate应用的性能,包括...
- @Id:标识类中的主键字段,可以配合@GeneratedValue指定主键生成策略。 - @GeneratedValue:定义主键的自增策略,如IDENTITY(数据库自动增长)、SEQUENCE(序列)等。 - @Column:定义属性对应表中的列,可以...
本文将针对Hibernate中的几个重要概念进行详细讲解,包括主键生成策略、get()与load()的区别以及二级缓存的使用。 首先,探讨的是Hibernate中的主键生成策略。在Hibernate中,主键的生成主要有三种方式:uuid、...
- @Id:定义主键字段,通常与@IdGenerator配合使用定义主键生成策略。 4. Hibernate的Session操作: - save()和saveOrUpdate():将对象持久化到数据库,如果对象尚未存在,会创建新记录。 - update():更新已...
总的来说,Hibernate第一天的学习涵盖了基本的环境配置、对象关系映射、主键生成策略、`SessionFactory`和`Session`的使用,以及事务管理和缓存机制。理解并掌握这些基础概念,是进一步深入学习Hibernate和进行实际...
可能会返回代理对象,并优先检查一级和二级缓存。 Hibernate的加载过程包括: - **一级缓存检查**:Session内部的缓存管理。 - **二级缓存检查**:SessionFactory级别的缓存,多个Session共享。 - **数据库查询...
2. **映射配置**:详细讲解了XML配置文件(hibernate.cfg.xml和.hbm.xml)和注解方式,如何定义实体类和数据库表之间的映射关系,包括主键生成策略、属性类型映射、关联映射(一对一、一对多、多对多)等。...
3. **对象关系映射(ORM)**:讲解Hibernate的核心——ORM技术,如何通过注解或XML配置文件将Java类与数据库表进行映射,包括实体类的定义、主键生成策略、属性映射等。 4. **Session和Transaction**:深入理解...
-缓存机制:理解一级缓存和二级缓存,以及查询缓存的工作原理。 3. **关联映射**: - 一对一、一对多、多对一、多对多关联映射的配置和实现,包括集合类型如List、Set、Map的使用。 -懒加载和立即加载策略,以及...
6.缓存机制:讲解Hibernate的缓存策略,包括一级缓存和二级缓存,以及第三方缓存解决方案如 EhCache 和 Infinispan 的集成。 7.性能优化:分享提高Hibernate应用性能的技巧,如延迟加载、批处理、预加载等。 通过...
Hibernate提供了一级缓存(Session级别)和二级缓存(SessionFactory级别)。一级缓存默认开启,二级缓存可配置插件如EhCache实现,提高数据访问效率。 八、延迟加载(Lazy Loading) Hibernate支持懒加载策略,...
4. 缓存机制:Hibernate包含一级缓存(Session级缓存)和二级缓存(SessionFactory级缓存),以及查询缓存,有效提高数据访问速度。 四、核心类详解 1. EntityPersister:负责实体的持久化操作,包括保存、更新、...
4. 映射文件(.hbm.xml或注解):定义对象和数据库表之间的映射关系,包括字段对应、主键生成策略、关联关系等。 5. Query与Criteria API:提供查询对象和数据的方法,包括HQL(Hibernate Query Language)和JPQL...
- 缓存机制:提供了第一级缓存和第二级缓存,提高性能。 - 支持多种数据库:通过配置文件可以轻松切换不同的数据库平台。 - 自动SQL生成:根据对象模型自动生成SQL,减少手动编写SQL的工作量。 5. 使用流程: -...
- `@Table`注解指定表名,`@Id`定义主键,`@GeneratedValue`管理主键生成策略。 - `@Column`定义字段与列的映射,`@ManyToOne`, `@OneToOne`, `@OneToMany`, `@ManyToMany`处理关联关系。 4. Session与...
Hibernate 是一个强大的 Java 对象关系映射(ORM)框架,它极大地简化了数据库操作,让...同时,了解如何配置和管理二级缓存,以及如何根据不同的数据库环境选择合适的主键生成策略,也是提高应用程序性能的关键。
- **映射文件**(`.hbm.xml`):定义对象与表之间的映射规则,如字段对应、主键生成策略等。 ### 6. 常见操作 - **查询**:使用Session的`load()`或`get()`方法获取对象,`createCriteria()`或`createQuery()`构建...