什么是hibernate:hibernate是应用在dao层的框架技术。主要思想orm(对象关系映射);
一、hibernate环境配置:入门程序
1.导入jar包:必须的jar包
2.实体类:User类
实体类中的属性与数据库中表的字段一一对应。
package com.fxy.hibernate.enity;
public class User {
private int uid;
private String username;
private String password;
private String address;
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", address=" + address + "]";
}
}
3.配置文件:
a.配置映射文件
首先需要添加约束dtd,这个约束可以在下载的hibernate的jar包中找到,这里的映射文件的名称和位置没有固定要求。需要注意的点已经在下面代码中注释了。
<?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属性表示实体类的全限定名称,table表示表的名称 -->
<class name="com.fxy.hibernate.enity.User" table="t_user">
<!-- 设置字段uid为主键 -->
<id name="uid" column="uid">
<!-- 设置uid字段自增 -->
<generator class="native"></generator>
</id>
<!-- 配置其他属性与字段一一对应 -->
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="address" column="address"></property>
</class>
</hibernate-mapping>
b.hibernate核心配置文件:
引入约束
这里的核心配置文件的名称和位置是确定的,位置在src目录下,名称为hibernate.cfg.xml.
配置三种信息:
1.配置数据库信息,连接数据库。必须配置。
2.配置hibernate信息,可以不配置,但是一些功能可能无法起作用。
3.引入映射配置文件。必须配置
<?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.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_day01?useSSL=false&serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 配置hibernate的信息,可选 -->
<!-- 输出底层sql语言 ,可选-->
<property name="hibernate.show_sq">true</property>
<!-- 输出底层sql语言格式 化(换行),可选-->
<property name="hibernate.format_sql">true</property>
<!-- hibernate自动创建表需要配置,
update表示如果已经存在表就进行更新操作,没有表就创建
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置数据库的方言,每个数据库特有的语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 引入映射配置文件 -->
<mapping resource="com/fxy/hibernate/enity/user.hbm.xml"/>
</session-factory>
</hibernate-configuration>
4.测试文件:
a.加载hibernate核心配置文件:在创建Configuration对象时就将hibernate核心配置文件加载在Configuration对象中。
configuration cfg = new Configuration();
cfg.configure();
b.创建SessionFactory对象:在这个过程中,hibernate就会根据映射和核心配置文件自动创建表。
SessionFactory sf = cfg.buildSessionFactory();
c.创建Session对象,这里的Session对象和Servlet中的Session是不同的。这里的Session对象
Session session = sf.openSession();
d.开启事务:
Transaction tx = session.beginTransaction();
f.执行crud操作。在hibernate中我们不需要写SQL语句,都可以通过java代码实现crud操作。具体操作见后面内容。
g.提交事务:(这里就是简单的测试一样hibernate配置环境的过程。这里事务的操作不是很规范,如果在事务中存在异常,那么后面的代码就不会执行了。接下来会专门改进代码。)
tx.commit();
g.关闭资源
session.close();
sf.close();
二、hibernate api介绍:
1.Configuration:
该类对象的主要作用是到src中找到hibernate.cfg.xml文件,并将该文件加载到其对象中去。
2.SessionFactory:
由Configuration对象创建SessionFactory对象。在创建该对象的过程中,根据核心配置文件和映射文件。会为我们自动根据实体类创建好表。
因此该步骤十分消耗资源,所以一般我们将它封装到一个工具类中。
3.Session:
Session对象是一个单线程对象。只能自己使用,不能和别人共用。所以每需要Session,都需要创建一次Session对象。
因为代码书写不是一个人的活动,可能需要多个人。所以很难保证Session是单线程的。所以这里我们将Session与本地线程hibernate绑定,这样就能确保Session为单线程对象。
三、代码改进:
根据以上说明。我们将代码进行如下改进:
1.编写工具类,这里保证SessionFactory对象只生成一次。
public class HibernateUtil{
Configuration cf = null;
SessionFactory sessionFactory = null;
//为了保证SessioFactory对象只生成一次
static{
cf = new Configuration();
cf.configure();
sessionFactory = cf.buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
2.hibernate绑定Session.
a.修改核心配置文件:
<!-- 配置Session与hibernate绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
b.在工具类中获取session
public class HibernateUtil {
static Configuration cfg;
static SessionFactory sessionFactory;
static {
cfg = new Configuration();
cfg.configure();
sessionFactory = cfg.buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
//获取与hibernate绑定的Session对象
public static Session getSession() {
Session session = sessionFactory.getCurrentSession();
return session;
}
}
c.修改测试代码:
package com.fxy.hibernate.test;
import javax.xml.soap.Text;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.fx.hibernate.util.HibernateUtil;
import com.fxy.hibernate.enity.User;
public class HibernateTest {
Session session = null;
Transaction tx = null;
@Test
public void demo01() {
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
User user = session.get(User.class, 4);
System.out.println(user);
tx.commit();
}catch (Exception e) {
tx.rollback();
}finally {
//session.close();//与hibernate绑定的Session不需要手动关闭。不然会报异常。
}
}
}
四、对实体类进行crud操作
1.增加操作insert
User user= new User();
user.setUsername("");
user.setPassword("");
user.setAddress("");
session.save(user);
2.根据id查询
User user = session.get(User.class,id);
//重写User的toString()方法。
System.out.println(user);
3.根据id删除
User user = session.get(User.class,id);
session.delete(user);
4.根据id修改:
User user = session.get(User.class, 2);
user.setUsername("hfnu");
session.update(user);
五、一级缓存:
1.hibernate的一级缓存是默认打开的。
2.hibernate的一级缓存的作用范围为从session创建到session关闭。
3.hibernate的一级缓存存储的数据必须为持久态。
在这里介绍一下实体类的三种状态:
1.瞬时态:对象里没有Id值,对象与session没有关联
2.持久太:对象里有Id值,对象与session关联
3.托管太:对象里有id值,对象与session没有关联
4.hibernate二级缓存已经不用了,被redis取代。他的作用范围是sessionFactory的作用范围。且二级缓存是默认不打开的需要配置。
5.一级缓存的特性:持久态自动更新数据库。比如我们根据id值更改数据库。首先通过session.get()方法获得id值并返回对象,且和session关联。所以这个对象为持久态。这个时候我们通过set()方法进行更改后不执行update方法同样可以更新数据库。这个就是hibernate得一级缓存特性的一个应用。