Hibernate框架
标签(空格分隔): javaWeb
[TOC]
Hibernate介绍
Hibernate核心内容是ORM(关系对象模型)。可以将对象自动的生成数据库中的信息,使得开发更加的面向对象。这样作为程序员就可以使用面向对象的思想来操作数据库,而不用关心繁琐的JDBC。所以,Hibernate处于三层架构中的D层(持久层)
Hibernate核心技术
Configuration
Configuration作用:
- 读取 hibernate.cfg.xml
- 管理对象关系映射文件
- 加载 hibernate 驱动 url 以及用户名,密码....
- 管理 hibernate 配置信息(mapping resource)
SessionFactory
SessionFactory作用:
- 可以缓存sql语句和数据,称为sessionFactory级的缓存(二级缓存)
- 它是一个重量级的类,因此我们需要保证一个数据库只有一个sessionfactory
sessionfactory获取session的方法
SessionFactory factory = new Configuration().configure().buildSessionFactory();
//openSession();
//---是获取一个新的 Session
Session session = factory.openSession();
//getCurrentSession();
//---获取和当前线程绑定的session,就是在同一个线程中,获取的session是同一个session,这样可以利于事务的控制
Session session = factory.getCurrentSession();
/*
getCurrentSession须先配置才能用:
需要在hibernate.cfg.xml的配置文件中提供配置
<property name="hibernate.current_session_context_class">thread</property>
*/
方法 | 使用方式 | 关闭方式 | 线程安全 |
---|---|---|---|
openSession() | 同一个线程中,每次都使用不同session | 手动关闭 | 不安全 |
getCurrentSession() | 同一个线程中,保证使用同一个session | 自动关闭 | 安全 |
Session
Session之快照机制
在创建session这个一级缓存对象的时候,session分为2块区域,一个是缓存区域。一个是快照区域
当到了查询语句, 所获得的数据,缓存区域保存一份,快照区域也保存一份。
到后面的set的时候,会修改缓存区域的参数。
当提交事务的时候,会对比2块区域的内容,一致就没问题。不一致就修改数据库。
与一级缓存相关的方法
session.close() //一级缓存消失
Session.clear(); //清空缓存
Session.evict(Object entity); //清除指定的对象在一级缓存中的引用
Session.flisb(); //使用数据库中的数据覆盖缓存中的数据
Query查询接口
// 1.查询所有记录
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
System.out.println(list);
条件查询
// 1.条件查询:
Query query = session.createQuery("from Customer where name = ?");
query.setString(0, "李健");
List<Customer> list = query.list();
System.out.println(list);
// 2.条件查询:
Query query = session.createQuery("from Customer where name = :aaa and age = :bbb");
query.setString("aaa", "李健");
query.setInteger("bbb", 38);
List<Customer> list = query.list();
System.out.println(list);
排序查询
//排序查询和SQL语句中的排序的语法是一样的
升序
session.createQuery("from Customer order by cust_id").list();
//降序
session.createQuery("from Customer order by cust_id desc").list();
分页查询
Hibernate框架提供了分页的方法,咱们可以调用方法来完成分页
//两个方法如下:
setFirstResult(a) //-- 从哪条记录开始,如果查询是从第一条开启,值是0
setMaxResults(b) //-- 每页查询的记录条数
//演示代码如下
List<LinkMan> list = session.createQuery("from LinkMan").setFirstResult(0).setMaxResults().list();
Criteria查询接口
// 1.查询所有记录
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
System.out.println(list);
// 2.条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "李健"));
List<Customer> list = criteria.list();
System.out.println(list);
// 3.条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "李健"));
criteria.add(Restrictions.eq("age", 38));
List<Customer> list = criteria.list();
System.out.println(list);
Transtraction(事物)
Hibernate的使用
下载jar包:
导入jar
/*Hibernate-required start */
hibernate-core-5.0.7.Final.jar //核心
hibernate-commons-annotations-5.0.1.Final.jar //注解
javassist-3.18.1-GA.jar //动态代理
dom4j-1.6.1.jar //XML解析
antlr-2.7.7.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
jboss-logging-3.3.0.Final.jar
standard.jar
/*Hibernate-required end */
/*---------------------------------*/
//BeanUtils包
commons-beanutils-1.8.3.jar
commons-logging-1.1.1.jar
/*---------------------------------*/
//jstl包
jstl.jar
standard.jar
/*---------------------------------*/
//mysql驱动包
mysql-connector-java-5.1.7-bin.jar
/*---------------------------------*/
/*日志 log4j*/
slf4j-api-1.6.1.jar //Hibernate推荐使用的日志接口(未实现)
slf4j-log4j12-1.7.2.jar //log4j接口与实现间的链接
log4j-1.2.16.jar //log4j具体实现
/*---------------------------------*/
持久化类
持久化类 = JavaBean(Java类) + xxx.hbm.xml(hbm的配置文件)
持久化类的编写规则
- 提供一个无参数 public访问控制符的构造器 -- 底层需要进行反射.
- 提供一个标识属性,映射数据表主键字段 -- 唯一标识OID.数据库中通过主键.Java对象通过地址确定对象.持久化类通过唯一标识OID确定记录
- 所有属性提供public访问控制符的 set或者get 方法
- 标识属性应尽量使用基本数据类型的包装类型
新建JavaBean类Customer.java
package com.itheima.domain;
/**
* 客户的JavaBean
* @author Administrator
*/
public class Customer {
/**
* `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_user_id` bigint(32) DEFAULT NULL COMMENT '负责人id',
`cust_create_id` bigint(32) DEFAULT NULL COMMENT '创建人id',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_linkman` varchar(64) DEFAULT NULL COMMENT '联系人',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
*/
// 以后使用包装类,默认值是null
private Long cust_id;
private String cust_name;
private Long cust_user_id;
private Long cust_create_id;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_linkman;
private String cust_phone;
private String cust_mobile;
public Long getCust_id() {
return cust_id;
}
public void setCust_id(Long cust_id) {
this.cust_id = cust_id;
}
public String getCust_name() {
return cust_name;
}
public void setCust_name(String cust_name) {
this.cust_name = cust_name;
}
public Long getCust_user_id() {
return cust_user_id;
}
public void setCust_user_id(Long cust_user_id) {
this.cust_user_id = cust_user_id;
}
public Long getCust_create_id() {
return cust_create_id;
}
public void setCust_create_id(Long cust_create_id) {
this.cust_create_id = cust_create_id;
}
public String getCust_source() {
return cust_source;
}
public void setCust_source(String cust_source) {
this.cust_source = cust_source;
}
public String getCust_industry() {
return cust_industry;
}
public void setCust_industry(String cust_industry) {
this.cust_industry = cust_industry;
}
public String getCust_level() {
return cust_level;
}
public void setCust_level(String cust_level) {
this.cust_level = cust_level;
}
public String getCust_linkman() {
return cust_linkman;
}
public void setCust_linkman(String cust_linkman) {
this.cust_linkman = cust_linkman;
}
public String getCust_phone() {
return cust_phone;
}
public void setCust_phone(String cust_phone) {
this.cust_phone = cust_phone;
}
public String getCust_mobile() {
return cust_mobile;
}
public void setCust_mobile(String cust_mobile) {
this.cust_mobile = cust_mobile;
}
@Override
public String toString() {
return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + ", cust_user_id=" + cust_user_id
+ ", cust_create_id=" + cust_create_id + ", cust_source=" + cust_source + ", cust_industry="
+ cust_industry + ", cust_level=" + cust_level + ", cust_linkman=" + cust_linkman + ", cust_phone="
+ cust_phone + ", cust_mobile=" + cust_mobile + "]";
}
}
java同目录配置映射文件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.itheima.domain.Customer" table="cst_customer">
<!-- 配置id
见到name属性,JavaBean的属性
见到column属性,是表结构的字段
-->
<id name="cust_id" column="cust_id">
<!-- 主键的生成策略
increment:Hibernate中提供的一种增长机制(并发访问会出错)
identity:数据库的自动增长(auto_increment)(Oracle数据库没有自动增长)
sequence:底层使用的是序列的增长方式(Oracle自动增长需要使用)
uuid:使用随机的字符串作为主键
native:本地策略(MySQL-使用identity,Oracle-使用sequence)
-->
<generator class="native"/>
</id>
<!-- 配置其他的属性 -->
<property name="cust_name" column="cust_name"/>
<property name="cust_user_id" column="cust_user_id"/>
<property name="cust_create_id" column="cust_create_id"/>
<property name="cust_source" column="cust_source"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_linkman" column="cust_linkman"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
</class>
</hibernate-mapping>
核心配置文件hibernate.cfg.xml
可以参考hibernate包hibernate-release-5.0.7.Final\project\etc\hibernate.properties
<?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>
<!-- 先配置SessionFactory标签,一个数据库对应一个SessionFactory标签 -->
<session-factory>
<!-- 必须要配置的参数有5个,4大参数,数据库的方言 -->
<!-- mysql数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- mysql数据库名称 -->
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 数据库的方言:为每一种数据库提供适配器,方便转换-->
<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>
<!-- 生成数据库的表结构
update:如果没有表结构,创建表结构。如果存在,不会创建,添加数据
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 映射配置文件,需要引入映射的配置文件 -->
<mapping resource="com/itheima/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
测试环境
/**
* 测试保存
*/
// 获取session
Session session = HibernateUtils.getSession();
// 开启事务
Transaction tr = session.beginTransaction();
// 执行代码
Customer c = new Customer();
c.setCust_name("哈哈");
// 保存
session.save(c);
// 提交事务事务
tr.commit();
// 释放资源
session.close();
/**
* 测试查询的方法
*/
// 原来:加载配置文件,获取Factory对象,获取session
Session session = HibernateUtils.getSession();
Transaction tr = session.beginTransaction();
// 创建查询的接口
Query query = session.createQuery("from Customer");
// 查询所有的数据 select * from 表
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
// 提交事务
tr.commit();
// 释放资源
session.close();
}
/**
* 测试添加或者修改
*/
@Test
public void testSaveOrUpdate(){
// 原来:加载配置文件,获取Factory对象,获取session
Session session = HibernateUtils.getSession();
Transaction tr = session.beginTransaction();
/*// 演示错误
Customer c = new Customer();
// c.setCust_id(10L); 千万不能自己设置
c.setCust_name("测试");
// 保存或者修改
session.saveOrUpdate(c);*/
// 先查询再改
Customer c = session.get(Customer.class, 6L);
c.setCust_name("小泽");
session.saveOrUpdate(c);
// 提交事务
tr.commit();
// 释放资源
session.close();
}
/**
* 测试修改
*/
@Test
public void testUpdate(){
// 原来:加载配置文件,获取Factory对象,获取session
Session session = HibernateUtils.getSession();
Transaction tr = session.beginTransaction();
// 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值
Customer c = session.get(Customer.class, 6L);
// 设置客户的信息
c.setCust_name("小苍");
c.setCust_level("3");
// 修改
session.update(c);
// 提交事务
tr.commit();
// 释放资源
session.close();
}
/**
* 测试删除的方法
* 注意:删除或者修改,先查询再删除或者修改
*/
@Test
public void testDel(){
// 原来:加载配置文件,获取Factory对象,获取session
Session session = HibernateUtils.getSession();
Transaction tr = session.beginTransaction();
// 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值
Customer c = session.get(Customer.class, 7L);
// 删除客户
session.delete(c);
// 提交事务
tr.commit();
// 释放资源
session.close();
}
/**
* 测试get()方法,获取查询,通过主键来查询一条记录
*/
@Test
public void testGet(){
// 原来:加载配置文件,获取Factory对象,获取session
Session session = HibernateUtils.getSession();
Transaction tr = session.beginTransaction();
// 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值
Customer c = session.get(Customer.class, 7L);
System.out.println(c);
// 提交事务
tr.commit();
// 释放资源
session.close();
}
/**
* 测试工具类
*/
@Test
public void testSave2(){
// 原来:加载配置文件,获取Factory对象,获取session
Session session = HibernateUtils.getSession();
Transaction tr = session.beginTransaction();
Customer c = new Customer();
c.setCust_name("小风");
session.save(c);
// 提交事务
tr.commit();
// 释放资源
session.close();
}
/**
* 测试保存客户
*/
@Test
public void testSave(){
/**
* 1. 先加载配置文件
* 2. 创建SessionFactory对象,生成Session对象
* 3. 创建session对象
* 4. 开启事务
* 5. 编写保存的代码
* 6. 提交事务
* 7. 释放资源
*/
/*// 1. 先加载配置文件
Configuration config = new Configuration();
// 默认加载src目录下hibernate.cfg.xml的配置文件
config.configure();
// 了解,手动加载
// config.addResource("com/itheima/domain/Customer.hbm.xml");
*/
// 简写的方法
Configuration config = new Configuration().configure();
// 2. 创建SessionFactory对象
SessionFactory factory = config.buildSessionFactory();
// 3. 创建session对象
Session session = factory.openSession();
// 4. 开启事务
Transaction tr = session.beginTransaction();
// 5. 编写保存的代码
Customer c = new Customer();
// c.setCust_id(cust_id); 主键是自动递增了
c.setCust_name("测试3");
c.setCust_level("2");
c.setCust_phone("110");
// 保存数据,操作对象就相当于操作数据库的表结构
session.save(c);
// 6. 提交事务
tr.commit();
// 7. 释放资源
session.close();
factory.close();
}
常用方法
save(obj);
delete(obj);
get(obj);
update(obj);
saveorupdate(obj);
creatrQuery(obj);
网友评论