hibernate

hibernate

 

基础,API,映射,Inverse属性和cascade属性,多种查询逆向工程缓存

 

基础 :

(1)开源轻量级框架
Hibernate是一种ORM框架ORM是一种思想,对象与数据库中的列的关系。

  • O代表的是Objcet
  • R代表的是Relative
  • M代表的是Mapping

对象关系映射

 让实体类首先和数据库表对应,让实体类属性和表里字段对应,以实现直接存取Java对象!

底层是jdbc ,使用Hibernate框架就不用我们写很多繁琐的SQL语句,从而简化我们的开发!


(2 ) 配置文件
1.引入jar开发包
hibernate3.jar核心 + required 必须引入的(6个) + jpa 目录 + 数据库驱动包

2.配置相关的XML文件 相关写法
主配置文件: hibernate.cfg.xml

包含:配置数据库、mapping相关映射配置

映射配置: .hbm.xml

包含:映射字段、对多设置

 

 

 

API :熟悉API

(1)  hibernate执行流程:

第一步:加载hibernate核心配置文件
Configuration config= new Configuration();
config.configure();

第二步:创建sessionFactory对象
SessionFactory sessionFactory=config.buildSessionFactory();

第三步:使用sessionFactory创建SESSION对象
Session session=sessionFactory.openSession();

第四步:开启事务
Transaction tx=session.beginTransaction();

第五步:写具体逻辑crud操作
...
//session.save(demo1);

 

第六步:提交事务
tx.commit();

session.close();

第七步:关闭资源
sessionFactory.close();

 

 

Configuration 配置管理类:主要管理配置文件的一个类
configure方法 加载配置文件
buildSessionFactory方法 创建Session工厂
SessionFactory
openSession方法 创建一个Session对象
getCurrentSession方法 创建Session对象或取出Session对象

 

Session (1)类似jdbc中connection(2)调用crud操作(3)session对象单线程对象,session对象不能共用,只能使用。

绑定session:

<!-- 配置session绑定本地线程
<property name="hibernate.current_session_context_class">thread</property>
-->

 

Transaction 事务四个特性:原子性、一致性、隔离性、持久性

 

(2)session

Session是Hibernate最重要的对象,Session维护了一个连接(Connection),只要使用Hibernate操作数据库,都需要用到Session对象

更新操作:save(Objcet o)方法

主键查询:通过主键来查询数据库的记录,从而返回一个JavaBean对象

  • session.get(javaBean.class, int id); 【传入对应的class和id就可以查询】
  • session.load(javaBean.class, int id); 【支持懒加载】

HQL查询:hibernate提供的面向对象的查询语言。(SQL:Struct query language 结构化查询语言,查询的是表以及列【不区分大小写】

  Query query = session.createQuery("FROM User");

        List list = query.list();
        System.out.println(list);

(可以查询,也可以传递参数进去查询)

QBC查询:QBC查询: query by criteria 完全面向对象的查询。HQL查询是需要SQL的基础的,因为还是要写少部分的SQL代码....QBC查询就是完全的面向对象查询。

        //创建关于user对象的criteria对象
        Criteria criteria = session.createCriteria(User.class);
        //添加条件
        criteria.add(Restrictions.eq("id", 1));
        //查询全部数据
        List list = criteria.list();
        System.out.println(list);

 

本地SQL查询:它是不能跨平台的

        //将所有的记录封装成User对象存进List集合中
        SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM user").addEntity(User.class);
        List list = sqlQuery.list();
        System.out.println(list);


映射

参考:https://segmentfault.com/a/1190000013600430#articleHeader34

 

集合映射

(1)Set集合映射配置
<!-- 在客户映射中中表示所有的联系人 使用set标签表示所有人,set标签中有Name属性,属性写在客户实体类中表示联系人的set集合名称 -->

List集合映射配置

List集合是有序的,因此要多配置一个列来维护数据的有序性!
<list name="address" table="address">
<key column="user_id"></key> 
<!--index是关键字,不能使用!!!!-->
<list-index column="indexNum"></list-index>
<element column="addr" type="string"></element>
</list>

Map集合映射配置

Map集合和Collection集合的区别就是键值对模型,那么在配置的时候多一个key即可!

(2)组件映射
继承映射

(3)子类拥有自己的表、父类不对应表【推荐】union-subclass
子类、父类都有自己的表joined-subclass,那么就是三张表
子类父类共有一张表subclass

 

 

 

对多映射

(1)一对多

private Set<LinkMan> setLinkMan=new  HashSet<LinkMan>();

<set name="setLinkMan">
<key column="keyId"></key>
<one-to-many class="com.test.entity.LinkMan"></one-to-many>
</set>

 

 

private Customer cus;

  <many-to-one name="cus" class="com.test.entity.Customer" column="keyId"></many-to-

(2)多对多


<set name="setCou" table="c_l">
<key column="KKlId"></key>
<many-to-many class="com.test.entity.Customer" column="kkcut_Id"></many-to-many>
</set>

<set name="setLinkMan" table="c_l">
<key column="kkcut_Id"></key>
<many-to-many class="com.test.entity.LinkMan" column="KKlId"></many-to-many>
</set>

 

 

 

 

 

 

Inverse属性和cascade属性

(1)inverse属性
表示控制权是否转移.

  • true:控制权已转移【当前一方没有控制权】
  • false:控制权没有转移【当前一方有控制权】

因为hibernate双向维护外键,在客户和联系人中都需要维护外键,修改客户时修改一次外键,修改联系人时候也是修改一次外键,造成了性能问题。
解决:让其中一方放弃外键维护
<set name="user" inverse="true"> (ture为放弃,false是不放弃)

inverse属性只能在“一”的一方设置

Inverse在维护关联关系时是否起作用:保存数据,获取数据,解除关联关系,删除数据对关联关系的影响。


(2)cascade属性
级联的意思,操作某一属性时,对其他关联字段的影响

级联保存、更新、删除

可以在“一”的一方也可以在“多”的一方设置
<set name="setLinkMan" cascade="save-update,delete">

 

(3)ascade和inverse总结

inverse属性只能在“一”的一方中设置。inverse=false表示有控制权,inverse=ture表示没有控制权

  • 在保存关联信息时·

    • 有控制权--->可以保存相对应的关联数据
    • 没有控制权--->数据会保存,但是关联关系没有维护,也就是外键列为NULL
  • 在查询数据时

    • 有无控制权对查询数据没有任何影响
  • 在解除关联关系时

    • 有控制权--->可以解除关联关系
    • 没有控制权--->不能解除关联关系,不会生成update语句,也不会报错
  • 在删除数据时对关联关系的影响

    • 有控制权--->将外键的值设置为NULL,随后删除数据
    • 没有控制权--->如果删除的记录有被外键引用,会报错,违反主外键引用约束,如果删除的记录没有被引用,可以直接删除

多对多关系的时候也是一样的,只不过多对多的关联关系是在中间表中。

 

ascade属性,cascade有这么几个值:

  • none 不级联操作, 默认值
  • save-update 级联保存或更新
  • delete 级联删除
  • save-update,delete 级联保存、更新、删除
  • all 同上。级联保存、更新、删除

我们可能使用到的往往是:save-update这个值,因为级联删除的风险太大了

  • 级联保存

    • 没有设置级联保存-->如果单单保存一个对象,而对象又存在外键时,那么就会抛出异常
    • 设置了级联保存-->那么就可以将对象以及有关联关系的对象一并保存
  • 级联删除

    • 没有设置级联删除-->在删除数据的时候,会把外键的字段设置为NULL,再删除当前一方的记录
    • 设置了级联删除-->把对象有关联关系的记录都删除了

 

如果cascade和inverse同时设置时:

inverse属性优先级是要比cascade要高的,如果inverse属性设置了true,那么cascade就无效了!

 

 

查询

(1)get/load主键查询

(2)对象导航查询

  // 对象导航查询
        Dept dept =  (Dept) session.get(Dept.class, 12);
        System.out.println(dept.getDeptName());

        //这里就可以得到部门对应的所有员工
        System.out.println(dept.getEmps());

(3)HQL查询

(4)Criteria 查询(完全面向对象的查询)

(5)本地SQL查询

(6)分页查询:
得到数据库表中的总记录数
查询起始位置到末尾位数的数据
Query query = session.createQuery("from Monkey");
//得到滚动结果集
ScrollableResults scroll = query.scroll();
//滚动到最后一行
scroll.last();
int i = scroll.getRowNumber() + 1;
System.out.println("总计路数:" + i);
//设置分页位置
query.setFirstResult(0);
query.setMaxResults(3);
System.out.println(query.list());



逆向工程:

在设计数据库表时,我们使用PowerDesigner来生成概念模型\物理模型…
逆向工程可以帮我们自动生成实体和映射文件,这样就非常方便了。

 

 

 

缓存:

为什么要是使用缓存?

减少对数据库的访问次数!从而提升hibernate的执行效率!

 

(1)一级缓存 :
session的缓存
作用:减少对数据库的访问次数,从而提升hibernate的执行效率。

只要是持久化对象状态的,都受Session管理,也就是说,都会在Session缓存中
用户不能操作缓存内容; 如果想操作缓存内容,必须通过hibernate提供的evit/clear方法操作。

相关方法:
session.flush(); 让一级缓存与数据库同步
session.evict(arg0); 清空一级缓存中指定的对象
session.clear(); 清空一级缓存中缓存的所有对象

(2)二级缓
目前已经不使用,替代技术redis

 

(3)懒加载:
当使用数据的时候才去获取数据、执行对应的SQL语句…当还没用到数据的时候,就不加载对应的数据!
主要目的就是为了提高Hibernate的性能,提高执行效率!


get: 及时加载,只要调用get方法立刻向数据库查询
load:默认使用懒加载,当用到数据的时候才向数据库查询。
User user = (User) session.load(User.class, 1);

可以在对应的配置文件用通常lazy属性来设置
<class name="IdCard" table="IdCard" lazy="false">
true 使用懒加载
false 关闭懒加载

 

(4) hibernate中对象的三种状态(概念)

瞬时态:对象没有ID值,对象和session没有关联

直接new出来的对象就是临时/瞬时状态的

该对象还没有被持久化【没有保存在数据库中】

不受Session的管理


持久态对象有ID值,和SESSION有关联

当保存在数据库中的对象就是持久化状态了

  • 当调用session的save/saveOrUpdate/get/load/list等方法的时候,对象就是持久化状态
  • 在数据库有对应的数据
  • 受Session的管理
  • 当对对象属性进行更改的时候,会反映到数据库中


托管态(游离):有ID值,和session没关联

当Session关闭了以后,持久化的对象就变成了游离状态了...

  • 不处于session的管理
  • 数据库中有对应的记录

 

posted @ 2018-10-19 15:36  StingLon  阅读(218)  评论(0)    收藏  举报