01-Hibernate、环境搭建、配置、API、CRUD
1.1、Hibernate框架学习路线
Hibernate的入门(Hibernate的环境搭建、Hibernate的API、Hibernate的CRUD)
Hibernate的一级缓存、其他的API
Hibernate的一对多配置、Hibernate的多对多的配置
Hibernate的查询方式、抓取策略
1.2、CRM案例
1.2.1、CRM概述
1.2.1.1、什么是CRM
1.2.1.2、CRM有哪些模块
1.3、Hibernate概述
1.3.1、框架概述
1.3.2、EE的三层架构
1.3.2.1、EE的景点三层架构
1.3.3、Hibernate概述
1.3.3.1、什么是Hibernate
1.3.3.2、ORM
1.4、Hibernate入门
1.4.1、Hibernate入门
1.4.1.1、搭建开发环境
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itheima</groupId> <artifactId>hibernate_day01</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>antlr</groupId> <artifactId>antlr</artifactId> <version>2.7.7</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.1</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jta_1.1_spec</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.0.7.Final</version> </dependency> <dependency> <groupId>org.hibernate.common</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>5.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.0.7.Final</version> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.1-api</artifactId> <version>1.0.0.Final</version> </dependency> <dependency> <groupId>org.jboss</groupId> <artifactId>jandex</artifactId> <version>2.0.0.Final</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.18.1-GA</version> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.3.0.Final</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>mchange-commons-java</artifactId> <version>0.2.3.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.2</version> </dependency> </dependencies> </project>
1.4.1.2、创建表
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_phone` varchar(64) DEFAULT NULL COMMENT '固定电话', `cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话', PRIMARY KEY (`cust_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
1.4.1.3、创建实体类
1.4.1.4、创建映射配置文件
映射需要通过XML的配置文件来完成,这个配置文件可以任意命名。尽量统一命名规范(类名.hbm.xml)
约束文件位置:
>xsd > 
<?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.itheima.hibernate.demo01.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>
1.4.1.5、创建Hibernate核心配置文件
<?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</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 配置Hibernate的方言 --> <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> <!-- 配置C3P0连接池 --> <property name="connection.provider_class">org.hibernate.c3p0.internal.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> <mapping resource="com/itheima/hibernate/demo01/Customer.hbm.xml"/> </session-factory> </hibernate-configuration>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement">3</property> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts">30</property> <!--两次连接中间隔时间,单位毫秒。Default: 1000 --> <property name="acquireRetryDelay">1000</property> <!--连接关闭时默认将所有未提交的操作回滚。Default: false --> <property name="autoCommitOnClose">false</property> <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么 属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试 使用。Default: null--> <property name="automaticTestTable">Test</property> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false--> <property name="breakAfterAcquireFailure">false</property> <!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出 SQLException,如设为0则无限期等待。单位毫秒。Default: 0 --> <property name="checkoutTimeout">100</property> <!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。 Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester--> <property name="connectionTesterClassName"></property> <!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可 Default: null--> <property name="factoryClassLocation">null</property> <!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs. (文档原文)作者强烈建议不使用的一个属性--> <property name="forceIgnoreUnresolvedTransactions">false</property> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod">60</property> <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> <property name="initialPoolSize">3</property> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime">60</property> <!--连接池中保留的最大连接数。Default: 15 --> <property name="maxPoolSize">15</property> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0--> <property name="maxStatements">100</property> <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 --> <property name="maxStatementsPerConnection"></property> <!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default: 3--> <property name="numHelperThreads">3</property> <!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0 的数据源时。Default: null--> <property name="overrideDefaultUser">root</property> <!--与overrideDefaultUser参数对应使用的一个参数。Default: null--> <property name="overrideDefaultPassword">password</property> <!--密码。Default: null--> <property name="password"></property> <!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意: 测试的表必须在初始数据源的时候就存在。Default: null--> <property name="preferredTestQuery">select id from test where id=1</property> <!--用户修改系统配置参数执行前最多等待300秒。Default: 300 --> <property name="propertyCycle">300</property> <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 等方法来提升连接测试的性能。Default: false --> <property name="testConnectionOnCheckout">false</property> <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false --> <property name="testConnectionOnCheckin">true</property> <!--用户名。Default: null--> <property name="user">root</property> 在Hibernate(spring管理)中的配置: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property> <property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property> <property name="user"><value>Kay</value></property> <property name="password"><value>root</value></property> <!--连接池中保留的最小连接数。--> <property name="minPoolSize" value="10" /> <!--连接池中保留的最大连接数。Default: 15 --> <property name="maxPoolSize" value="100" /> <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime" value="1800" /> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement" value="3" /> <property name="maxStatements" value="1000" /> <property name="initialPoolSize" value="10" /> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod" value="60" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts" value="30" /> <property name="breakAfterAcquireFailure" value="true" /> <property name="testConnectionOnCheckout" value="false" /> </bean> 编辑本段相关信息连接池配置(以Hibernate为例) ########################### ### C3P0 Connection Pool### ########################### #hibernate.c3p0.max_size 2 #hibernate.c3p0.min_size 2 #hibernate.c3p0.timeout 5000 #hibernate.c3p0.max_statements 100 #hibernate.c3p0.idle_test_period 3000 #hibernate.c3p0.acquire_increment 2 #hibernate.c3p0.validate false 在hibernate.cfg.xml文件里面加入如下的配置: <!-- 最大连接数 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 最小连接数 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 --> <property name="hibernate.c3p0.timeout">120</property> <!-- 最大的PreparedStatement的数量 --> <property name="hibernate.c3p0.max_statements">100</property> <!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒--> <property name="hibernate.c3p0.idle_test_period">120</property> <!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 --> <property name="hibernate.c3p0.acquire_increment">2</property> <!-- 每次都验证连接是否可用 --> <property name="hibernate.c3p0.validate">true</property>
抽取工具类:
1.4.1.8、编写测试代码
public class HibernateDemo1 { //保存客户案例 @Test public void demo01(){ //1.加载Hibernate的核心配置文件 Configuration configure = new Configuration().configure(); //2.创建一个SessionFactory对象 SessionFactory sessionFactory = configure.buildSessionFactory(); //3.通过SessionFactory获取到一个session Session session = sessionFactory.openSession(); //4.手动开启事务 Transaction transaction = session.beginTransaction(); //5.编写代码 Customer customer = new Customer(); customer.setCust_name("payn"); session.save(customer); //6.事务提交 transaction.commit(); //7.资源释放 session.clear(); } }
1.5、Hibernate的常见配置
1.5.1、XML提示配置
1.5.1.1、配置XML提示问题。eclipse下

1.5.2、Hibernate映射配置文件
1.5.2.1、映射配置文件
class
标签用来建立类与表的映射关系
属性:
name :类的全路径
table :表名(类名与表名一致,table可以省略)
catalog :数据库名
id
标签用来建立类中的属性与表中的主键的对应关系
属性:
name :类中的属性名
column :表中的字段名(类中的属性名和表中的字段名如果一致,column可以省略)
length :长度
type :类型
property
标签用来建立类中的普通属性与表的字段的对应关系
属性:
name :类中的属性名
column :表中的字段名
length :长度
type :类型
not-null :设置非空
unique :设置唯一
1.5.3、Hibernate核心配置文件
1.5.3.1、核心配置文件-->配置方式
方式一:属性文件的方式 hibernate.properties
hibernate.connection.driver_class=com.mysql.jdbc.Driver
…
hibernate.show_sql=true
属性文件的方式不能引入映射文件(且需手动编写代码加载映射文件)
方式二:XML文件的方式 hibernate.cfg.xml
1.5.3.2、核心配置文件
必须的配置:
连接数据库的基本的参数
驱动类
url路径
用户名
密码
方言
可选的配置:
显示SQL :hibernate.show_sql
格式化SQL :hibernate.format_sql
自动建表 :hibernate.hbm2ddl.auto
none :不使用hibernate的自动建表
create :如果数据库中已经有表,删除原有表,重新创建,如果没有表,新建表。(测试)
create-drop :如果数据库中已经有表,删除原有表,执行操作,删除这个表。如果没有表,新建一个,使用完了删除该表。(测试)
update :如果数据库中有表,使用原有表,如果没有表,创建新表(更新表结构)
validate :如果没有表,不会创建表。只会使用数据库中原有的表。(校验映射和表结构)。
映射文件的引入 :
引入映射文件的位置
<mapping resource="com/itheima/hibernate/demo01/Customer.hbm.xml"/>
1.6、Hibernate核心API
1.6.1、Hibernate核心API
1.6.1.1、Configuration:配置对象
作用:
加载核心配置文件
hibernate.properties
Configuration cfg = new Configuration();
hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
加载映射文件
// 手动加载映射
configuration.addResource("com/itheima/hibernate/demo1/Customer.hbm.xml");
1.6.1.2、SessionFactory:Session工厂
SessionFactory内部维护了Hibernate的连接池和Hibernate的二级缓存(不讲)。是线程安全的对象。一个项目创建一个对象即可。
配置连接池:(了解)
<!-- 配置C3P0连接池 --> <property name="connection.provider_class">org.hibernate.c3p0.internal.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>
抽取工具类:
/** * Hibernate的工具类 */ public class HibernateUtils { private static Configuration configuration; private static SessionFactory sessionFactory; static { configuration = new Configuration().configure(); sessionFactory = configuration.buildSessionFactory(); } public static Session openSession(){ return sessionFactory.openSession(); } }
1.6.1.3、Session:连接对象
Session代表的是Hibernate与数据库的链接对象。不是线程安全的。与数据库交互桥梁。
Session中的API
保存方法:
Serializable save(Object obj);
查询方法:
T get(Class c,Serializable id);
T load(Class c,Serializable id);
get方法和load方法的区别?
get方法
采用的是立即加载,执行到这行代码的时候,就会马上发送SQL语句去查询。
查询后返回是真实对象本身。
查询一个找不到的对象的时候,返回null
load方法
采用的是延迟加载(lazy懒加载),执行到这行代码的时候,不会发送SQL语句,当真正使用这个对象的时候才会发送SQL语句。
查询后返回的是代理对象。javassist-3.18.1-GA.jar 利用javassist技术产生的代理。
查询一个找不到的对象的时候,返回ObjectNotFoundException
修改方法:
void update(Object obj);
删除方法:
void delete(Object obj);
保存或更新:
void saveOrUpdate(Object obj)
public class HibernateDemo2 { //保存客户 使用工具类 @Test public void demo01(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Customer customer = new Customer(); customer.setCust_name("jack"); Serializable res = session.save(customer); System.out.println(res); tx.commit(); session.clear(); } @Test public void demo02(){ Session session = HibernateUtils.openSession(); //开启事务 Transaction tx = session.beginTransaction(); /* get方法 采用的是立即加载,执行到这行代码的时候,就会马上发送SQL语句去查询。 查询后返回是真实对象本身。 查询一个找不到的对象的时候,返回null load方法 采用的是延迟加载(lazy懒加载),执行到这行代码的时候,不会发送SQL语句,当真正使用这个对象的时候才会发送SQL语句。 查询后返回的是代理对象。javassist-3.18.1-GA.jar 利用javassist技术产生的代理。 查询一个找不到的对象的时候,返回ObjectNotFoundException * */ //使用get方法查询 // Customer customer = session.get(Customer.class, 1L); // System.out.println(customer); //使用load方法进行查询 Customer customer = session.load(Customer.class, 1L); // System.out.println(customer); tx.commit(); session.close(); } @Test // 修改操作 public void demo3(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // 直接创建对象,进行修改 /*Customer customer = new Customer(); customer.setCust_id(1l); customer.setCust_name("mills"); session.update(customer);*/ // 先查询,再修改(推荐) Customer customer = session.get(Customer.class, 1l); customer.setCust_name("white"); session.update(customer); tx.commit(); session.close(); } @Test // 删除操作 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(); } @Test // 保存或更新 public void demo5(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); /*Customer customer = new Customer(); customer.setCust_name("tom"); session.saveOrUpdate(customer);*/ Customer customer = new Customer(); customer.setCust_id(3l); customer.setCust_name("mary"); session.saveOrUpdate(customer); tx.commit(); session.close(); } @Test // 查询所有 public void demo6(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // 接收HQL:Hibernate Query Language 面向对象的查询语言 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(); } }
查询所有:
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
SQLQuery query = session.createSQLQuery("select * from cst_customer");
List<Object[]> list = query.list();
1.6.1.4、Transaction:事务对象
Hibernate中管理事务的对象。
commit();
rollback();

浙公网安备 33010602011771号