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的管理
- 数据库中有对应的记录
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号