一、JavaEE三层架构
- web表现层
- service业务层
- dao持久层
二、三大框架
- struts2表现层框架
- hibernate持久层框架(只能操作数据库)
- spring综合类框架
三、MVC思想(表现层的设计模式)
- m:模型
- v:视图
- c:控制器
四、概念
(一)Hibernate
hibernate是轻量级、企业级的开源框架。
hibernate底层对JDBC进行了封装,好处是不需要写JDBC代码和SQL语句。
在dao持久化层使用hibernate实现数据库的CRUD操作
(二)ORM思想
hibernate使用ORM思想对数据库进行CRUD操作
ORM:Object Relational Mapping,对象关系映射。建立实体类和数据库表之间的对应关系,实现操作实体类对象即操作数据库表。
五、搭建Hibernate环境
(一)导入jar包
(二)创建实体类
package com.caijiajia.domain;
import java.io.Serializable;
/**
* @ClassName:Customer
* @Description:实体类
* @Author:chicago
* @Date:2018/8/31 上午8:30
* @Version 1.0
*/
public class Customer implements Serializable {
private Integer custId;
private String custName;
private String custSource;
private String custIndustry;
private String custLevel;
private String custAddress;
private String custPhone;
public Integer getCustId() {
return custId;
}
public void setCustId(Integer 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 + '\'' +
'}';
}
}
(三)配置实体类和数据库表的映射关系
<?xml version="1.0" encoding="UTF-8"?>
<!--
1、在实体类所在的包下创建xml配置文件,建议文件名称为:实体类名+hbm.xml
2、导入dtd约束
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.caijiajia.domain">
<!--
class标签:
name属性:实体类全路径;
table属性:数据库表名称;
-->
<class name="Customer" table="cst_customer">
<!--
配置实体类id和表id对应:
hibernate要求实体类有一个属性唯一值、表有字段作为唯一值;
-->
<id name="custId" column="cust_id">
<!--
设置数据库id的增长策略:generator指定主键的生成方式。
native:使用本地数据库的自动增长能力。
-->
<generator class="native"></generator>
</id>
<property name="custName" column="cust_name"></property>
<property name="custSource" column="cust_source"></property>
<property name="custIndustry" column="cust_industry"></property>
<property name="custLevel" column="cust_level"></property>
<property name="custAddress" column="cust_address"></property>
<property name="custPhone" column="cust_phone"></property>
</class>
</hibernate-mapping>
(四)创建hibernate核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- 项目根路径下创建名称为hibernate.cfg.xml配置文件,并导入dtd约束 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
配置SessionFactory,创建Session对象。
Session对象是hibernate中操作数据库的核心对象。
-->
<session-factory>
<!-- 创建SessionFactory的三部分信息 -->
<!-- 1、连接数据库的信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234567890</property>
<!-- 2、hibernate的可选配置 -->
<!-- 数据库的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 是否显示hibernate生成SQL的语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 是否使用格式化输出SQL语句到控制台 -->
<property name="hibernate.format_sql">true</property>
<!--
SQL结构化查询语言包含6部分:
DDL:Data Definition Language
DML:Data Manipulation Language
DQL:Data Query Language
DCL:Data Control Language 数据控制语言
CCL:Cursor Control Language 游标控制语言
TPL:Transaction Processing Language 事务处理语言
-->
<!-- update表示检测实体类的映射配置和数据库的表结构是否一致。如果不一致,则更新表结构。 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 3、映射文件的位置 -->
<mapping resource="com.caijiajia.domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
(五)实现操作(添加)
package com.caijiajia.test;
import com.caijiajia.domain.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* @ClassName:Test
* @Description:单元测试:实现保存一个客户到数据库
* @Author:chicago
* @Date:2018/9/2 下午3:22
* @Version 1.0
*/
public class Test {
/**
* 步骤分析:
* 1、加载hibernate核心配置文件;
* 2、根据核心配置文件创建SessionFactory;
* 3、根据SessionFactory创建Session;
* 4、开启事务;
* 5、执行保存操作;
* 6、提交事务;
* 7、释放资源;
*/
@org.junit.Test
public void add() {
Customer c = new Customer();
c.setCustName("taobao");
// 创建配置文件对象
Configuration cfg = new Configuration();
// 1、加载核心配置文件(加载默认位置、默认名称的配置文件)
cfg.configure();
// 2、根据核心配置文件创建SessionFactory对象(此过程会根据映射关系创建数据库表)
SessionFactory factory = cfg.buildSessionFactory();
// 3、根据SessionFactory创建Session对象
Session session = factory.openSession();
// 4、开启事务
Transaction tx = session.beginTransaction();
// 5、执行保存操作
session.save(c);
// 6、提交事务
tx.commit();
// 7、释放资源
session.close();
factory.close();
}
}
(六)运行结果
六、Hibernate配置文件详解
(一)映射配置文件
- 映射配置文件名和位置没有固定要求;
- class标签name属性值为实体类全路径;
- id标签和property标签name属性值为实体类属性名;
- id标签和property标签column属性省略表示和name属性值一样;
- property标签type属性表示生成表字段的类型;
(二)核心配置文件
- 配置文件名和位置固定;
- 配置包含三部分:数据库必须配置、hibernate可选配置、映射文件必须配置;
七、Hibernate核心API
(一)Configuration
// 创建配置文件对象
Configuration cfg = new Configuration();
// 加载核心配置文件(加载默认位置、默认名称的配置文件)
cfg.configure();
Configuration创建配置文件对象,并加载项目根路径下的hibernate.cfg.xml配置文件。
(二)SessionFactory
SessionFactory接口是线程安全的。
- 负责初始化Hibernate和创建Session对象;
- 起到缓冲区的作用(将自动生成的SQL语句、映射数据、可重复利用的数据放入缓冲区);
- 维护hibernate信息(提高效率):
- 连接数据库的信息;
- hibernate基本配置信息;
- 映射文件的位置信息;
- 映射配置文件的内容;
理解如何提高效率:创建SessionFactory对象时,在映射配置文件中生成对应每个实体类的预定义SQL语句(至少四条增删改查)。从而,在多线程应用中,减少读取配置文件生成语句的开销。因此,SessionFactory对象是线程安全的。
SessionFactory对象使用原则:一个应用只有一个SessionFactory对象(只创建一次),在应用加载时(服务器启动时)创建,应用卸载时销毁。
(三)Session
Session对象负责操作数据库,维护hibernate的一级缓存,是非线程安全的。
使用原则:一个线程只能有一个Session对象。
调用Session对象中的方法实现CRUD操作:
- 添加:save
- 修改:update
- 删除:delete
- 根据id查询:get
step 1:抽取工具类
package com.caijiajia.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* @ClassName:HibernateUtils
* @Description:抽取hibernate的工具类
* @Author:chicago
* @Date:2018/9/3 下午9:10
* @Version 1.0
*/
public class HibernateUtils {
private static SessionFactory factory;
// hibernate把可以预见的异常都转成运行时异常
static {
try {
Configuration cfg = new Configuration();
cfg.configure();
factory = cfg.buildSessionFactory();
} catch (ExceptionInInitializerError e) {
throw new ExceptionInInitializerError("初始化SessionFactory失败,请检查配置文件");
}
}
/**
* 获取新的Session对象
*
* @return
*/
public static Session openSession() {
return factory.openSession();
}
}
step 2:实现CRUD操作
package com.caijiajia.test;
import com.caijiajia.domain.Customer;
import com.caijiajia.utils.HibernateUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import java.util.List;
/**
* @ClassName:TestUtils
* @Description:实现CRUD操作
* @Author:chicago
* @Date:2018/9/3 下午9:33
* @Version 1.0
*/
public class TestUtils {
@Test
public void testSave() {
Customer c = new Customer();
c.setCustName("测试保存功能");
Session s = HibernateUtils.openSession();
Transaction tx = s.beginTransaction();
// 保存客户
s.save(c);
tx.commit();
s.close();
}
@Test
public void testFindOne() {
Session s = HibernateUtils.openSession();
Transaction tx = s.beginTransaction();
// 查询id为5的客户
Customer c = s.get(Customer.class, 5);
System.out.println(c);
tx.commit();
s.close();
}
@Test
public void testUpdate() {
Session s = HibernateUtils.openSession();
Transaction tx = s.beginTransaction();
// 查询id为5的客户
Customer c = s.get(Customer.class, 5);
// 修改客户的地址为:上海市浦东新区
c.setCustAddress("上海市浦东新区");
// 执行更新
s.update(c);
tx.commit();
s.close();
}
@Test
public void testDelete() {
Session s = HibernateUtils.openSession();
Transaction tx = s.beginTransaction();
// 查询id为5的客户
Customer c = s.get(Customer.class, 5);
// 删除id为5的客户
s.delete(c);
tx.commit();
s.close();
}
@Test
public void testFindAll() {
Session s = HibernateUtils.openSession();
Transaction tx = s.beginTransaction();
//使用Session对象获取查询SQLQuery对象
SQLQuery sqlQuery = s.createSQLQuery("select * from cst_customer");
//使用SQLQuery对象获取结果集
List<Object[]> list = sqlQuery.list();
for (Object[] os : list) {
System.out.println("==========数组中的内容==========");
for (Object o : os) {
System.out.println(o);
}
}
tx.commit();
s.close();
}
}
(四)Transaction
Transaction负责提交和回滚事务。
// 通过Session对象开启事务
Transaction tx = session.beginTransaction();
/**
* 事务回滚
*/
@Test
public void testRollback() {
Customer c = new Customer();
c.setCustName("测试保存功能");
Session s = null;
Transaction tx = null;
try {
s = HibernateUtils.openSession();
tx = s.beginTransaction();
// 保存客户
s.save(c);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
s.close();
}
}
八、Hibernate中使用C3P0连接池
(一)导入c3p0相关的jar包
(二)创建核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- 项目根路径下创建名称为hibernate.cfg.xml配置文件,并导入dtd约束 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
配置SessionFactory,创建Session对象。
Session对象是hibernate中操作数据库的核心对象。
-->
<session-factory>
<!-- 创建SessionFactory的三部分信息 -->
<!-- 1、连接数据库的信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234567890</property>
<!-- 2、hibernate的可选配置 -->
<!-- 数据库的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 是否显示hibernate生成SQL的语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 是否使用格式化输出SQL语句到控制台 -->
<property name="hibernate.format_sql">true</property>
<!--
SQL结构化查询语言包含6部分:
DDL:Data Definition Language
DML:Data Manipulation Language
DQL:Data Query Language
DCL:Data Control Language 数据控制语言
CCL:Cursor Control Language 游标控制语言
TPL:Transaction Processing Language 事务处理语言
-->
<!-- update表示检测实体类的映射配置和数据库的表结构是否一致。如果不一致,则更新表结构。 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 设置hibernate的连接池提供商 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 3、映射文件的位置 -->
<mapping resource="com.caijiajia.domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>