Hibernate框架
特点:
全自动持久层框架(不需要sql就可以对数据库增删改查’CRUD‘)
学习成本高
Hibernate简介
1.一个开源免费的实现了ORM思想的持久层框架
2.可以使用实体类通过注解或xml方式来建立表的映射,自动生成对应的增删改查SQL
Hibernate 执行流程
Hibernate的使用
1.导入依赖包
2.编写配置文件
Hibernate建立映射关系
1.hibernate.cfg.xml中
<!--生成映射关系的类-->
<mapping class="com.seecen.fsd.ssh.model.User"/>
2.执行方法
@Test
public void createTable() {
/**
* 读取hibernate配置文件
* 创建Metadata
* 根据Metadata创建或更新表结构
*/
StandardServiceRegistryBuilder builder =
new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml");
Metadata metadata = new MetadataSources(builder.build()).buildMetadata();
new SchemaExport((MetadataImplementor) metadata).create(true, true);
}
映射类的一些注解意思
@Entity 实体类
@Table name 表名
@Id 主键
@Column 列
Name 数据库字段名
Length 字段长度
Nullable 是否可以为空
Unique 是否唯一
Insertable 是否包含在插入sql中
Updateable 是否包含在更新sql中
ColumnDefinition 检查约束默认值
@Transient 失效(建表、查询插入等不包含该字段)
@Temporal 指定时间精度
TemporalType.DATA 年月日
TemporalType.TIME 时分秒
TemporalType.TIMESTAMP 年月日时分秒
主键自增(写在属性上面)
package com.seecen.model;
import javax.persistence.*;
import java.util.Date;
/**
* hibernate通过实体+注解来建立表的映射关系
*/
@Entity
@Table(name = "t_ssh_user")
public class User {
private Integer userId;
private String userName;
private String userPsw;
private Double sal;
private Date createTime;
private Date updateTime;
private String deptName;
public User() {
}
public User(Long userId, String userName) {
this.userId = userId.intValue();
this.userName = userName;
}
public User(Integer userId, String userName) {
this.userId = userId;
this.userName = userName;
}
//失效
@Transient
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Id//主键
@Column(name = "user_id")
//自增
//增加定义序列的注解
//增加指定自增规则的注解
@SequenceGenerator(name = "gen",
sequenceName = "seq_user",initialValue = 8, allocationSize = 1)
@GeneratedValue(generator = "gen",strategy = GenerationType.SEQUENCE)
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
@Column(name = "user_name",nullable = false,unique = true)
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
//inserttable是否出现在插入sql中
@Column(name = "user_psw",length = 4000,insertable = false,updatable = false)
public String getUserPsw() {
return userPsw;
}
public void setUserPsw(String userPsw) {
this.userPsw = userPsw;
}
@Column(name = "user_sal",
columnDefinition = "number(10,2) default '8.8'",
insertable = false)
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
@Temporal(TemporalType.TIMESTAMP)
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
Hibernate多表关联查询
一对一
学生和学生卡
@OneToOne
一对多
学生和班级
@OneToMany
多对多
学生和老师
@ManyToMany
延时加载
Fetch
FetchType.LAZY (延迟加载数据)
FetchType.EAGER (立马获取数据)
实体类的三个状态
临时状态:new的时候
持久状态: 开启session
游离状态: 关闭session
HQL(HIBERNATE QUERY LANGUAGE)
Hibernate的查询语言
Hql 是类似 sql语句的查询语言
SQL 结构化查询语言
HQL使用注意事项
- Hql 类似 SQL
- HQL中表名和字段名分别是类名和属性名
- HQL省略SELECT关键字
数据库事务的配置及使用
- 注解方法
a) 第一步:
b) 第二步:在需要开启事务的方法上面添加@Transactional注解
2.采用aop切面配置的方法
<!-- 事务管理 -->
1. <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy proxy-target-class="true" />
<aop:config expose-proxy="true">
<aop:pointcut id="allManagerMethod" expression="execution(* com.seecen.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
事务相关知识点
-
什么是数据库事务
数据库事务:保证数据库在并发操作的环境下保证业务数据安全性和正确性的一种机制
数据库事务必须服从四个原则(ACID):
原子性
一致性
隔离性
持久性
2.并发操作采生的问题
脏读 : 一个事务读取了另一个事务改写(update)但未提交的数据
不可重复读: 一个事务执行相同的查询两次或两次以上,但结果不一样
幻影读:一个事务执行查询,读取到了另一个事务插入的数据
3.隔离级别
读未提交
读已提交
重复读
序列
Oracle支持的三种隔离级别
读已提交
序列(串行模式)
只读
Spring框架中使用事务
设置隔离级别
隔离级别 |
含义 |
ISOLATION_DEFAULT |
使用后端数据库默认的隔离级别。 |
ISOLATION_READ_UNCOMMITTED |
允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。 |
ISOLATION_READ_COMMITTED |
允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。 |
ISOLATION_REPEATABLE_READ |
对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。 |
ISOLATION_SERIALIZABLE |
完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。 |
传递特性
REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。