1.简介
1)项目中框架的体系结构
2)ORM框架:对象关系映射(Object Relational Mapping),是一种程序技术,用于实现对象编程语言里不同类型系统的数据之间的转换。
3)Hibernate:是一个开放源代码的对象关系映射的框架,它对JDBC进行了非常轻量级的对象封装。
(1)它将POJO与数据库建立映射关系,是一个全自动的持久化层ORM框架。
(2)Hibernate可以自动生产SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思想来操纵数据库。
(3)Hibernate可以用在任何使用JDBC的场合,既可以在Java的客户端程序中使用,也可以在Servlet/JSP的web应用中使用。
4)主流的ORM框架
(1)JPA:Java Persistence API,通过JDK5.0注解或XML描述对象-关系表的映射关系(只有接口规范);
(2)MyBatis:
(3)DBUtils:
5)Hibernate的优点
(1)对JDBC访问数据库的代码做了封装,大大简化了数据访问繁琐的重复性代码
(2)Hibernate是一个基于JDBC的主流持久层框架,是一个优秀的ORM实现,很大程度上简化了DAO层的编码工作
(3)使用了Java的反射机制
(4)性能非常号,轻量级框架,映射的灵活性很出色,支持很多关系型数据库,有一对一,多对多的各种复杂关系映射。
2.Hibernate的简单使用
1)下载位置:http://hibernate.org/orm/
2)创建数据库表:
3)配置核心配置文件hibernate.cfg.xml,配置数据库连接信息
4)映射文件hibernate mapping(*.hbm.xml),声明对象如何关联数据库表字段
5)调用hibernate的API
3.使用IDEA创建Hibernate项目
1)创建数据库
create database hibernate_demo01;
use hibernate_demo01;
create table t_user(
id int auto_increment primary key,
username varchar(50),
password varchar(30)
);
2)使用IDEA创建Hibernate项目
(2)导入mysql相关jar包
3)创建实体类;
package com.dhy.hibernate.domain;
public class User {
private int uid;
private String username;
private String password;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4)配置hibernate.cfg.xml文件,及映射文件hibernate mapping(*.hbm.xml)关联数据库表字段
(1)配置hibernate.cfg.xml文件
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//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://localhost:3306/hibernate_demo01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- mysql的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 是否显示sql语句 -->
<property name="show_sql">true</property>
<!-- 是否格式化sql语句 -->
<property name="format_sql">true</property>
<!-- 是否自动提交事务,对于insert有效,对于delete无效,delete必须手动提交事务 -->
<property name="connection.autocommit">true</property>
<!-- 配置JavaBean与表的映射文件-->
<mapping resource="com/dhy/hibernate/domain/User.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
(2)配置映射文件User.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name:对应模型的全名称-->
<class name="com.dhy.hibernate.domain.User" table="t_user">
<!-- name:模型属性名;column:表字段名 -->
<id name="uid" column="id">
<!-- gengerator:id的生成策略,native是指id自增长 -->
<generator class="native"></generator>
</id>
<!-- 模型属性名与表字段名相同时,不用配置column属性-->
<property name="username"></property>
<property name="password"></property>
</class>
</hibernate-mapping>
5)测试
package com.dhy.hibernate.test;
import com.dhy.hibernate.domain.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class Test01 {
@Test
public void test01(){
//保存用户数据
//1.获取核心配置文件对象,默认是加载src的hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
//2.创建会话工厂
SessionFactory factory = cfg.buildSessionFactory();
//3.创建会话,相当于连接Connect
Session session = factory.openSession();
//开启事务
Transaction transaction = session.getTransaction();
transaction.begin();
//创建对象
User user = new User();
user.setUsername("dhy");
user.setPassword("123456");
session.save(user);
//提交事务
transaction.commit();
//关闭会话
session.close();
//关闭工厂,释放资源
factory.close();;
}
}
控制台显示:4.Hibernate相关解析
2)配置对象
(1)Hibernate的核心配置文件有多种样式:
hibernate.properties:用于配置key/value形式的内容,key不能重复,有局限性,一般不用。
(2)Configuration对象:
Configuration cfg = new Configuration().configure();
是用来加载配置文件的,new Configureation()构造方法加载的是hibernate.properties文件,comfigure()方法加载的是hibernate.cfg.xml文件。配置文件一般放在src目录下,同时configure(String url)可以指定文件路径。
加载映射文件方式:
<1>在配置文件中配置【常用方式】:
<!-- 配置JavaBean与表的映射文件-->
<mapping resource="com/dhy/hibernate/domain/User.hbm.xml"></mapping>
<2>在代码中添加映射文件:
//1.获取核心配置文件对象,默认是加载src的hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
//另外一种添加映射文件的方式
cfg.addResource("com/dhy/hibernate/domain/User.hbm.xml");
(3)SessionFactory工厂对象
<1>SessionFactory相当于java web 连接池,用于管理所有Session;
<2>获得SessionFactory方式:config.buildSessionFactory();
<3>还用于缓存配置信息;
(4)Session对象
<1>获取Session对象的方法:
①factory.openSession():创建一个全新的session对象;
②factory.getCurrentSession():同一线程中,session都是同一对象,使用该方法需要配置文件中开启,该方法不需要关闭session。
<!-- 开启与当前线程绑定session的功能-->
<property name="hibernate.current_session_context_class" >thread</property>
5.相关报错
1)报错SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
注意版本需要一样,否则会出现下面错误:
2)报错Duplicate class/entity mapping
原因:映射文件重复配置
3)报错:WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
原因:字符串中没有配置SSL这个配置项
解决方式:
6.session中的常用 方法
1)增加:
save(Object o):
//保存用户数据
//1.获取核心配置文件对象,默认是加载src的hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
/* //另外一种添加映射文件的方式
cfg.addResource("com/dhy/hibernate/domain/User.hbm.xml");*/
//2.创建会话工厂
SessionFactory factory = cfg.buildSessionFactory();
//3.创建会话,相当于连接Connect
Session session = factory.openSession();
//4.开启事务
Transaction transaction = session.getTransaction();
transaction.begin();
//创建对象
User user = new User();
user.setUsername("dhy");
user.setPassword("123456");
//5.保存对象
session.save(user);
//6.提交事务,配置文件中配置了autoCommit时候可以不用这一步
transaction.commit();
//transaction.rollback();//回滚,try……catch()……中
//7.释放资源
session.close();
factory.close();
2)删除:
delete(Object o):
//1.获取配置文件对象
Configuration configuration = new Configuration().configure();
//2.获取SessionFacory对象
SessionFactory factory = configuration.buildSessionFactory();
//3.获取会话Session对象
Session session = factory.openSession();
//4.开启事务
Transaction transaction =session.getTransaction();
transaction.begin();
//5.删除数据,先获取要删除的对象,然后删除
User user = (User)session.get(User.class,2);
session.delete(user);
//5.删除数据,主动创建对象,然后删除
/*User user = new User();
user.setUid(3);
session.delete(user);*/
//6.提交事务,无论在配置文件中是否配置了autoCommit,此处都需要提交事务
transaction.commit();
//7.关闭资源
session.close();
factory.close();
3)修改:
update(Object o):更新对象
saveOrUpdate(Object o):保存或更新对象,当对象不存在(对象的id不存在)的时候就做保存操作,否则做更新操作
//1.获取配置文件对象
Configuration configuration = new Configuration().configure();
//2.获取sessionFactory
SessionFactory factory = configuration.buildSessionFactory();
//3.获取连接对象
Session session = factory.openSession();
//4.开启事务
Transaction transaction = session.getTransaction();
transaction.begin();
/*//5.获取需要修改的对象信息
User user = (User)session.get(User.class,4);
user.setUsername("qq");*/
User user = new User();
user.setUid(4);
user.setUsername("QW");
/*//6.1 更新对象
session.update(user);*/
//6.2
session.saveOrUpdate(user);//首先判断User是否有id,有id就做update操作,否则做save操作
// 提交事务
transaction.commit();
//7.关闭资源
session.close();
factory.close();
4)查找:
get():获取对象(通过id),获取一个数据库不存在的数据时候,返回空
load():获取对象(通过id),获取一个数据库不存在的数据时候,报错
//1.获取配置文件对象
Configuration configuration = new Configuration().configure();
//2.获取SessionFacory对象
SessionFactory factory = configuration.buildSessionFactory();
//3.获取会话Session对象
Session session = factory.openSession();
/* //5.获取对象,get()获取对象,获取一个数据库不存在的数据时候,返回空
User user = (User)session.get(User.class,2);
User user2 = (User)session.get(User.class,6);
System.out.println(user.toString());*/
//5.获取对象,load()获取对象,获取一个数据库不存在的数据时候,报错
User user3 = (User)session.load(User.class,2);
User user4 = (User)session.load(User.class,6);
System.out.println(user3.toString());
//7.关闭资源
session.close();
factory.close();
7.get()与load()方法的区别
1)get()方法是直接加载数据库,在使用get()方法的时候就立即加载数据库;
2)load()方法是懒加载,只有用到时候才去查询数据库,方法返回的是对象的一个代理;也就是在使用load()方法的时候先创建一个代理对象(在缓存中查找,后面有介绍),当继续执行代码时候,用到了该对象的时候再进行数据库的加载。