@ORM框架
对象关系映射,用于实现面向对象编程语言里不同系统的数据之间的转换
@实例
public void demo01(){
User user = new User();
user.setUsername("haha");
user.setPassword("123");
//加载配置文件获得核心配置对象
Configuration config = new Configuration().configure("配置文件");
//获得工厂SessionFactory,相当于连接池
SessionFactory factory = config.buildSessionFactory();
//获得回话session,相当于链接Connection
Session session = factory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
//操作
session.save(user);
//提交事务 | 回滚事务
transaction.commit();
//释放资源
session.close();
//关闭工厂
factory.close();
}
PO:persistent object ,用于与数据库交互数据
BO:Business object 业务数据对象
VO: value Object 值对象
@Configuration配置对象
1:提供构造 new Configuration() hibernate 将自动加载hibernate.properties
2:提供方法 configure() 将加载src下的hibernate.cfg.xml
3:扩展api configure(String) 加载执行目录下的xml文件
4:手动加载配置文件
//手动加载指定的配置文件
config.addResource("com/shikun/hello/User.hbm.xml");
//手动加载指定类,对应的映射文件
config.addUser(user.class);
@SessionFactory工厂
1:SessionFactory相当于java web连接池,用于管理所有session
2:获得方式:config.buildSessionFactory();
3:sessionFactory hibernate缓存配置信息(数据库配置信息,映射文件)
4:SessionFactory线程安全,可以是成员变量,多个线程同时访问
5://打开一个新的回话 session
factory.openSession();
//获得当前线程中绑定的会话session
factory.getCurrentSession();
6:hibernate支持,将创建session绑定到本地线程中,底层使用ThreadLoacl,在程序之 间共享session
1:必须在hibernate.cfg.xml配置
<property name="hibernate.current_session_context_class">thread</property>
2:如果提交或回滚事务,底层将自顶关闭session
@Session会话
1:Session相当于JDBC的Connection会话
2:session单线程,线程不安全,不能编写成员变量
3:session api
1:save 保存 2:update 更新 3:delete:删除
4:get:通过id查询,如果没有 null
5:load 通过id查询,如果没有跑异常
6:createQuery("hql") 获得Query对象
7:createCriteria(class) 会的Criteria对象
@Transaction事务
1:开启事务 beginTransaction()
2:获得事务 getTransaction()
3:提交事务 commit()
4:回滚事务 rollback()
@Query对象
1:hibernate执行hql语句
2:hql语句:hibernate提供面向对象查询语句,使用对象和属性进行查询
3:获得session.createQuery("hql");
4:方法:
list() 查询所有
uniqueResult():获得一个结果,如果没有查询到返回null,如果查询多条抛异常
setFirstResult(int) 分页,开始索引数startIndex
setMaxResult(int) 分页,每页显示个数 pageSize
@Criteria对象
1:QBC(query by criteria),hibernate提供春面向对象查询语言
2:获得方式:Criteria criteria = session.createCriteria(User.class);
3:eq :等于 gt:大于 ge:大于等于 lt:小于 le:小于等于 like:模糊查询
@hibernate基本配置
<property name="hibernate.connection.driver_class>com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
//与本地线程绑定
<property name="hibernate.current_session_context_class">thread</property>
//方言:不同的数据库,生成sql语句提供依据
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Diaelct</property>
//sql语句
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
//表生成策略
<property name="hibernate.hbm2ddl.auto">create</property>
//验证
<property name="javax.persistence.validation.mode">none</property>
//添加映射文件
<mapping resource="com/shikun/hello/User.hbm.xml"/>
@hibernate中持久化类
1:持久化对象的唯一标识OID
1:javaan地址区分同一个类的不同对象
2:关系数据库用主键区分同一条记录
3:Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系
4:对象的OID和数据库的标的主键对应,由hibernate来为OID赋值
2:区分自然主键和代理主键
主键需要具备:不为空,不能重复,不能改变
1:自然主键:在业务中,某个属性符合主键的三个要求,该属性可以作为主键列
2:代理主键:在业务中,不存符合以上三个条件的属性,就增加一个没有意义的列 作主键
3:基本数据与包装类型
1:基本类型无法表达null,默认为0
2:包装类默认值是null
@主键生成策略
<id>配置主键,name:属性名称 access=““ 设置使用属性还是字段
column=”“ 表的列名 length=“” 长度 type=“” 类型
<generator>class 属性用于设置主键生成策略
1:increment 由hibernate自己维护自动增长
2:identity hibernate磁层采用数据库本身自动增长列
3:sequence hibernate底层采用数据库序列
4:Hilo
5:native:根据底层数据库的能力选择 identity,sequence或者Hilo中的一个
6:uuid 采用字符串唯一值,代理主键,由hibernate维护
7:assigned 自然主键,由程序自己维护
@对象状态
hibernate规定三种状态:瞬时态,持久态,脱管态
1:瞬时态:transient,session没有缓存对象,数据库也没有对应记录,OID没有值
2:持久态:persistent,session缓存对象,数据库最终会有记录 OID特点:有值
3:脱管态:detached,session没有缓存对象,数据库有记录 OID有值
4:状态转换
1:瞬时态转换持久态 一般操作:save方法,saveOrUpdate
2:瞬时态转换脱管态 一般操作:通过setId方法设置数据
@一级缓存
1:又称为session级别的缓存,当获得一次会话session,hibernate在session中创建多 个集合map,用于存放操作数据po对象,为程序优化服务,如果之后需要相应的数据,
hibernate优先从session缓存中获取,如果有就使用;如果没有在查询数据库。当session关闭时,一级缓存销毁
2:清除缓存
session.evict(对象);
3:快照:与一级缓存一样的存放位置,对一级缓存数据备份,保证数据库的数据与一级 缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一集缓存,执行update语句,将一级缓存的数据更新到数据库
4:refresh 刷新:保证一级缓存的数据与数据库的数据保证一致将执行select语句查询数据库,将一级缓存中的数据覆盖掉,只要执行refresh都将执行select语句
@PO对象操作
1save&persist
save方法:瞬时态转换持久态,会初始化OID
1:执行save方法,立即触发insert语句,从数据库获得主键的值OID值
2:执行save方法前,设置OID将忽略
3:如果执行查询,session缓存移除了,在执行save方法,将执行insert
4:persist方法不会立即得到ID,所以执行sql语句的时机要靠后
2:update :脱管态 转换 持久态
1:如果OID在数据存放的,将执行update语句
2:如果OID不存在将抛异常
3:saveOrUpdate:判断是否有OID
代理主键:
1:如果没有OID,将执行insert语句
2:如果有OID,将执行update语句
自然主键:
1:先执行select语句,查询是否存放
2:如果不存在,将执行insert
3:如果存在,将执行update
@多表设计
一对多:主表必须主键和从表必须外键,主表的主键与从表外键形成主外键关系
多对多:提供中间表,提供2个字段(外键)分别对应两个主表
@关联关系映射
1:一对多实现:一个客户,拥有多个订单
private Set<Order> orderSet = new HashSet<Order>();
配置文件
1:确定容器 set<set>
2: name确定对象属性名
3:确定从表外键的名称
4:确定关系,及另一个对象的类型
注意:在hibernate中可以只进行单项配置,每一个配置项都可以完整的描述彼此关系,一般情况采用双向配置,双方都可以完成描述表与表之间关系
<set name="orderSet" cascade="delete-orphan">
<key column="customer_id"></key>
<one-to-many class="com.shikun.Order"/>
</set>
多对一:多个订单属于一个客户
private Customer customer;
配置文件
1:name 确定属性名称
2:class 确定自定义类型
3:column 确定从表的外键名称
<many-to-one name="custoemr" class="com.shikun.Customer" column="customer_id"></many-to-one>
2:双向关联,使用inverse
<set name="orderSet" inverset="true">
<key column="customer_id"></key>
<one-to-many class="com.shikun.Order"/>
</set>
3:级联操作
1:save-update 级联保存或更新
<set name="orderSet" cascade="save-update">
</set>
2:delete 级联删除
<set name="orderSet" cascade="delete">
</set>
3:孤儿删除:一对多关系,存在父子关系,主表可以成为父表多表也可以成为子表
客户和订单接触关系后,外键被设置成null,此时订单就是孤儿,两者单独存在 孤儿删除,当订单称为孤儿,一并删除,客户仍存在
主表不能删除,从表已经引用(关联)的数据
从表不能添加,主表不存在的数据
<set name="orderSet" cascade="delete-orphan">
</set>
4:多对多映射
配置多对多关联映射
Course.hbm.xml
<set name="students" table="stu_cour">
<key column="cno"/>
<many-to-many class="com.shikun.Student" column="sno"/>
</set>
Student.hbm.xml
<set name="course" table="stu_cour">
<key column="sno"/>
<many-to-many class="com.shikun.Course" column="cno"/>
</set>
@抓取策略
1:检索方法
a:立即检索:立即查询,在执行查询语句时,立即查询所有的数据
b:延迟检索:延迟查询,在执行查询语句之后,在需要时在查询(懒加载)
2:检索策略
a:类级别检索:当前的类的属性获取是否需要延迟
b:关联级别的检索:当前类关联另一个类是否需要延迟
3:类级别检索
a:get :立即检索,get方法一执行,立即查询所有字段的数据
b:load:延迟检索,默认情况,load方法执行后,如果只使用OID的值不进行查询
如果要使用其他属性值将lazy默认值TRUE,为FALSE,表示立即检索
4:关联级别检索
a:一对多或多对多
1:容器<set>提供两个属性:fetch,lazy
fetch:确定使用sql格式
lazy:关联对象是否延迟
2:fetch:join,select,subselect
join:底层使用迫切左外链接,lazy无效
select:使用多个select语句
subselect:使用子查询
3:lazy:FALSE,true,extra
false:立即
TRUE:延迟
extra:极其懒惰
b:多对一:<many-to-one fetch="" lazy="">
1:fetch:取值:join,select
join:底层使用迫切左外链接
select:多条select语句
2:lazy取值:FALSE,proxy,no-proxy,no-proxy
FALSE:立即
proxy:采用关联对象,类级别检索的策略
5:批量查询
1:批量查询使用in语句减少查询语句的个数
select * from order where customer in(?,?,?,?,?)
2:<set batch-size="5">:5表示括号中?个数
@HQL:Hibernate Query Language 描写对象操作一种查询语句,查询的是对象的属性
1:查询所有客户
1:使用简单类名,存在自动导包
session.createQuery("from 简单类名");
2:使用全限定类名
session.createQuery("from com.shikun.简单类名");
2:选择查询
1:指定数据,cid,OID民称
2:使用id
3:对象别名
4:查询所有项
3:投影查询
1:默认
a:单列使用List<object>
b:多列需要List<Object[]>
4:order by asc|desc
5:分页
startIndex = (pageNum -1 )* pageSize
//pageNum 当前页
query.setFirstResult();
//pageSize:每页显示个数
query.setMaxResults()
6:绑定参数
1:setXxx(int,object)
2:setXxx(String,object)
3:setParameter(int|string,object)
7:聚合函数和分组
1:count(*|别名|oid)
8:连接查询
1.交叉连接 ,等效 sql 笛卡尔积
2.隐式内连接,等效 sql 隐式内连接
3.内连接,等效sql内连接
4.迫切内连接,hibernate底层使用 内连接。
5.左外连接,等效sql左外连接:底层是使用sql的左外链接,hibernate进行数据 自动封装,将一条记录封装给两个对象
6.迫切左外连接,hibernate底层使用 左外连接 left outer join fetch ,底层使用sql的左外链接,hibernate将一条记录封装给一个对象,将另一条数据封装给另一个对象,并将对象2关联到对象1,默认查询的数据重复
去重复
select distinct c from Customer left outer join fetch c.orderSet
7.右外连接,等效sql右外连接
9:命名查询
全局:session。getNamedQuery("queryName");
局部:session.getNamedQuery("className.queryName"); 需要使用类的全限定名称
@QBC
1:QBC查询:Query By Criteria 条件查询,面向对象的查询的方式
2:QBC简单的查询:session.createCriteria(Customer.class);
3: QBC分页的查询:
criteria.setFirstResult(10);
criteria.setMaxResults(10);
4:QBC排序查询:
criteria.addOrder(org.hibernate.criterion.Order.asc(""));
5:QBC条件查询
criteria.add(Restrictions.eq("属性","值"));
//模糊查询
criteria.add(Restrictions.like("属性","条件"));
6:离线查询:DetachedCriteria 离线查询对象,不需要session,在web
或service层拼凑,将此对象传递给dao层
DetachedCriteria detachedCtiteria = DetachedCriteria.forClass(Customer.class);
@整合c3p0连接池
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProcider</property>
@事务
悲观锁:丢失更新发生,采用数据库锁机制
读锁:共享锁 select ... from ... lock in share mode;
写锁:排它锁 select ... from ... for update
session.get(Customer.class,1,LockMode.UPGRADE);
乐观锁:丢失更新肯定不会发生,在po对象|表中提供一个字段,一般Integer在hbm.xml文件配置<version name="...">,用于表示记录,如果版本不一致,不允许操作
@二级缓存:降低应用程序直接读写硬盘的频率
1:hibernate提供缓存机制:一级缓存,二级缓存
一级缓存:session级别缓存,在一次请求中共享数据
二级缓存:sessionFactory级别缓存,整个应用程序共享一个会话工厂
2:SessionFactory的缓存两部分:内置缓存:使用一个Map,用于存放配置信息,预 定义HQL语句,提供给Hibernate框架自己使用,对外只读的,不能操作 ; 外置缓存:使用另一个Map,用于存放用户自定义数据,默认不开启,外置缓存hibernate只提供规范,需要第三方实现类,外置缓存又称为二级缓存
3:二级缓存内部结构
由四部分组成:类级别缓存,集合级别缓存,时间戳缓存,查询缓存
4:并发访问策略
1:transactional:事务型
2:read-write:读写型
3:nonstrict-read-write:非严格读写型
4:read-only:只读型
5:二级缓存提供商
EHCache: 可作为进程(单机)范围内的缓存,存放数据的物理介质可以是内存或硬盘, 对 Hibernate 的查询缓存提供了支持。--支持集群。
?OpenSymphony `:可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持
?SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存
?JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存
6:开启二级缓存
<property name="hibernate.cache.user_second_level_cache">true</property>
确定提供商
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
确定缓存内容
<class-cache usage="read-write" class=""/>
//集合缓存
<collection-cache usage="read-write" collertion=""/>
7;类缓存:只存放数据 一级缓存:存放对象本身
8:集合缓存:只存放关联对象OID的值,集合操作,将从集合缓存获得内容,此时只 能获得OID的值,然后从类缓存查询指定对象
9:时间戳:任何操作都在时间戳中记录操作时间,如果不一致,将触发select语句 10:查询缓存:又称为三级缓存,将HQL语句与查询结果进行绑定,通过HQL相同语句可以缓存内容,默认情况Query对象枝江查询结果存放在一级和二级缓存,查询缓存就是让Query可以从二级缓存获得内容
1:开启查询缓存
<property name="hibernate.cache.use_query_cache">true</property>
2:在查询query对象,设置缓存内容
Query q = s.createQuery("from student");
q.setCacheable(true);
原文:https://blog.csdn.net/github_37473774/article/details/71211299