1、Hibernate的概述
1) Hibernate是基于ORM思想的持久层的框架,底层是对jdbc的封装
2) 核心思想:Object Relation Mapping 对象关系映射。
2、Hibernate的入门
1)下载Hibernate的jar包
2)导入Hibernate的必须的jar包(13个包)
3)准备数据库表(R)
4)准备JavaBean对象(O)
5)准备映射文件:*.hbm.xml(M)
6)编写Hibernate的核心配置文件
7)入门程序测试:保存一个客户对象到数据库
3、Hibernate的核心API的介绍
1)Configuration
2)SessionFactory
3)Session
4)Transaction
4、抽取Hibernate的工具类
/** * 工具类 * @author Johnny.Chen * */ public class HibernateUtil { //全局的SessionFactory对象 private static SessionFactory factory;
//静态代码块 static{ Configuration cfg = new Configuration(); cfg.configure();//加载主配置文件 factory = cfg.buildSessionFactory(); }
/** * 打开一个session * @return */ public static Session openSession(){ return factory.openSession(); }
} |
5、完成客户对象的增删改查
session.save(Customer);
session.get(Customer.class,id);
session.update(Customer);
session.delete(Customer);
6、get方法与load方法的区别
get:立即加载
load:延迟加载
1、持久化类
Bean:可重用组件
JavaBean:用java语言写的可重用组件。
实体类:
一般属性都私有化
一般都提供get和set方法
一般都有无参的构造方法
一般实现Serializable接口
持久化类: 实体类 + *.hbm.xml
特点:
一般属性都私有化
一般都提供get和set方法
一般都有无参的构造方法
一般实现Serializable接口
必须还要有一个OID属性
2、对象标识符【OID】
OID由Hibernate来维护
3、hibernate 的主键生成策略
1)自然主键和代理主键
2)主键生成策略
Hibernate中的主键生成策略 native:【推荐】 根据数据库选择相应的主键自增长策略,identity、sequence 这两个中去找 identity: 适用于有数据库自增长能力的策略,想mysql可以用这种 用法:<generator class="identity"></generator>
sequence: 适用序列机制的数据库,例如:Oracle 用法: <generator class="sequence"> <param name="sequence_name">seq_linkman_id</param> </generator>
increment:【了解】 先查询id最大值然后+1,变成主键的值,一般不用这种方式,原因是不适合并发操作 用法:<generator class="increment"></generator>
uuid :【了解】 生成uuid的字符串,适用于字符主键,一般用的也少 用法:<generator class="uuid"></generator>
assigned:【了解】 手动指定id,自己指定,不指定会报错 用法:<generator class="assigned">< |
4、对象的三种状态
靠两个特制:OID、是否被Session管理
1)瞬时态
没有OID,没有被Session管理
2)持久态:有更新数据库的能力
有OID,被Session管理
3)脱管态
有OID,没有被Session管理
/** * Hibenrate中对象的三种状态: * @author Johnny.Chen * */ public class HibernateDemo2 {
@Test //ctrl + 1 public void test(){ Session s = HibernateUtil.openSession(); Transaction tx = s.beginTransaction(); //======================================= LinkMan l = new LinkMan();//瞬时态 l.setLkmName("贝吉塔");
s.save(l);//持久态 System.out.println(l.getLkmId()); //======================================= tx.commit(); s.close();//关闭session System.out.println(l);//脱管态
}
/** * 持久态又更新数据库的能力 */ @Test //ctrl + 1 public void test2(){ Session s = HibernateUtil.openSession(); Transaction tx = s.beginTransaction(); //======================================= LinkMan linkMan = s.get(LinkMan.class, 1L);//持久态 linkMan.setLkmName("悟空"); // s.update(linkMan);//原来我们需要update才更新数据库的,现在我们注释掉这里 //======================================= tx.commit(); s.close();//关闭session
}
} |
问题:为什么能更新数据库?
5、Hibernate中的一级缓存
什么是缓存:就是内存中 的一部分
目的:提高效率
那种数据适用缓存:查得多,改的少的
什么数据不适合:股票走势、用户的账户信息【金额】
Hibernate中有一级缓存和二级缓存:
1)一级缓存是Session中的缓存
2)二级缓存是SessionFactory的缓存【已经不用】
public class HibernateDemo3 { /** * 证明一级缓存的存在 */ @Test //ctrl + 1 public void test2(){ Session s = HibernateUtil.openSession(); Transaction tx = s.beginTransaction(); //======================================= LinkMan linkMan = s.get(LinkMan.class, 1L);//会发起请求:打印sql语句 System.out.println(linkMan); LinkMan linkMan2 = s.get(LinkMan.class, 1L);//不会发起请求:不打印sql语句 System.out.println(linkMan2); System.out.println(linkMan==linkMan2);//true //======================================= tx.commit(); s.close();//关闭session
}
} |
6、Hibernate中的快照机制
快照是Hibernate中的另外一个map,它其实就是数据库的备份
由于有快照机制和一级缓存,所以持久态对象能更新数据库。
7、事务控制
一个线程只有一个Session
事务的控制一般都是业务层
在业务层和持久层中都会用到session对象,这个两个地方用到的对象应该是同一个:
把Session绑定到当前线程上:
1)在hibernate.cfg.xml中配置
<?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> <!-- 主要有三部分信息 1、数据库的链接信息 2、hibernate的配置信息 3、映射文件的位置 --> <!-- 这里面的配置都能从 \\hibernate-release-5.0.7.Final\\project\\etc\\hibernate.properties 中找到 --> <!-- 1、数据库链接信息--> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_day02</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">passw0rd</property> <!-- oracle --> <!-- <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@192.168.44.11:1521:orcl</property> <property name="hibernate.connection.username">scott</property> <property name="hibernate.connection.password">123456</property> -->
<!-- 2、hibernate的配置信息 --> <!-- 配置数据库的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> --> <!-- 配置显示sql语句 --> <property name="hibernate.show_sql">true</property> <!-- 格式化sql语句 --> <property name="hibernate.format_sql">true</property> <!-- 自动维护表结构 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置c3p0链接池 --> <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!-- 把Session绑定到当前线程上 key: hibernate.current_session_context_class value: thread --> <property name="hibernate.current_session_context_class">thread</property>
<!-- 3、映射文件的位置 --> <mapping resource="cn/itcast/entity/LinkMan.hbm.xml"/> </session-factory> </hibernate-configuration> |
2)换一个SessionFactory的方法获取Session
/** * 工具类 * @author Johnny.Chen * */ public class HibernateUtil {
private static SessionFactory factory;
//实例化session工厂 static{ Configuration cfg = new Configuration(); cfg.configure(); factory = cfg.buildSessionFactory(); }
/** * 获取session对象,每次都是新的 * @return */ public static Session openSession(){ return factory.openSession(); }
/** * 获取当前线程的session对象 * @return */ public static Session getCurrentSession(){ return factory.getCurrentSession(); }
}
|