非本人总结的笔记,抄点笔记复习复习。感谢传智博客及黑马程序猿
Hibernate的简介
什么是Hibernate
Hibernate:冬眠。对类进行实例化操作,这里类指的是之前说的javabean,javabean正确的叫法:实体类 entity
Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库****ORM****框架
Hibernate具体实现的操作:
Hibernate的是开源轻量级的框架,对jdbc的代码进行封装,程序员不需要写底层的sql语句的代码,就可以实现对数据库的操作。实现对数据库的crud操作。
Javaee中有三层结构
Web层:struts2
Service层:spring
持久化层(dao层):hibernate框架
Hibernate是使用在持久化层的框架
Jdbc底层代码的步骤:
1 加载驱动
2 创建连接
3 对sql语句进行预编译操作
4 设置参数,执行sql语句
5 释放资源
什么是ORM
ORM: object relational mapping , 对象关系映射
ORM 就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作
做操作时候,有实体类 ,有数据库表 ,
在hibernate中,让实体类和数据库进行映射对应的关系(配置文件配置),
操作实体类就相当于操作数据库表中的数据
流行数据库框架
JPA Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系(只有接口规范)
Hibernate 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL
MyBatis 本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架
Apache DBUtils 、Spring JDBCTemplate
Hibernate的优点
- Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
- Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作
- Hibernate使用java的反射机制,而不是字节码增强程序类实现透明性
- Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系
Hibernate的版本
Struts2 版本 2.3.15
Hibernate 版本 3.6.10
Hibernate 3.x 4.x 5.x
1、下载hibernate3.x的开发包 (3.6.10)
http://sourceforge.net/projects/hibernate/files/hibernate3/
2.jar包作用
Hibernate的入门案例
Hibernate的开发环境搭建
第一步:导入hibernate的核心的jar包
1、导入hibernate的核心的jar包
2、导入lib里面的required里面的所有的jar包
3、导入lib里面jpa中所有的jar包
4、hibernate需要日志的输出
hibernate本身不支持日志输出,导入第三方支持日志输出的jar包(两个)
5、导入数据库驱动的jar包
加上数据库驱动jar包一共有 11个
第二步:创建实体类 user类
package cn.itcast.entity;
import java.util.Date;
/**
* 实体类
*/
public class User {
private Integer id;
private String username;
private Date birthday;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
第三步:创建Hibernate的核心配置文件
1、Hibernate的核心配置文件
名称必须是 hibernate.cfg.xml,位置放到 src下面
2、在核心配置文件中引入dtd约束
<?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">
3、配置的相关信息
(1)配置数据库的相关内容
(2)配置hibernate的相关内容
<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>
<!-- 配置数据库的方言
比如在mysql里面有关键字 limit ,只能使用在mysql里面
让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>
<!-- hibernate会帮自己创建数据库表,默认不会创建,需要配置
值 update: 如果数据库里面不存在表,创建;如果已经存在,更新
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置事务自动提交 -->
<!-- <property name="hibernate.connection.autocommit">true</property> -->
<!-- 引入映射配置文件 -->
<mapping resource="cn/itcast/entity/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
第四步:配置实体类和数据表映射关系
1、创建映射配置文件,文件格式xml
但是这个文件映射配置文件名称和位置没有要求,一般建议:命名(实体类.hbm.xml) 位置:放到实体类所在的包里面
2、映入dtd约束
<?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">
3、配置实体类和表映射关系
<hibernate-mapping>
<!-- 配置实体类名称和表名称对应
name:实体类全路径
table:表名称
-->
<class name="cn.itcast.entity.User" table="USER">
<!--
在hibernate中要求每个表有一个唯一标识
-->
<id name="id" column="ID">
<generator class="identity"></generator>
</id>
<!-- 配置其他的属性和其他字段映射
name: 实体类属性名称
column: 表里面字段名称
细节问题:
1 propery里面有 type属性,指定字段类型,但是可以省略
2 column属性,实体类属性名称和字段名称一样,column可以省略
-->
<property name="username" column="USERNAME"></property>
<property name="birthday" column="BIRTHDAY"></property>
</class>
</hibernate-mapping>
第五步:在Hibernate的核心配置文件中映入映射文件
因为hibernate只会加载核心配置文件,其他文件不会加载
如果没有在核心文件中引入映射文件,出现错误
可以在myeclipse 直接把映射文件拖到核心配置文件里就可以了
<!--
引入映射配置文件 -->
<mapping resource="cn/itcast/entity/User.hbm.xml"
/>
实现添加操作
使用hibernate代码实现crud操作,步骤是固定
第一步 加载核心配置文件
第二步 创建sessionFactory
第三步 使用sessionFactory创建session
第四步 开启事务
第五步 写具体逻辑(crud)
第六步 提交事务
第七步 关闭资源
package cn.itcast.hibernate.test;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import cn.itcast.entity.User;
import cn.itcast.utils.HibernateUtils;
/**
实现hibernate的crud的操作
*/
public class TestDemo1 {
//实现添加操作
@Test
public void add() {
//加载核心配置文件
Configuration cfg = new Configuration();
cfg.configure();
//创建sessionFactory
SessionFactory sessionFactory = cfg.buildSessionFactory();
//打开session
Session session = sessionFactory.openSession();
//开启事务
Transaction tx = session.beginTransaction();
//写添加逻辑
//项数据库设置值
User user = new User();
user.setUsername("lucy");
user.setBirthday(new Date());
//调用session里面的方法 save方法,保存的意思
session.save(user);
//提交事务
tx.commit();
//关闭连接
session.close();
sessionFactory.close();
}
}
Hibernate的配置文件详解(hibernate.cfg.xml)
1、hibernate中加载核心配置文件
要求
- 位置:放到src下
- 名称:必须是hibernate.cfg.xml
配置三部分
- 配置数据库信息(必须的)
- 配置hibernate的相关信息(不是必须的)
- 配置引入的映射文件(如果有映射文件必须配置)
2、映射配置文件
位置和名称没有固定要求
核心API使用
Configuration类(管理Hibernate的配置信息)
Configuration 类负责管理 Hibernate 的配置信息。包括如下内容:
加载hibernate.properties 和 hibernate.cfg.xml
持久化类与数据表的映射关系(*.hbm.xml文件)
创建Configuration 的两种方式
属性文件(hibernate.properties):
Configuration cfg = new Configuration(); //手动加载hbm
Xml文件(hibernate.cfg.xml)
Configuration cfg = newConfiguration().configure();
在核心配置文件中引入映射配置文件
之前做法:
还有另外方式加载映射配置文件(了解)
SessionFactory接口(获取Session对象)
Configuration对象根据当前的配置信息生成SessionFactory对象
SessionFactory对象中保存了当前数据库配置信息和所有映射关系以及预定义的SQL语句
SessionFactory对象是线程安全的
SessionFactory还负责维护Hibernate的二级缓存
Configuration configuration = new Configuration().configure();
创建sessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
可以通过SessionFactory对象 获得Session对象
Session session = sessionFactory.openSession();
构造SessionFactory 很消耗资源,一般情况下一个应用只初始化一个
☆抽取HibernateUtils 用来提供Session对象
创建HibernateUtils
package cn.itcast.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 创建sessionFactory对象
*/
public class HibernateUtils {
static Configuration cfg = null;
static SessionFactory sessionFactory = null;
//静态代码块
static {
cfg = new Configuration();
cfg.configure();
//创建sessionFactory
sessionFactory = cfg.buildSessionFactory();
}
//提供得到Session的方法
public static Session getSession() {
Session session = sessionFactory.openSession();
return session;
}
}
使用工具类得到session对象
package cn.itcast.hibernate.test;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import cn.itcast.entity.User;
import cn.itcast.utils.HibernateUtils;
/**
* 实现hibernate的crud的操作
*/
public class TestDemo1 {
//实现添加操作
@Test
public void addTestSession() {
//根据工具类得到session对象
Session session = HibernateUtils.getSession();
//开启事务
Transaction tx = session.beginTransaction();
//写添加逻辑
User user = new User();
user.setUsername("jacktom");
user.setBirthday(new Date());
//调用session里面的方法 save方法
session.save(user);
//提交事务
tx.commit();
//关闭连接
session.close();
//sessionFactory不需要关闭了
// sessionFactory.close();
}
}
Session接口(CRUD操作)
调用Session里面的方法,实现crud操作
Session是单线程对象,只能有一个操作时候,不能同时多个操作使用,不要把Session变量定义成成员变量,每次使用都创建新对象,相当于JDBC的Connection
Session是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心;Session是线程不安全的
所有持久化对象必须在session 的管理下才可以进行持久化操作
Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久化操作的数据都缓存在 session 对象处
持久化类与 Session 关联起来后就具有了持久化的能力
常用方法
方法 | 作用 |
---|---|
save()/persist() 、update() 、saveOrUpdate() | 增加和修改对象 |
delete() | 删除对象 |
get()/load() | 根据主键查询 |
createQuery()、createSQLQuery() | 数据库操作对象 |
createCriteria | 条件查询 |
Transaction接口(事务)
代表数据库操作的事务对象
Transactiontransaction = session.beginTransaction();
提供事务管理的方法
commit():提交相关联的session实例
rollback():撤销事务操作
wasCommitted():检查事务是否提交
回顾:
什么是事务
两个操作:提交和回滚
事务特性:原子性、一致性、隔离性、持久性
不考虑隔离性产生问题:脏读、不可重复读、虚读
在jdbc中,使用jdbc代码实现添加操作,默认事务自动提交
在hibernate中,事务默认不是自动提交的,需要手动配置,手动代码提交
如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务
让hibernate事务提交有两种:
第一种: 通过配置方式设置hibernate是自动提交
产生问题:第一个save方法添加数据,但是添加之后出现异常,第二个添加不能完成
第二种:手动代码方式控制事务
package cn.itcast.hibernate.test;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import cn.itcast.entity.User;
import cn.itcast.utils.HibernateUtils;
/**
*实现hibernate的crud的操作
*
*/
public class TestDemo1 {
//事务操作
@Test
public void testTx() {
//根据工具类得到session对象
Session session = null;
//开启事务
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//实现两次添加操作
//写添加逻辑
User user = new User();
user.setUsername("jacktom");
user.setBirthday(new Date());
//调用session里面的方法 save方法
session.save(user);
//发生异常
int a = 1/0;
User user1 = new User();
user1.setUsername("lilei");
user1.setBirthday(new Date());
//调用session里面的方法 save方法
session.save(user1);
//提交
tx.commit();
}catch(Exceptione) {
e.printStackTrace();
//回滚
tx.rollback();
}finally {
//关闭session
session.close();
}
}
}
Query接口(HQL语句查询操作)
Query代表面向对象的一个Hibernate查询操作
session.createQuery 接受一个HQL语句
HQL是Hibernate Query Language缩写,语法很像SQL语法,但是完全面向对象的
使用Query对象步骤
获得Hibernate Session对象
编写HQL语句
调用session.createQuery 创建查询对象
如果HQL语句包含参数,则调用Query的setXXX设置参数
调用Query对象的list() 或uniqueResult() 方法执行查询
Query还包含两个方法 用于控制返回结果
setFirstResult(intfirstResult) 设置返回结果从第几条开始
setMaxResults(intmaxResults) 设置本次返回结果记录条数
实现查询的操作
Query query = session.createQuery(“hql语句”)
query.list(); 返回集合
package cn.itcast.hibernate.test;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import cn.itcast.entity.User;
import cn.itcast.utils.HibernateUtils;
/**
* 实现hibernate的crud的操作
*/
public class TestDemo1 {
//query使用
@Test
public void testQuery() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//查询表中所有的记录
//hql语句 User是实体类的名称
Query query = session.createQuery("from User");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
}
Hibernate实现crud操作(重点)
功能具体介绍
(1)添加操作save
调用Session里的save(实体类对象),不需要设置对象的id值
User user = new User();
user.setUsername("jackTom");
user.setBirthday(new Date());
session.save(user);//调用Session里的save方法
(2)根据主键查询操作
调用Session里面的get方法
get方法里面有两个参数:
参数 | 值 |
---|---|
参数一 | 返回实体类的Class |
参数二 | id值 |
User user = (User)session.get(User.class, 1);//调用Session里面的get方法
(3)修改操作update
调用session里面的方法update方法
update方法里面传递参数有一个:
修改之后的值,封装到实体类对象,这个对象中必须有id值
做修改操作时候实现的步骤: 首先 根据id把原始信息查询出来 其次,设置要修改的值 最后,调用update方法实现
User user = new User();
user.setId(2);
user.setUsername("东方不败");
session.update(user);
做修改操作时候实现的步骤:
首先 根据id把原始信息查询出来
其次,设置要修改的值
最后,调用update方法实现
//修改:根据id修改
//修改id=1的username,修改为其他值
//根据id查询出来对象
User user = (User)session.get(User.class, 1);
//设置对象中,要修改的值
user.setUsername("大腹便便");
//调用update方法实现
session.update(user);
(4)删除操作delete
调用session里面的方法 delete方法
Delete方法中传递一个参数: 实体类对象,对象中至少要有一个id值
实现方式有两种
第一种 先查询出来对象,再调用delete方法删除
//删除id是4的记录
//查询id是4的记录
User user = (User)session.get(User.class, 4);
//调用delete方法
session.delete(user)
第二种 创建对象,设置id值,再调用delete方法删除
//删除id是3的记录
//创建对象
User user = new User();
//设置id值
user.setId(3);
//调用delete方法删除
session.delete(user);
(5)查询操作(3种)hql sql qbc
查询表中所有记录
第一种 使用hql查询
//创建query对象
Query query = session.createQuery("from User");
//调用query里面list方法返回list集合
List<User> list = query.list();
for(User user : list){
System.out.println(user);
}
第二种 使用本地sql查询(会用)
//创建对象
SQLQuery query = session.createSQLQuery("select * from user");
//调用query里面的方法
//返回list集合,每部分不是对象形式,而是数据形式
List<Object[]> list = query.list();
for(Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
crud代码演示:
package cn.itcast.hibernate.test;
import java.util.Arrays;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.itcast.entity.User;
import cn.itcast.utils.HibernateUtils;
/**
* 实现hibernate的crud的操作
*/
public class TestDemo2 {
//根据主键查询
@Test
public void testGet() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//调用session里面get方法
User user = (User) session.get(User.class, 1);
System.out.println(user);
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
//本地sql查询
@Test
public void testSQL() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//创建对象
SQLQuery query = session.createSQLQuery("select * from user");
//调用query里面的方法
//返回list里面,每部分不是对象形式,而是数组形式
List<Object[]> list = query.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
//hql语句查询 Query
@Test
public void testHQL() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//创建query对象
Query query = session.createQuery("from User");
//调用query里面list方法返回list集合
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
//第二种直接删除操作(不建议使用)
@Test
public void testDeleteDemo2() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//删除id是3的记录
//创建对象
User user = new User();
//设置id值
user.setId(2);
//调用delete方法删除
session.delete(user);
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
//第一种删除操作(先查询在删除方法)建议使用
@Test
public void testDeleteDemo1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//删除id是4的记录
//查询id是4的对象
User user = (User) session.get(User.class, 4);
//调用delete方法
session.delete(user);
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
//修改操作(先查询在修改)
@Test
public void testUpdateSuccess() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//修改:根据id修改
// 修改id=1的username,修改为 其他值
//根据id查询出来对象
User user = (User) session.get(User.class, 1);
//设置对象中,要修改成的值
user.setUsername("大腹便便");
//调用update方法实现
session.update(user);
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
//修改操作(直接修改)
@Test
public void testUpdate() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//修改:根据id修改
// 修改id=2的username,修改为 东方不败
//创建实体类对象
//操作实现修改,但是问题:
//调用update方法之后,把表里面所有字段都修改
//只是设置id和username值,根据id修改username和birthday
User user = new User();
user.setId(2);
user.setUsername("东方不败");
session.update(user);
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
}
}
}
基本数据类型和包装类使用
回顾:
Java中基本数据类型 有8个 byte short int long float double char boolean
对应的包装类:
int---Integer char---Character,其他是首字母大写
在实体类中使用基本数据类型还是使用包装类?
都是使用包装类。
考试成绩。
可以使用类型 int 和 包装类 Integer
一般都使用 包装类
表示 学生得分是 0 分
int score = 0;
Integer score = 0;
表示学生是否参加考试
int score = 0;
Integer score = null;
Hibernate的主键oid
什么是oid
在java中,区分不同的对象,根据对象的地址
在数据库中,区别不同的记录,根据主键id值
现在是实体类和数据库映射关系
在java中没有主键,在数据库里面没有地址
使用hibernate的OID区别不同的对象,如果OID相同的就是一个对象
自然主键和代理主键
自然主键:
Oid和业务相关的属性或者字段
比如人的身份证号码
代理主键:
Oid和业务不相关的属性和字段
比如写id
配置Hibernate的oid
<id name="id" column="ID">
<generator class="native"></generator>
</id>
使用id标签
有name属性 值写 实体类属性名称
Column属性值 写数据库表字段
在id标签里面使用 generator,配置oid
有class属性值 oid主键的生成策略
Hibernate的oid主键生成策略
Increment和identity
使用increment作为生成策略,生成建表语句中没有AUTO_INCREMENT自动增长
使用identity作为生成策略,生成的语句中 有AUTO_INCREMENT自动增长