Hibernate基本使用

Hibrenate框架
一、Hibrenate
1、是一个持久层框架,实现jdbc的封装。是一个全自动的ORM框架
2、ORM:对象 关系(数据库表) 映射,orm致力于将数据库操作转换成Java程序熟悉的对象操作。
3、ORM主要体现在两个方面
a、java程序通过jdbc与数据库程序交互;类似于 请求—响应
b、orm在请求时,由java程序向数据库传递sql时,通过操作的对象 对于操作表,通过操作的对象属性 对应 操作的表字段
c、orm在响应是,一般就是查询操作,且返回结果,将ResultSet集合中装载的查询组装成对应的实体对象;根据查询时指定的对象,组装成与之对应的对象;根据表字段与对象属性名对应的关系实现数据赋值
二:全自动与半自动
1、 全自动orm:
a) 在请求和响应过程中,都是用orm机制自动进行处理的
2、 半自动orm
a) 在请求过程中,操作对此与对应的表的关系,依然需要使用手动编写的sql实现
b) 在响应过程中,将查询结果自动组成对象

三:hibernate基本使用
1、创建maven程序
2、引入hibernate 和mysql依赖

 <dependency>
      <groupId>org.hibernategroupId>
      <artifactId>hibernate-coreartifactId>
      <version>5.1.4.Finalversion>
    dependency>
    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>5.1.29version>
    dependency>

3、创建hibernate.cfg.xml文件


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.Driverproperty>
    <property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01property>
    <property name="hibernate.connection.username">rootproperty>
    <property name="hibernate.connection.password">rootproperty>
    
    
    <property name="hibernate.show_sql">trueproperty>
    
    <property name="hibernate.format_sql">trueproperty>
    
    <property name="hibernate.hbm2ddl.auto">updateproperty>
    
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty>
 	
	<mapping resource="cn/itcast/entity/Car.hbm.xmL"/>

session-factory>
hibernate-configuration>

4、使用框架
4.1、创建实体类

package com.hibernate;

import javax.persistence.criteria.CriteriaBuilder;
import java.io.Serializable;

/**
 * @author pgg
 * @date 2022/4/6
 */
public class Car implements Serializable {
    private Integer cid;
    private String cname;
    private String color;

    public Car() {
    }

    public Car(Integer cid, String cname, String color) {
        this.cid = cid;
        this.cname = cname;
        this.color = color;
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

4.2、自定义orm配置文件


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.hibernate.Car" table="t_car">
        <id name="cid" column="cid">id>
        <property name="cname" column="cname"/>
        <property name="color" column="color"/>
    class>
 
hibernate-mapping>

4.3、编写dao,使用hibernate实现语句库的交互
4.3.1、hiberante有一个Session对象,该对象提供了CRUD方法
4.3.1.1、每一个session对象内置connection连接
4.3.1.2、session.save/update/delete/get()…
4.3.2、hibernate有一个sessionFactory对象,创建session对象:sessionFactory.openSession()
4.3.3、hibernate有一个Configuration对象,创建sessionFactory对象

第一步 加载hibernate核心配置文件

第二步 创建SessionFactory对象

第三步 使用SessionFactory创建session对象

第四步 开启事务

第五步 写具体逻辑 crud操作

第六步 提交事务

第七步 关闭资源

	@Test
	public void testAdd() {
//		第一步 加载hibernate核心配置文件
		// 到src下面找到名称是hibernate.cfg.xml
		//在hibernate里面封装对象
		Configuration cfg = new Configuration();
		cfg.configure();
		
//		第二步 创建SessionFactory对象
		//读取hibernate核心配置文件内容,创建sessionFactory
		//在过程中,根据映射关系,在配置数据库里面把表创建
		SessionFactory sessionFactory = cfg.buildSessionFactory();
		
//		第三步 使用SessionFactory创建session对象
		// 类似于连接
		Session session = sessionFactory.openSession();
		
//		第四步 开启事务
		Transaction tx = session.beginTransaction();

//		第五步 写具体逻辑 crud操作
		//添加功能
		User user = new User();
		user.setUsername("小王");
		user.setPassword("250");
		user.setAddress("日本");
		//调用session的方法实现添加
		session.save(user);
		
//		第六步 提交事务
		tx.commit();

//		第七步 关闭资源
		session.close();
		sessionFactory.close();
	}

四:hibernate操作对象状态
瞬时态:刚刚创建的对象属于瞬时态,在jvm中存在,在数据库和session对象中部存在
持久态:jvm中存在,数据库中存在,session缓存中存在,操作jvm中对象,就会通过session,自动更新数据库中的数据
save()、update() 是将瞬时态对象 转换成持久态
get() 直接获取一个持久态
注意:delete 删除的对象必须是持久态,删除后属于瞬时态
游离态:jvm中存在,数据库中存在,session缓存中不存在
session.close()、session.clear()

五:hibernate的crud
1、hiberante有一个Session对象,该对象提供了CRUD方法,其直接提供的方法只能实现但记录的CRUD

一:session提供的单条记录的查询

  1. session.get()/session.load()
  2. session.get(类名.class,id): 根据主键值,查找单条记录,通过类名.class对象类型,找到对应的orm,从而找到操作的表;id值即为orm配置时字段的值
    如:
package com.hibernate.dao;

import com.hibernate.domain.Car;
import com.hibernate.util.HibernateUtil;
import org.hibernate.Session;

public class CarDao {
    public void find1(){
        Session session= HibernateUtil.getSession();
        Car car=session.get(Car.class,1);
        System.out.println(car.getCname());
    }

    public void find2(){
        Session session=HibernateUtil.getSession();
        Car car=session.load(Car.class,1);
        System.out.println(car);
    }
}

六:get和load的特点
懒加载:懒加载不是不加载,只加载id主键,当需要使用数据再通过id去与数据库交互查询
相同点:都是根据主键查找单条记录
不同点:
get方法会从数据库直接获取数据对象,如果没有数据,返回null
load方法会先获得一个代理对象,再需要使用数据时再从数据库中获取数据(懒加载),如果数据不存在,则在获取时抛出异常
load方法查询时,默认是懒加载查询,可以通过设置,关闭懒加载(2中方式)
方式一:在orm文件中通过懒加载属性关闭

<hibernate-mapping>
    <class name="com.hibernate.domain.Car" table="t_car"  lazy="false">
        <id name="cid" column="cid"></id>
        <property name="cname" column="cname"/>
        <property name="color" column="color"/>
    </class>

</hibernate-mapping>

方式二:将实体类Car,使用final关键字修饰
load方法懒加载的体现是先获得代理,然后需要数据时代理再查数据;代理实现有两种方式:1、基于父类 2、实现接口 确保代理对象与目标实体对象有相同的api(方法),final修饰的类不能被继承,即不能产生代理,即关闭懒加载


public final class Car implements Serializable {
    private Integer cid;
    private String cname;
    private String color;

    public Car() {
    }
 }

关闭懒加载后,数据存在,直接获得数据对象,数据不存在,依然会抛出异常
七:hibernate增删改查操作
注意:增删改时需要开启事务,提交事务
1、保存:session.save(对象);

    /**
     * 保存
     */
    public void save1(){
        Car car=new Car(1,"bm3","蓝色");
        Session session=HibernateUtil.getSession();
        session.beginTransaction();//开始事务
        session.save(car);
        session.getTransaction().commit();//提交事务
    }

2、修改:session.update(对象);
扩展:对于持久态对象,修改对象就相当于修改数据,而不需要执行修改方法

	/**
	 *修改的方法
	 */
	public void update1(){
        Car car=new Car(1,"bm2","白色");
        Session session=HibernateUtil.getSession();
        session.beginTransaction();//开始事务
        session.update(car);
        session.getTransaction().commit();//提交事务

    }
    /**
     * 扩展修改的方法 只针对持久态对象
     */
    public void update(){
        Session session=HibernateUtil.getSession();
        Car car=session.get(Car.class,1);//持久态
        car.setColor("红色");
        session.beginTransaction();//开始事务
        session.getTransaction().commit();//提交事务
    }

3.删除:session.delete(对象);不能通过主键删除
尽管从删除逻辑而言,通过主键数据就可以删除整体记录,但Hibernate对数据库的操作都是一对象的操作体现的,所以删除时也必须删除对象(1、对象可以只包含主键 2、对象必须时持久态才能删除)


    /**
     * 方式一:删除操作
     */
    public void delete1(){
        Session session=HibernateUtil.getSession();
        Car car=new Car();
        car.setCid(1);
        session.beginTransaction();//开始事务
        session.delete(car);
        session.getTransaction().commit();//提交事务
    }

    /**
     * 方式二:删除操作
     */
    public void delete2(){
        Session session=HibernateUtil.getSession();
        Car car=new Car();
        car.setCid(1);
        session.beginTransaction();//开始事务
        session.delete(car);
        session.getTransaction().commit();//提交事务
    }

    /**
     * 方式三:删除操作
     */
    public void delete3() throws InterruptedException {
        Session session=HibernateUtil.getSession();
        Car car=new Car(1,"bmw","red");
        session.beginTransaction();//开始事务
        session.save(car);
        session.getTransaction().commit();//提交事务
        Thread.sleep(20000);
        session.beginTransaction();//开始事务
        session.delete(car);
        session.getTransaction().commit();//提交事务
    }

4、扩展:
保存或修改:session.saveOrUpdate(对象);先根据主键值做查询,数据存在执行修改,数据不存在,执行保存

/**
     * 保存或修改
     */
    public void saveOrUpdate1(){
        Session session=HibernateUtil.getSession();
        Car car=new Car(1,"bmw","blue");
        session.beginTransaction();//开始事务
        session.saveOrUpdate(car);
        session.getTransaction().commit();//提交事务
    }

5、扩展
保存或修改:session.merge(对象) ;先根据主键值做查询,数据存在执行修改,数据不存在,执行保存

/**
     * 保存或修改
     */
    public void merge(){
        Session session=HibernateUtil.getSession();
        Car car=new Car(1,"bmw","blue");
        session.beginTransaction();//开始事务
        session.merge(car);
        session.getTransaction().commit();//提交事务
    }

saveOrUpdate和merge区别:
1、区别体现再修改时,
2、无论哪个方法实现修改,都可以将瞬时态对象转换成持久态对象,如果再session缓存中,之前已经存在了一个相同的id的持久态对象,那么saveOrUpdate方法会抛出异常(有两个不同的对象却有相同的id),但是merge方法会修改成功,因为merge会将两个相同的对象数据合并
merge修改的对象并没有变成持久态,而是将对象的数据覆盖到原持久态对象中

扩展:保存时的主键生成机制
只需要在orm配置文件中,使用id的子标签《generator》标签指定生成机制
HIbernate提供了多种主键生成机制,常用的有:
1、uuid varchar主键 32位16进制唯一数
2、identity 一般时mysql等 int类型的主键 自增,需要在建表时也设置主键自增
3、sequence 是oracle int类型的主键,序列自增,因为Oracle的序列是一个独立的数据库对象,拥有自己的名字,所以在设置sequence序列生成机制时需要通过传递指定序列的名,如果没有传递,则默认使用hibernate_sequence名字的 序列
4、foregin 一对一关联时,有关联表外键值充当主键值
5、assigned 默认 手动提供主键值
6、native:使用当前数据库默认支持的主键生成方式,如果是mysql则相当于identity,如果是Oracle,则相当于是sequence


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.hibernate.domain.Book" table="t_book"  lazy="false">
        <id name="bno" column="bno">
        	 
            <generator class="uuid">generator>
        id>
        <property name="bname" column="bname"/>
        <property name="author" column="author"/>
    class>

hibernate-mapping>

注意:使用主键生成机制时,save方法执行保存后,会以返回值的形式将生成的主键返回

你可能感兴趣的:(#,HIbernate框架,hibernate)