Hibernate详解

项目文件jar包(Hibernate1.rar)
hibernate路线图
Hibernate 简介(优点和缺点)
Hibernate 入门案例(基于XML的操作方式)
Hibernate 配置文件详解(基于xml的方式)
Hibernate 常用api介绍 (事务,回顾脏读,不可重复读(行级,读更改),幻读(表级读新增)以及数据库隔离级别.并发事务的解决悲观锁和乐观锁机制)
使用Hibernate框架完成 CRUD 操作
Hibernate 的对应关系详解(使用注解的方式进行配置,摘取一对多进行代码数据示例操作)

1.Hibernate 简介

同样的hibernate框架是基于jdbc轻量级进行的封装在这里我们再次提到一下这个叫做ORM(面向对象进行数据结构的设计)

面向对象进行数据结构的设计和数据库表的设计有什么不同
hibernate讲究的是全自动对象映射,与mybatis不同,mybatis讲究的是半自动映射
最先本质是为了解决java程序员设计对象的问题,是java的开发人员不关心数据库设计和范式定律
随着业务场景的复杂以及追求可插拔的高度自由化,当然同时也是为了以后springBoot中使用JPA做铺垫,hibernate中我们除了在初次使用的时候使用XML配置后,hibernate的级联关系操作我们采取使用注解的方式进行操作
准确的来说hibernate有的东西,mybatis也有.

2.Hibernate 入门案例(基于XML的操作方式)
1.构建一个新的项目(引入的jar包)
在这里插入图片描述
2.分别编写实体和对应的映射文件person.clas 和 pserson_hbm.xml

public class Person {
		private  int  pid;
		private  String pname;
		private  Date   bir;
}
//------------映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">    
<hibernate-mapping>
     <!-- 映射哪一个实体类,以及表名 -->
       <class name="com.wwj.model.Person" table="person">
       		<!-- 主键的生成策略采用自增  name为对象的属性-->
            <id name="pid" column="pid">
                  <generator class="increment"></generator>
            </id>
            <property name="pname" column="pname"></property>
            <property name="bir" column="bir"></property>
       </class>
</hibernate-mapping> 

3.编写全局声明配置文件 src下 (log4j保持最先的一致)

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-
3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 方言 保证控制台输出效果一致-->
		<property name="dialect">
			org.hibernate.dialect.MySQLDialect</property>
			<!-- 数据库驱动jar包 -->
			<property name="connection.driver_class">
				com.mysql.jdbc.Driver</property>
				<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
				<property name="connection.username">root</property>
				<property name="connection.password">root</property>
				<!--显示sql语句是否格式化sql语句 -->
				<property name="hibernate.show_sql">true</property>
				<property name="hibernate.format_sql">true</property>
				<!--执行DDL的方式,create: 每一次运行都会覆盖原表中的内容 update: 保留原表中的内容 -->
				<property name="hibernate.hbm2ddl.auto">update</property>
				<!-- 将我们的对象和表的映射文件加载到主配置文件中 -->
				<mapping resource="com/wwj/model/Person_hbm.xml" />
	</session-factory>
</hibernate-configuration>

4.构建操作,对比mybatis执行流程动作

/**
 * 
 * @author wwj 
 * 1: 读取全局配置文件 
 * 2: 构建 sessionFactory 
 * 3: 创建 session(会话)
 * 4: 开启transcation
 * 5: 操作数据   (CRUD)
 * 6: 提交事务 transcation
 * 7: 关闭 session
 *
 */
public class TestHT {
	
	public static void main(String[] args) throws ParseException {
		//先处理下时间
		SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd");
		String format = sf1.format(new Date());
		Date parse = sf1.parse(format);
		// 读取配置文件,实例化 默认的寻找 名字为 hibernate.cfg.xml
		Configuration cfg = new Configuration().configure();
		// 构建 session 工厂
		SessionFactory sf = cfg.buildSessionFactory();
		// 创建 session
		Session session = sf.openSession();
		// 操作数据 (insert delete update) 手动开启事务
		Transaction bt = session.beginTransaction();
		// 操作数据  (注意这里的面向对象操作)
		Person per = new Person();
		per.setPname("张三");
		per.setBir(parse);
		// CRUD操作
		session.save(per);
		// 提交事务
		bt.commit();
		session.close();
	}
}

观察控制台的输出结果以及数据库表的结构
在这里插入图片描述
4. Hibernate常用api介绍
基本上大部分的框架都有一个叫做config的接口(使用xml解析填写的配置文件)
xxxFactory,万物皆有工厂造出来,不会平白无故的生成(工厂模式)
工厂虽然可以有很多,工厂很庞大,庞大就耗资源,所以我们才考虑对象的生成(单例模式)

(1)事务的ACID
原子性(Atomicity) 要么买要么就不买
一致性(Consistency)有买有卖,不能空仓打粮仓
隔离性(Isolation) 大家交易同一个物品的时候(互相又看不到)但是又不应该出现价格的相互影响(信息的壁垒)
持久性(Durability) 有迹可循,有记录

(2)事务并发
多个线程访问数据库同一条数据
脏读:一个事务读取到了另一个事务未提交的数据。
在这里插入图片描述
不可重复读(行级):一个事务范围内,两个相同的查询却得到了不同的结果。
在这里插入图片描述

幻读(表级):一个事务范围内,两个相同的查询却得到了不同的结果。
在这里插入图片描述
不可重复读发生点在一行上面,而幻读是发生在整张表上面

行级锁机制和表级锁都等同于操作上面仅且只有一个事务

补充说明:通过数据所提供的隔离级别(由低到高)

ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
ISOLATION_REPEATABLE_READ:这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION_SERIALIZABLE:这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
重点说明 (Hibernate操作数据都是先查在操作)

悲观锁机制:也就是同步执行,一个一个来 查询语句加上for update
乐观锁: 使用版本号的机制
大家先查,看到的版本默认为1
做增加删除修改的时候在版本号上面加1 帅选条件要根据当前版本号 最后提交总有先后
有一个操作一定会发生异常,通过捕获异常来进行下一步的处理

5.使用 Hibernate 框架完成 CRUD 操作

public class TestHT {
	
	public static void main(String[] args) throws ParseException {
		//先处理下时间
		SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd");
		String format = sf1.format(new Date());
		Date parse = sf1.parse(format);
		// 读取配置文件,实例化 默认的寻找 名字为 hibernate.cfg.xml
		Configuration cfg = new Configuration().configure();
		// 构建 session 工厂
		SessionFactory sf = cfg.buildSessionFactory();
		// 创建 session
		Session session = sf.openSession();
		// 操作数据 (insert delete update) 手动开启事务
		Transaction bt = session.beginTransaction();
		// 操作数据
		Person per = new Person();
		per.setPname("张三");
		per.setBir(parse);
		// CRUD操作
		// --1 .增加
		session.save(per);
		// --2 .查询 (如果查询多个,需要用到hql语句)
		Person p = (Person) session.get(Person.class, 1);
		// --3. 修改需要先查
		p.setPname("小李");
		session.update(p);
		// -- 删除
		session.delete(p);
		// -- 查询所有
		Query createQuery = session.createQuery("from Person");
		List<Person> list = createQuery.list();
		for(Person pp:list) {
		System.out.println(pp.getPname());
		}
		// 提交事务
		bt.commit();
		session.close();
	}

6.Hibernate的对应关系详解 (采用注解的方式)
1.一对一双向注解
Dad类

package com.wwj.onetoone;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Dad {
		@Id
		@GeneratedValue
		private int did;
		private String dadName;
		
		@OneToOne(cascade = CascadeType.ALL)
		@JoinColumn(name="sonId",unique=true)
		private Son son;
		public int getDid() {
			return did;
		}
		
		public void setDid(int did) {
			this.did = did;
		}
		public String getDadName() {
			return dadName;
		}
		public void setDadName(String dadName) {
			this.dadName = dadName;
		}
		public Son getSon() {
			return son;
		}
		public void setSon(Son son) {
			this.son = son;
		}
		
}

Son类

package com.wwj.onetoone;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

@Entity
public class Son {
	@Id
	@GeneratedValue
	private  int sid;
	private  String sname;
	
	@OneToOne(mappedBy="son")
	private  Dad  dad;
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public Dad getDad() {
		return dad;
	}
	public void setDad(Dad dad) {
		this.dad = dad;
	}
	
}

2.一对多双向注解
Dad类

package com.wwj.onetomany;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;



@Entity
public class Dad {
		@Id
		@GeneratedValue
		private int did;
		private String dadName;
		
		@OneToMany(cascade=CascadeType.ALL,mappedBy="dad")
		private List<Son> sons;
		public int getDid() {
			return did;
		}
		
		public void setDid(int did) {
			this.did = did;
		}
		public String getDadName() {
			return dadName;
		}
		public void setDadName(String dadName) {
			this.dadName = dadName;
		}

		public List<Son> getSons() {
			return sons;
		}

		public void setSons(List<Son> sons) {
			this.sons = sons;
		}
      
		
}

Son类

package com.wwj.onetomany;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

@Entity
public class Son {
	@Id
	@GeneratedValue
	private  int sid;
	private  String sname;
	
	@ManyToOne
	@JoinColumn(name="dadId")
	private  Dad  dad;
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public Dad getDad() {
		return dad;
	}
	public void setDad(Dad dad) {
		this.dad = dad;
	}
	
}

3.多对多双向注解

Dad类

package com.wwj.manytomany;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;



@Entity
public class Dad {
		@Id
		@GeneratedValue
		private int did;
		private String dadName;
		
		@ManyToMany(cascade = {CascadeType.ALL})
		@JoinTable(name="dad_son",
		joinColumns={@JoinColumn(name="did")},
		inverseJoinColumns={@JoinColumn(name="sid")})
		private List<Son> sons = new ArrayList<>();
		public int getDid() {
			return did;
		}
		
		public void setDid(int did) {
			this.did = did;
		}
		public String getDadName() {
			return dadName;
		}
		public void setDadName(String dadName) {
			this.dadName = dadName;
		}

		public List<Son> getSons() {
			return sons;
		}

		public void setSons(List<Son> sons) {
			this.sons = sons;
		}
      
		
}

son类

package com.wwj.manytomany;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

@Entity
public class Son {
	@Id
	@GeneratedValue
	private  int sid;
	private  String sname;
	
	@ManyToMany
	@JoinTable(name="dad_son",
	joinColumns={@JoinColumn(name="sid")},
	inverseJoinColumns={@JoinColumn(name="did")})
	private  List<Dad>  dads;
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public List<Dad> getDads() {
		return dads;
	}
	public void setDads(List<Dad> dads) {
		this.dads = dads;
	}
	
	
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值