概述
框架
框架是软件的半成品,已经完成了相应部分的内容了,只需要实现自己业务即可
hibernate框架
-
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装
-
Hibernate将POJO与数据库表建立映射关系,是一个全自动的ORM框架
-
hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库
-
Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用
ORM
- Object Relational Mapping对象关系映射
-
将对象与数据库中表建立映射关系,操作对象就可以操作数据库中表
hibernate优点
-
简化JDBC的编程
-
修改了实体类,不需要修改源代码
-
轻量级的框架
hibernate入门
下载
解压
-
documentation:Hibernate的开发规范和文档(\documentation\javadocs\index.html)
-
lib:Hibernate的开发使用的jar包(required—必选的jar包,optional—可选的jar包)
-
project:Hibernate的提供测试的工程(etc<hibernate.properties>所有数据库的连接信息)
导入jar包
引入lib/required/*.jar
数据库驱动包
日志包
创建数据库和表
/*创建客户表*/
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_address` varchar(128) DEFAULT NULL COMMENT '客户联系地址',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '客户联系电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
创建实体类
public class Customer {
private Long custId;
private String custName;
private String custSource;
private String custIndustry;
private String custLevel;
private String custAddress;
private String custPhone;
public Customer() {
super();
}
public Customer(Long custId, String custName, String custSource, String custIndustry, String custLevel,
String custAddress, String custPhone) {
super();
this.custId = custId;
this.custName = custName;
this.custSource = custSource;
this.custIndustry = custIndustry;
this.custLevel = custLevel;
this.custAddress = custAddress;
this.custPhone = custPhone;
}
public Long getCustId() {
return custId;
}
public void setCustId(Long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
@Override
public String toString() {
return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
+ ", custPhone=" + custPhone + "]";
}
}
创建映射文件
约束位置
类名.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:实体类的全限定类名 table:表名 catalog:数据库名,可以省略-->
<class name="com.itheima.domain.Customer" table="cst_customer" catalog="crm">
<!-- id:用来建立表中主键和类中属性的映射 -->
<!-- name:类中的属性 column:表中列名-->
<id name="custId" column="cust_id">
<!-- generator:主键生成策略 native:主键自动增长-->
<generator class="native" />
</id>
<!-- property:表中其他列(column)和类中其他属性(name)的映射 -->
<!-- length:长度 not-null:非空 unique:唯一 -->
<property name="custName" column="cust_name" length="100" unique="true"/>
<property name="custSource" column="cust_source" />
<property name="custIndustry" column="cust_industry" />
<property name="custLevel" column="cust_level" />
<property name="custAddress" column="cust_address" />
<property name="custPhone" column="cust_phone" />
</class>
</hibernate-mapping>
创建核心配置文件
约束位置
(hibernate.cfg.xml),放在SRC下
<?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>
<!-- 配置数据库的连接信息了 必选项 5个 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///crm</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 方言 分页查询每一个数据库都不一样 -->
<!-- 作用:让hibernate自动去匹配符合当前数据库的sql语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选项 -->
<!-- 连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 让控制台输出hibernate给我们自动生成的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化输出的sql语句 -->
<property name="hibernate.format_sql">true</property>
<!-- 让hibernate生成对应的数据库表 -->
<!--
create:没有表自动创建表,有表删除再给你创建
create-drop: 没有表自动创建表,有表删除再给你创建,最终用完就删除,测试数据
update: 没有表创建表,有表使用表
validate:默认没有配置的值 不让hibernate创建表 得自己维护表
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 引入映射文件地址 -->
<mapping resource="com/itheima/domain/Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>
编写代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.itheima.domain.Customer;
public class TestHibernate {
@Test
public void save() throws Exception {
// 1.加载数据库核心配置文件
Configuration config = new Configuration();
config.configure();
// 2.创建SessionFactory 底层维护连接池
SessionFactory sessionFactory = config.buildSessionFactory();
// 3.获取session
Session session = sessionFactory.openSession();
// 4.开启事务
Transaction tx = session.beginTransaction();
// 5.创建用户
Customer customer = new Customer();
customer.setCustName("jack");
// 6.保存
session.save(customer);
// 7.提交事务
tx.commit();
// 8.关闭资源
session.close();
sessionFactory.close();
}
}
hibernate的常见配置
核心配置文件的方式
- hibernate.properties
- 不能加载映射文件(类名.hbm.xml)。必须手动编写代码加载映射文件
- hibernate.cfg.xml
- 结构清晰(工作中用)
核心配置文件的内容
数据库的基本配置信息5个
<!-- 配置数据库的连接信息了 必选项 5个 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///crm</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 方言 分页查询每一个数据库都不一样 -->
<!-- 作用:让hibernate自动去匹配符合当前数据库的sql语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
可选的配置信息
<!-- 连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 让控制台输出hibernate给我们自动生成的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化输出的sql语句 -->
<property name="hibernate.format_sql">true</property>
<!-- 让hibernate生成对应的数据库表 -->
<!--
create:没有表自动创建表,有表删除再给你创建
create-drop: 没有表自动创建表,有表删除再给你创建,最终用完就删除,测试数据
update: 没有表创建表,有表使用表
validate:默认没有配置的值 不让hibernate创建表 得自己维护表
-->
<property name="hibernate.hbm2ddl.auto">update</property>
加载映射文件
<!-- 引入映射文件地址 -->
<mapping resource="com/itheima/domain/Customer.hbm.xml" />
抽取工具类
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
public static final Configuration config;
public static final SessionFactory sessionFactory;
static{
config= new Configuration().configure();
sessionFactory = config.buildSessionFactory();
}
public static Session openSession(){
return sessionFactory.openSession();
}
}
Hibernate的常用API
Configuration
- 用来加载核心配置文件
- 方法
- 加载核心配置文件
- Configuration cfg = new Configuration().configure();//xml配置文件
- 加载映射文件
- Configuration config = new Configuration();//properties配置文件
- config .addResource("com/itheima/domain/Customer.hbm.xml");
- 创建session工厂
- public SessionFactory buildSessionFactory();
SessionFactory
作用:创建session
- Session工厂,是一个线程安全的对象,内部维护Hibernate的连接池
- 一般一个应用(项目)只需要创建一次的对象
- 方法
方法 | 作用 |
public Session openSession() ; | 获取session |
Session
- Session是Hibernate持久化操作的核心API,它提供了和持久化有关的操作,比如添加、修改、删除、加载和查询实体对象
- Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心
- Session是线程不安全的,所以不要放在对象的成员位置上
- 所有持久化对象必须在 session 的管理下才可以进行持久化操作
- Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久化操作的数据都缓存在 session 对象处
- 持久化类与 Session 关联起来后就具有了持久化的能力
特点
- 不是线程安全的。应避免多个线程使用同一个Session实例
- Session是轻量级的,它的创建和销毁不会消耗太多的资源。应为每次客户请求分配独立的Session实例
- Session有一个缓存,被称之为Hibernate的一级缓存。每个Session实例都有自己的缓存
常用的方法
方法 | 描述 |
save(Object obj); | 添加数据 |
update(Object obj); | 修改数据 |
delete(Object obj); | 删除数据 |
T get(Class c,Serializable s); | 查询数据 |
T load(Class c,Serializable s); | 查询数据 |
saveOrUpdate(Object obj); | 保存或者修改 |
createQuery() | HQL语句的查询的方式 |
beginTransaction(); | 开启事务 |
get/load方法的区别
- get
- 立即加载:执行get方法立即发送,执行SQL语句
- 返回的是自身对象
- 查不到结果返回null
- load
- 延迟加载:不会立即访问数据库,而是返回代理对象,只有真正需要使用对象的时候才会访问数据库
- 返回的是代理对象
- 查不到结果报错
Transaction
Transaction是事务的接口
常用的方法
方法 | 作用 |
commit() | 提交事务 |
rollback() | 回滚事务 |
特点
- Hibernate框架默认情况下事务不自动提交,需要手动提交事务
- 如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务
案例
import java.sql.Connection;
import java.sql.SQLException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.junit.Test;
import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;
public class TestHibernate {
@Test
public void save() throws Exception {
// 1.加载数据库核心配置文件
Configuration config = new Configuration();
config.configure();
// 2.创建SessionFactory 底层维护连接池
SessionFactory sessionFactory = config.buildSessionFactory();
// 3.获取session
Session session = sessionFactory.openSession();
// 4.开启事务
Transaction tx = session.beginTransaction();
// 5.创建用户
Customer customer = new Customer();
customer.setCustName("jack");
// 6.保存
session.save(customer);
// 7.提交事务
tx.commit();
// 8.关闭资源
session.close();
sessionFactory.close();
}
/**
* @MethodName:selectOne
* @Description:查询数据库中的一条记录
* @throws Exception
*/
@Test
public void selectOne() throws Exception {
// 1.获取session
Session session = HibernateUtils.openSession();
// 2.开启事务
Transaction tx = session.beginTransaction();
// 3.执行查询
Customer customer = session.get(Customer.class, 1L);// id是Long类型的数据
System.out.println(customer);
// 提交事务
tx.commit();
// 关闭资源
session.close();
}
/**
* @MethodName:updateName
* @Description:修改客户姓名
* @throws Exception
*/
@Test
public void updateName() throws Exception {
// 1.获取session
Session session = HibernateUtils.openSession();
// 2.开启事务
Transaction tx = session.beginTransaction();
// 3.修改数据要先查后改
Customer customer = session.get(Customer.class, 1l);
customer.setCustName("rose");
session.update(customer);
// 4.提交事务
tx.commit();
// 5.关闭资源
session.close();
}
/**
* @MethodName:delete
* @Description:
* @throws Exception
*/
@Test
public void delete() throws Exception {
// 1.获取session
Session session = HibernateUtils.openSession();
// 2.开启事务
Transaction tx = session.beginTransaction();
// 3.先查询,后删除
Customer customer = session.get(Customer.class, 3l);
session.delete(customer);
// 4.提交事务
tx.commit();
// 5.关闭资源
session.close();
}
/**
* @MethodName:testName
* @Description:证明session连接是从配置好的c3p0连接池获取的
* @throws Exception
*/
@Test
public void testName() throws Exception {
Session session = HibernateUtils.openSession();
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
System.out.println(connection.getClass().getName());
}
});
}
}