Java hibernate框架知识总结

**ORM(Object Realtion Mapping)**对应关系映射。通过映射关系,能够将对象的数据存储到数据中,并且能从数据库中获取数据存储到一个对象中。

HIbernate与ORM的关系:Hibernate 是ORM的实现。Hibernate是一个数据持久化层的ORM框架。

HIbernate的优点:简化了JDBC繁琐的编码;对面向对象特性支持良好。可以执行好。

Hibernate的缺点:不适合需要使用数据库特定优化机制的情况。不适合大规模的批量数据处理。

使用Hibernate的简单步骤:下载并部署jar文件–>编写Hibernate配置文件–>创建持久化类和映射文件–>使用Hibernate API。

hibernate运行流程图:
在这里插入图片描述

hibernate各个包作用。

配置文件和映射文件:配置文件中需要配置四本一言。映射文件是数据库表和javaBean的映射。

相关概念

  • 用于操作数据库
  • hibernate可以用面向对象的方式操作数据库
  • ORM框架-将对象与表的关系使用配置文件映射

框架搭建

  1. 导包
    导入lib下的required下的包
  2. 准备实体&映射文件
    在实体所在包下新建映射文件(名称:类名.hbm.xml),导入dtd约束(在hibernate-mapping-3.0.dtd)
<hibernate-mapping>
    <class name="类名" table="表名">
        <!--配置主键-->
        <id name="主键对应的属性名" column="表的主键名" >
            <!--配置id生成策略-->
            <generator class="native"></generator>
        </id>
        <!--配置其他属性-->
        <property name="属性名" column="表的字段"></property>
    </class>
</hibernate-mapping>
  1. 准备主配置文件
    在src目录下,新建hibernate.cfg.xml主配置文件,导入dtd约束(在hibernate-configuration-3.0.dtd)
<session-factory>
    <!--5个必选项-->
    <proprrty name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <proprrty name="hibernate.connection.url">jdbc:mysql:///test</property>
    <proprrty name="hibernate.connection.username">root</property>
    <proprrty name="hibernate.connection.password">123</property>
    <!--mysql方言,选择最短的选项-->
    <proprrty name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <!--3个可选项-->
    <!--选择标准的sql打印在控制台-->
    <property name="hibernate.show_sql" >true</property>
    <property name="hibernate.format_sql" >true</property>
    <!--自动建表-->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!--引入映射文件-->
    <mapping resource="cn/it/domain/User.hbm.xml" />
</session-factory>
  1. 书写代码

配置详解

映射文件

hibernate-mapping
package属性:填写一个包名,后续配置中默认类所在包即为package属性填写的包

class属性
映射表与类的对应
name属性:类名
table属性:表名

id属性(映射主键)
name属性:类中主键属性名
column属性:表中主键名,默认列名为属性名
length属性:当前列的长度,默认数据库对于类型最大长度
type属性:当前列的类型,默认自动检测属性

generator属性:主键生成策略

代理主键:
increment:先查询表中主键最大值,加1作为新的主键值.
identity:依赖于数据库的主键自增
sequence:使用数据库中的序列
hilo:hibernate自己用高低位算法完成主键自增
uuid:生成随机字符串作为主键(长度应大于32位)
native(常用):自动根据数据库 三选一.(identity|sequence|hilo)

自然主键:
assigned:hibernate不生成主键.由开发人员自己设置主键值.

property属性(映射普通列)
name属性:类中主键属性名
column属性:表中主键名,默认列名为属性名
length属性:当前列的长度,默认数据库对于类型最大长度
type属性:当前列的类型,默认自动检测属性

主配置文件
整体结构在框架搭建的主配置文件中。

自动建表(hibernate.hbm2ddl.auto)
create:自动建表,每次启动hibernate都会自动建表,即使表已经存在,仍然会删除重新建。
create-drop:自动建表,每次启动hibernate都会自动建表,每次运行完成后会将表删除。
update:自动建表,如果有表,就不在重新创建,如果配置改变,自动更改表结构。
validate:不会自动创建表结构,只负责在启动时检验表结构,检出问题后会抛出异常。

**## API详解

五大核心接口:Configuration、SessionFactory、Session、Transaction、Query。**

Configuration

config,读取配置文件
buildSessionFactory,创建sessionFactory

Configuration conf = new Configuration().config;
SessionFactory sf = conf.buildSessionFactory;

SessionFactory
根据配置信息创建session对象。

  1. SessionFactory创建需要消耗较多的内存资源。
  2. SessionFactory是线程安全的设计。
    结论:在一个web项目中确保只有一个SessionFactory存在。
//获得一个全新的session
Session session = sf.openSession();
//获得与线程绑定的session,使用需要两个条件:1.在主配置文件中配置2.不需手动关闭session
Session session = getCurrentSession

Session
hibernate中操作数据库的核心对象。

  1. 操作增删改查
  2. 获得事务操作对象

beginTransaction|getTransaction 获得事务对象,第一个还具有开启事务的功能。
get|load   根据给定标识和实体类返回持久化对象的实例
save    增
delete  删
update  改
saveOrUpdate 根据给定的实例的标识属性的值来决定执行增或改的操作。
createQuery 根据给定的HQL查询条件创建一个新的Query实例。
createCriteria  根据给定的实体的名称,创建一个新的Criteria实例。
createSQLQuery 根据给定的SQL查询条件创建一个新的SQLQuery实例。

get方法不会应用类级别加载策略,立即加载。
load方法会应用类级别加载策略,load方法调用时,不会发送任何sql语句,返回一个代理对象,使用对象时才执行查询加载数据。

Transaction
用于操作事务的对象

tx.tx.begin();//开启事务
tx.commit();//提交事务
tx.rollBack();//回滚事务

创建实体对象规则

public的空参构造
准备属性,public的set/get方法
提供oid,映射主键字段
标识属性尽量使用基本数据类型的包装类
类不能被final修饰

对象的三种状态

瞬时 没id,没关联

持久 有id,有关联

游离 有id,没关联

持久化状态:持久化状态对象会在事务提交时会持久化到数据库,我们需要将对象持久化到数据库,就需要把对象转换为持久化状态。

一级缓存
一级缓存:也称为session缓存.属于线程级别缓存. 该缓存本质其实就是一个集合.该集合被放置到了session对象中.所以也叫session缓存.因为session是线程级别的.所以该缓存属于线程级别缓存.
缓存的作用:提高查询、修改效率。

查询:

  1. 根据id查询对象
  2. ResultSet会被封装成对象,放入缓存以及返回程序。如果缓存中存在要查id的对象,返回缓存中的对象。

修改:

  1. 根据id查询对象
  2. ResultSet会被封装成对象,一式两份,分别放入session缓存以及缓存快照中
  3. 事务在提交时,会比对session缓存中的以及快照中的对象是否发生变化。如果发生变化执行修改。

hibernate中的事务管理

设置事务隔离级别

<!--数值可设置为1、2、4、8-->
<property name="hibernate.connection.isolation">4</property>

hibernate中事务的应用
事务在service层管理。
确保service层和dao层使用的时同一个Connection,调用getCurrentSession方法是从ThreadLocal中获得与线程绑定的session。
getCurrentSession必须配置才能使用

<!--指定getCurrent获得session与当前线程绑定-->
<property name="hibernate.current_session_context_class">thread</property>

getCurrentSession方法获得的session对象,会在事务提交时自动关闭,不用手动关闭。

一对多|多对一关系

ORM
ORM:对象关系映射

o:一的一方使用集合,多的一方直接引用一的属性
r:多的一方使用外键引用一的一方
m:一对多关系映射,多对一关系映射

<!--配置一对多关系-->
<set name="集合属性名">
    <key column="外键名"></key>
    <one-to-many class="多的一方对应的类名" />
</set>

<!--配置多对一关系-->
<many-to-one name="引用一的属性名" column="外键名" class="一的一方对应的类名"><many-to-one>

应用

Cascase属性:级联操作
none:默认值,不级联
save-update:级联保存或级联更新
delete:级联删除
all:save-update+delete
结论:Cascase属性的性质属于减少开发时书写代码量的配置,可以不用靠写代码代替,级联操作尤其级联删除配置使用风险大,不建议使用。

inverse属性:是否放弃维护关系
inverse属性:

  • true:放弃
  • false(默认):维护

一对多中可以使用Inverse属性放弃维护关系,多对一中不能放弃维护关系。

<set name="linkMen" inverse="true">
    <key column="lkm_cust_id"></key>
    <one-to-many class="LinkMan"></one-to-many>
</set>

结论:为了避免维护关系SQL打印冗余,可以在一的一方放弃维护。配置后注意,表达关系只能通过多的一方来维护。

多对多关系

ORM
ORM:对象关系映射

r:使用第三张表,该表至少两列,两列都是外键
o:两方都用集合来表达引用多个对方
m: 多对多映射文件

<set name="stu" table="score" inverse="true">
         <!--指的是本实体类在第三方表中外键的名称  -->
         <key column="cid"></key>
         <many-to-many class="Student" column="stuid" />
         </set>
<property name="score" column="score"></property>
         <!-- 一个课程关联多个成绩 
         	  一个学生关联多个成绩-->
         <many-to-one  class="Student" name="student" column="stuid" />
         
         <many-to-one class="Course" column="cid" name="course"/>
<property name="name" column="name"></property>
        <property name="sno" column="sno"></property>
        <!-- 多对多 -->
        
       <set name="course" table="score" inverse="false" cascade="all">
       
         <key column="stuid"></key>
         <many-to-many class="Course" column="cid" />

        </set>

应用

Cascade属性:级联操作
与一对多|多对一关系中相同的操作

不推荐使用delete

inverse属性:是否放弃维护关系
inverse属性:

true:放弃
false(默认):维护
结论:为了避免维护关系重复造成异常抛出,根据业务需要由一方放弃维护。放弃的规则:谁不依赖,谁放弃。例如:订单和商品,商品不依赖订单的存在,商品放弃维护。

Hibernate中的查询

根据OID查询
对象属性导航
HQL查询
Criteria查询
原生SQL查询
HQL
Hibernate Query Language:hibernate查询语言
该查询语言是面向对象的查询语言.
HQL语句中绝对不可能出现与数据库相关的信息.
该语言是Hibernate独有的语言.只能在Hibernate中使用

语法

一. 基础语法

   //1.书写sql
    //String hql = "select c from cn.it.domain.Customer c";//完整写法
    String hql = "from Customer";//简写
    //2.创建查询对象
    Query query = session.createQuery(hql);
    //3.执行查询
    List<Customer> list = query.list();

二. 投影查询

查询一个属性

String hql = "select c.id from Customer c";
Query query = session.createQuery(hql);
List<String> list = query.list();

查询两个属性

String hql = "select c.id,c.name from Customer c";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();

查询多个对象,并封装到对象中

String hql = "select new Customer(c.id,c.name,c.password) from Customer c";
Query query = session.createQuery(hql);
List<Customer> list = query.list();

三. 条件查询

问号占位符

String hql = "from Customer c where c.name=?";
Query query = session.createQuery(hql);
query.setParameter(0,"张%");//从0开始
List<Customer> list = query.list();

命名占位符

String hql = "from Customer c where c.id between :low and :high";
Query query = session.createQuery(hql);
query.setParameter("low",2);
query.setParameter("high",5);
List<Customer> list = query.list();

四. 分页查询

String hql = "from Customer";
Query query = session.CreateQuery(hql);
query.setFirstResult(2);//startIndex
query.setMaxResults(2);//pageSize
List<Customer> list = query.list();

五. 排序
desc降序,asc升序

String hql = "from Customer c order by c.id desc ";
Query query = session.createQuery(hql);
List<Customer> list = query.list();

六. 聚合函数查询
Count、Max、Min、Sum、Avg

String hql = "select count(c) from Customer c";
Query query = session.createQuery(hql);
Long count = (Long)query.uniqueResult();

七. 多表查询

内连接

String hql = "from Customer c inner join c.linkMen";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();

迫切内连接

String hql = "from Customer c inner join fetch c.linkMen";
Query query = session.createQuery(hql);
List<Customer> list = query.list();

左外连接

String hql = "from Customer c left join c.linkMen";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();

左外迫切连接

String hql = "from Customer c left fetch c.linkMen";
Query query = session.createQuery(hql);
List<Customer> list = query.list();

右外连接、右外迫切连接在左的基础上把left换为right即可

业务逻辑较为复杂的多表仍然需要使用原生SQL书写.

Criteria查询
hibernate框架中独有的查询方式.
Criteria是无语句面向对象查询.
Criteria一般用于单表查询.

语法

一、基础查询

//1.创建查询对象
Criteria c = session.createCriteria(Customer.class);
//2.执行查询
List<Customer> list = c.list();

二、条件查询


Criteria c = session.createCriteria(Customer.class);
//设置查询参数
c.add(Restrictions.and(Restrictions.between("id",2,5),Restrictions.like("name","李%")));
//查询
List<Customer> list = c.list();

三、分页查询

Criteria c = session.createCriteria(Customer.class);
c.setFirstResult(2);
c.setMaxResults(2);
List<Customer> list = c.list();

四、排序查询

Criteria c = session.createCriteria(Customer.class);
c.addOrder(Order.asc("age"));
List<Customer> list = c.list();

五、聚合查询

Criteria c = session.createCriteria(Customer.class);
c.setProjection(Projections.Count("id"));
Long count = (Long)c.uniqueResult();

离线Criteria查询对象

离线Criteria:不需要session就可直接创建

//获得离线查询对象
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
//设置条件
dc.add(Restrictions.like("name","王%"));
//将离线查询对象与session关联
Criteria c = dc.getExecutableCriteria(session);
//执行操作
List<Customer> list = c.list(); 

结论:适合单表

原生SQL 语法

一、基本查询

String sql = "select * from t_customer";
//创建查询对象
Query query = session.createSQLQuery(sql);
List<Object[]> list = query.list();

将指定结果封装到对象中

String sql = "select * from t_customer";
Query query = session.createSQLQuery(sql);
//指定将结果封装到对象中
query.addEntity(Customer.class);
List<Customer> list = query.list();

二、条件查询

参数查询:可以用问号|命名占位符

String sql = "select * from t_customer where name like ?";
Query query = session.createSQLQuery(sql);
query.setParameter(0,"陈%");
query.addEntity(Customer.class);
List<Cutomer> list = query.list();

三、分页查询

String sql = "select * from t_customer limit ?,?";
Query query = session.createSQLQuery(sql);
query.setParameter(0,2);//设置起始页
query.setParameter(1,3);//设置每页封装数量
query.addEntity(Customer.class);
List<Customer> list = query.list();

用于复杂业务查询

查询策略
类级别查询策略
lazy属性:是否懒加载|延迟加载

  1. true(默认值):懒加载|延迟加载
  2. false:立即加载

<!–配置类级别查询策略–>

<class name="User" table="cn.it.domain.User" lazy="true"></class>

关联级别查询策略

集合加载策略(一对多|多对多)

lazy属性:决定集合加载策略

true(默认值):懒加载|延迟加载
false:立即加载
extra:极其懒惰,在查询数量时,只查询数量,不查询内容。
fetch属性:指定集合的加载方式

select(默认值):加载集合时使用单表查询加载
join:加载集合时使用左外连接查询(使用改属性,lazy属性会失效)
subselect:使用子查询加载多个集合,如果只加载一个,效果和select相同。

属性加载策略(多对一)

lazy属性:决定属性加载策略

proxy(默认值):由对方类级别策略代我决定
false:立即加载
fetch属性:指定属性的加载方式

select(默认值):单表查询加载数据
join:使用多表查询同时加载数据(使用改属性,lazy属性会失效)

<many-to-one name="customer" column="lkm_cust_id" class="Customer" lazy="proxy" fetch="select"></many-to-one>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值