Java框架篇-Heibernate(一)
一 : 简述
Hibernate
框架是当今主流的Java持久层框架之一,简单易学,灵活,扩展性强,能够大大地简化程序的代码量,提高工作效率,受到广大开发人员喜爱.Heibernate是一个快放源代码的ORM(Object Relational Mapping,对象关系映射)
它对JDBC进行了轻量级的对象封装,使得开发人员可以使用面向对象的编程思维来操作数据库
二 :解压包结构
结构- documentation : 存放Heibernate的相关文档,包括参考文档的API文档
-
lib : 存放Hibernate编译和运行所依赖的JAR包,其中required子目录包含了运行Hibernate项目必须的JAR包
lib - project文件夹 : 存放Hibernate各种相关的源代码
三 : 快速入门
( 1 ) : 在数据库中创建表
( 2 ) : 创建对应实体类Customer
( 3 )创建映射文件
实体类Customer目前不具备持久化操作的能力,而Hibernate需要知道实体类Customer映射到数据库中的哪个表,以及类中的哪个属性对应数据库表中的哪个字段,这些都需要在映射文件中配置.
配置文件可以任意命名,尽量统一命名规范(类名.hbm.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 建立类与表的映射 -->
<class name="com.TianTian.java.Customer" table="cst_customer">
<!-- 建立类中的属性与表中的主键对应 -->
<id name="cust_id" column="cust_id" >
<generator class="native"/>
</id>
<!-- 建立类中的普通的属性和表的字段的对应 -->
<property name="cust_name" column="cust_name" length="32" />
<property name="cust_source" column="cust_source" length="32"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
</class>
</hibernate-mapping>
( 4 )创建核心配置文件
在src下创建一个名为heiberinate.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>
<property name="hibernate.connection.driver_class com.mysql.jdbc.Driver">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.driver_class com.mysql.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.driver_class com.mysql.username">root</property>
<property name="hibernate.connection.driver_class com.mysql.password">root</property>
<!-- 配置Hbernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="com/TianTian/test/Customer.hbm.xml">
</session-factory>
</hibernate-configuration>
( 5 )编写测试代码
注意
: 可能会报错
JAXB API是java EE 的API,因此在java SE 9.0 中不再包含这个 Jar 包。
java 9
中引入了模块的概念,默认情况下,Java SE中将不再包含java EE 的Jar包,而在 java 6/7 / 8 时关于这个API 都是捆绑在一起的
java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
解决方案 : https://blog.csdn.net/hadues/article/details/79188793
public void demo1(){
// 1.加载Hibernate的核心配置文件
Configuration configuration = new Configuration().configure();
// 手动加载映射
// configuration.addResource("com/itheima/hibernate/demo1/Customer.hbm.xml");
// 2.创建一个SessionFactory对象:类似于JDBC中连接池
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.通过SessionFactory获取到Session对象:类似于JDBC中Connection
Session session = sessionFactory.openSession();
// 4.手动开启事务:
Transaction transaction = session.beginTransaction();
// 5.编写代码
Customer customer = new Customer();
customer.setCust_name("雪芙");
session.save(customer);
// 6.事务提交
transaction.commit();
// 7.资源释放
session.close();
sessionFactory.close();
四 : 配置详解
( 1 ) : XML提示配置
在没有网络的情况下,在映射文件和配置文件书写的时候,会没有dtd提示,所以需要配置提示
① : 搜索XMLCatalog
搜索② : 选中自定义,然后添加
选中添加( 2 ) 映射的配置
-
[class标签的配置]
标签用来建立类与表的关系
<class name="com.TianTian.java.Customer" table="cst_customer" catalog="hibernate">
属性 :
name
: 类的全路径
table
:表名(类名与表名一致,tavble可以省略)
catalog
: 数据库名,可以不写
-
[id标签的配置]
<id name="cust_id" column="cust_id" >
标签用来建立类中的属性与表中的主键的对应关系
属性 :
name
: 类种的属性名
column
: 表中的字段名 (类中的属性名和表中的字段名如果一致,column可以省略)
length
: 长度
type
: 类型
-
[property标签的配置]
标签用来建立表中的普通属性与表的字段对应关系
属性 :
name
: 类中的属性名
column
: 表中的字段名
length
: 长度
not-null
:设置非空
unique
: 设置唯一
( 3 )Hibernate的核心配置
- 一种方式 : 属性文件的方式(hibernate.properties)
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.show_sql=true
...
- 二种方式 : xml文件方式(hibernate.cfg.xml)
XML中进行核心配置
- 连接数据库的基本参数
驱动类
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
url路径
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
用户名
<property name="hibernate.connection.username">root</property>
密码
<property name="hibernate.connection.password">root</property>
- 方言配置
根据方言生成对应的SQL
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- 可选配置
<!-- 可选配置================ -->
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
自动创建表有几个选项
①none : 不使用hibernate的自动建表
②create : 如果数据库中已经有表,删除原有表,重新创建,如果没有表,则新建(测试)
③create-drop:如果数据库中已经有表,删除原有表.执行操作,删除这个表.如果没有表,新建一个表,使用完了删除表(测试)
④updata : 如果数据库中有表,使用原有表,如果没有表,创建新表(更新表结构)
⑤validate : 如果没有表,不会创建表,只会使用数据库中原有的表(校验映射和表结构,不会更新表结构)
- 映射文件的引入
<mapping resource="com/TianTian/java/Customer.hbm.xml"/>
五 : 常用API
( 1 ) Configuration:Hibernate的配置对象
Configuration 类的作用是对Hibernate进行配置,以及对它进行启动,在Hibernate的启动过程中,Configuration类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象,虽然Configurationzai Hibernate扮演者很小的角色,但它是启动hibernate时所遇到的第一个对象
下面这种创建方式会去src下读取hibernate.cfg.xml配置文件
Configuration configuration = new Configuration().configure();
- 手动加载映射文件
configuration.addResource("com/itheima/hibernate/demo1/Customer.hbm.xml");
( 2 )SessionFactory:Session工厂
SessionFactory 接口负责Hibernate的初始化和建立Session对象,它在Hibernate中起到一个缓冲区的作用,Hibernate可以将自动生成的SQL语句,映射数据,以及某些可重复利用的数据放在这个缓冲区中,同时它还保存了对数据库配置的所有映射关系,维护了当前的二级缓存.
是线程安全的对象,一个项目创建一个对象即可
SessionFactory sessionFactory = configuration.buildSessionFactory();
-
加载log4j打印日志
直接把log4jproperties放入scr
下面 -
log4j文件配置
stdout
: 向控制台输出
file
: 向文件输出
log4j.rootLogger=warn, stdout,file
指定文件日志文件输出位置
log4j.appender.file.File=hibernate.log
设置trace所有信息都会显示,设置debug 显示 error,warn,debug,以此类推
级别 : error
,warn
,debug
,trace
(堆栈信息)
- 配置连接池
SessionFactory内部维持了一个连接池,如果我们需要使用第三方连接池如.C3P0,那么需要我们手动配置
用C3P0需要引入C3P0的jar包
<!-- 配置C3P0连接池 -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
- 抽取工具类
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg =new Configuration();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
}
测试工具类
public void demo2() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 5.编写代码
Customer customer = new Customer();
customer.setCust_name("娜娜");
Serializable id = session.save(customer);
System.out.println(id);
// 6.事务提交
transaction.commit();
// 7.资源释放
session.close();
}
( 3 )Session:类似Connection对象是连接对象
Session接口负责执行被持久化对象的CRUD操作,Session是应用程序与数据库之间交互操作的一个单线程对象,是Hibernate运作的中心,它的主要功能是为持久化对象提供创建,读取和删除的能力,所有持久化对象必须在session管理下才能进行持久化操作
总体来说就是不是线程安全的,与数据库交互的桥梁
- 保存方法
Serializable id = save(Object obj);
- 查询方法(单个)
T get(Class c,Serializable id);
T load(Class c,Serializable id);
区别 :
get方法
* * 采用的是立即加载,执行到这行代码的时候,就会马上发送SQL语句去查询。
* * 查询后返回是真实对象本身。
* * 查询一个找不到的对象的时候,返回null
load方法
* * 采用的是延迟加载(lazy懒加载),执行到这行代码的时候,不会发送SQL语句,当真正使用这个对象(使用这个对象,或者除了这个对象的id属性的其他属性)的时候才会发送SQL语句。
* * 查询后返回的是代理对象。javassist-3.18.1-GA.jar 利用javassist技术产生的代理。
* * 查询一个找不到的对象的时候,返回ObjectNotFoundException
Customer customer = session.load(Customer.class, 200l);
System.out.println(customer);
- 修改方法
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 直接创建对象,进行修改
/*Customer customer = new Customer();
customer.setCust_id(1l);
customer.setCust_name("王聪");
session.update(customer);*/
// 先查询,再修改(推荐)
* 不会破坏其他字段
Customer customer = session.get(Customer.class, 1l);
customer.setCust_name("美娜");
session.update(customer);
tx.commit();
session.close();
- 删除操作
// 删除操作
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 直接创建对象,删除
/* Customer customer = new Customer();
customer.setCust_id(1l);
session.delete(customer);*/
// 先查询再删除(推荐)--级联删除
Customer customer = session.get(Customer.class, 2l);
session.delete(customer);
tx.commit();
session.close();
}
- 保存或更新
设定了id是修改,没有就保存.
public void demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//保存操作
/*Customer customer = new Customer();
customer.setCust_name("甜心");
session.saveOrUpdate(customer);*/
//更新操作
Customer customer = new Customer();
customer.setCust_id(3l);
customer.setCust_name("思思");
session.saveOrUpdate(customer);
tx.commit();
session.close();
}
- 查询所有
public void demo6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 接收HQL:Hibernate Query Language 面向对象的查询语言
customer是类名
/*Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}*/
// 接收SQL:
SQLQuery query = session.createSQLQuery("select * from cst_customer");
List<Object[]> list = query.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
tx.commit();
session.close();
}
( 4 )Transaction:事务对象
- commit()提交
- rollback()