ssh - hibernate基本知识点 个人总结

Hibernate :
1、框架是什么?
用来提高开发效率的
将一些功能封装好,需要这些功能时,调用即可,不需要在手动实现
可以理解为是一个半成品的项目,只要懂得驾驭这些功能即可

2、Hibernate框架。
主要用于dao层的数据库操作、(由sturts2操作web层,spring统筹三层)
操作数据库的时候,可以以面向对象的方式来完成.不需要书写SQL语句
Hibernate是一款orm框架,(orm对象关系映射,依靠配置文件,将数据库表与javabean的对象映射起来,理想状况下实现面向对象的方式操作数据库 )

3.hibernate框架搭建的基本步骤:
1.导包。(lib下的required为必导包,以及数据库驱动包)
2、创建数据库,准备实体,准备表(可以由hibernate自动生成)
3、书写orm元数据。(完成对象与表的映射配置文件 以 .hbm.xml作为文件后缀)
a、导入约束 b 创建实体 c orm元数据
4、书写主配置文件 (默认文件名为 hibernate.cfg.xml 放在src 目录下)
a、五个必写配置 (以sql server数据库为例)
数据库驱动
com.microsoft.sqlserver.jdbc.SQLServerDriver

数据库url
jdbc:sqlserver://localhost:1433;DatabaseName=server01

数据库连接用户名
sa

数据库连接密码
123456

数据库方言
不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
sql99标准: DDL 定义语言 库表的增删改查
DCL 控制语言 事务 权限
DML 操纵语言 增删改查
注意: 不知道选哪个就选最短的吧

 `org.hibernate.dialect.SQLServerDialect`    

b、三个可选配置 

true

true

     
    update

C、元数据引入配置
    

5、元数据的配置
在mapping中加入package属性 可以在下面的配置中省略包名

package="cn.xxx.domain" >
class元素: 配置实体与表的对应关系的
            name: 完整类名
            table:数据库表名

    
        
            
                
            
            
              
        
    

hibernate api:
1、Configuration 读取主配置文件、建议封装起来只一个工程创建一次
2、SessionFactory 读取元数据,读取后在数据库建表,用于获取打开 session 的工厂
3、session 与用户交流的会话

public void fun1(){
    //1、创建Configuration ,加载主配置·,默认路径
    Configuration conf = new Configuration().configure();
    //2.根据配置信息创建 SessionFactory 
    SessionFactory sessionFactory = conf.buildSessionFactory();
    //3.获取一次会话
    Session session = sessionFactory.openSession();
    //4.获得并  打开事务
    Transaction tx = session.beginTransaction();
    //---------------CURD操作------------------------
    Customer c = new Customer();
    c.setCust_name("google公司");

    session.save(c);//执行保存

    //----------------------------------------------
    tx.commit(); //tx.rollback(); 回滚
    session.close();  
    sessionFactory.close();

===========================================

hibernate中的实体规则
1、注意事项:
需要提供无参构造
提供set/get方法(有set/get才算是一个属性)
应使用包装类型(可以有null这个值) 要有与主键对应的属性不应该直接使用与对象有关的属性做主键
不要用final修饰class
2、主键类型、主键生成规则。
自然主键(不建议使用):业务对象中有符合主键要求的属性
应该用代理主键(与对象无关的)

    生成规则:
        sequence: Oracle中的主键生成策略.
        native: hilo+sequence+identity 自动三选一策略.
        hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用.
        uuid: 产生随机字符串作为主键. 主键类型必须为string 类型.
        assigned:自然主键生成策略. hibernate不会管理主键值.由开发人员自己录入.

hibernate的对象状态:
根据有没有id 以及在缓存中的状态分为
瞬时状态; 没有id
持久化状态;有id有 session缓存
游离状态: 有ID 没有色双死哦in缓存

hibernate的一级缓存和快照(提高数据效率)
hibernate 在获取session对象然后与数据库交流前会查看一级缓存中是否有对应id,
如果没有则生成SQL语句查询数据库,然后返回到hibernate一级缓存中,同时在快照中存一份,在session没有关闭前如果 有下一条语句则会在缓存和快照中查找是否有对应的 对象ID 如果有则在缓存中更改,最后关闭才执行SQL到数据库。(提交事务后,缓存会与快照中的对象比较,没有变化就不执行sql)

hibernate的事务处理
事务的特性:a 原子性 c 一致性 i 隔离性 d 持久性
并发的主要问题; 脏读 不可重复读 幻、虚读
事务的隔离级别(严格性从小到大):读未提交 1 读已提交 2 可重复读 4 串行化 8 (通过设置配置文件制定隔离级别,整合spring后建议不要使用防止以spring冲突!)
4

hibernate 管理事务:
1、在servic业务开始前打开事务,业务执行之后提交事务,出现异常就回滚
2、dao层操作的session对象应该与servic层的session对应是同一个才能保证事务安全性。
3、hibernate中有get.CurrentSession()方法获取当前线程的session对象
(在servic层new 一个session对象,然后再调用DAO层的方法时,该方法用get.CurrentSession()获取该线程对象)
要设置主配置才能使用hibernate的get.CurrentSession()保证事务安全 , 在整合spring后此配置由spring负责
thread
4、注意,在使用get.xxx方法获取session对象时,当事务提交时 不需要手动调用close关闭,

hibernate的批量查询
1、HQL查询:hibernate query language(不复杂可以使用)
Hibernate独家查询语言,属于面向对象的查询语言
基本查询: save(user),delete() ,update()
2、Criteria查询:(hibernate 的查询方法)

=========================================
多表关系(在hibernate中要体现多表需要在实体类、配置文件中加入表间关系的语法)

一对多和多对一的 元数据配置:
O (对象): 一的一方使用集合. 多的一方直接引用一的一方.
在一的一方实体中加入集合属性,存放多的一方对象
private Set linkMens = new HashSet();
//在多的一方加入对象属性
private Customer customer ; //Customer为 一 的对象
R (关系型数据库):多的一方使用外键引用一的一方主键.
M (映射文件) 一对多的配置:



    
    
        
            
            
        

    多:   
    //name:  column:在多一方的表中加入的外键。class:一 的类
    
    
    

操作: 操作管理级别属性. 
    cascade: 级联操作   (在set标签中)
        减少我们书写的操作代码.
        none(默认值)   不级联
        save-update:    级联保存(建议使用)
        delete:         级联删除
        all:            级联保存+级联删除

    inverse: 反转关系维护
    (为了维持表间关系而存在,在一的一方放弃维护这样可以删除多一方的数据)
        属于性能优化.关系的两端如果都书写了关系.那么两方都会发送维护关系的语句.
        这样,语句就发生重复.我们可以使用inverse使一的一方放弃维护关系.
        true            放弃
        false(默认值)  维护
    结论: 在一对多中,一的一方可以放弃维护关系.多对多中必须有一方放弃维护!

多对多的关系
O 对象 两方都使用集合.
R 关系型数据库 使用中间表.至少两列.作为外键引用两张表的主键.
M 映射文件

<set name="集合名" table="中间表名" >  
    <key column="别人引用我id" />        
    to-many class="别人的类" column="我引用别人的id" />
set>

在配置多对多关系的时候注意 维护外键关系只需要一个表设置即可,
使用inverse属性
true: 放弃维护外键关系
false(默认值):维护关系

<set name="teachers" table="student_Teacher" inverse="true">
        <key column="sid" >key>
        to-many class="Teacher" column="tid" >to-many>
set>

结论: 将来在开发中,如果遇到多对多关系.一定要选择一方放弃维护关系.
一般谁来放弃要看业务方向. 例如录入员工时,需要为员工指定所属角色.
那么业务方向就是由员工维护角色. 角色不需要维护与员工关系.角色放弃维护

操作:操作管理级别属性. ..
    cascade: 级联操作   
        减少我们书写的操作代码.
        none(默认值)   不级联
        save-update:    级联保存
        delete:         级联删除
        all:            级联保存+级联删除
    结论: 可以使用save-update.不推荐使用delete. 也可以不用cascade.
    inverse: 反转关系维护
        属于性能优化.必须选择一方放弃维护主键关系.哪方放弃要看业务方向.   

===========================================================================
hibernate 查询总结和 加载 关联

oid查询:根据id查询==get(xxx.class,1l);
对象属性导航:getlist
HQL语法: 面向对象语句查询
//获取整个实体对象
String hql = “from xx实体类” (查询整个对象)
String hql2 = “from java.lang.Object”;
Query query = session.createQuery(hql);
List list = query.list();

//排序语法
String hql = “from xx实体” Order by 字段 desc /asc
//条件查询
String hql = “from xx实体” where id=? ;
Query query = session.createQuery(hql);
query.setParameter(1,8);
//分页查询(mysql中 用 limit ?,?)
setFirstResult(?);
setMax
//统计查询(聚合函数)
String hql=”select count(*)/avg(id)/sum()/min(id)/max()/ from xxx”
Query query = session.createQuery(hql);
Number number = (Number)query.uniqueResult();

//投影查询(查询一个属性)
String hql = “select xx_name from xx实体类” ;
Query query = session.createQuery(hql);
List list = query.list();
//多表查询
内连接 String hql = “from A inner join a.linkMens”;(linkMens为外键列)
Query query = session.createQuery(hql);
List list = query.list();
迫切内连接:
String hql = “from A inner join fetch a.linkMens”;(linkMens为外键列)
List list = query.list();
外连接
左外
String hql = “from A left inner join a.linkMens”;
右外
String hql = “from A right inner join a.linkMens”;

Criteria查询:
//基本查询:
A a = session.createCriteria(A.class);
List list = a.list(); //放在所有条件后面

//条件查询 直接add添加条件(Restrictions.xx)
a.add(Restrictions.ideq(1)); //查询id为1

//分页查询
a.setFirstResult(0);//第一页
a.setMaxResult(2); // 前两条

//排序
a.addOrder(Order.asc(id/字段))
a.addOrder(Order.desc(id/字段))

//统计查询
Number num = a.setProjection(Prjections.聚合函数);

//离线查询
criteria 创建依赖于session
session.createCriteria();

在Servic层 DerachedCriteria dc = DatachedCriteria.forClass(Customer.class);
dc.add(Restrictions.adEq(1)); //拼装条件  与Criteria 一致


Criteria c = dc.getExecutable(session);
List  list = c.list();

查询优化
类级别查询
懒加载/延迟加载:在打印对象时有$符号,则该对象为代理对象
get方法立即加载,session.get(A.class,2l);
load方法延迟加载,返回一个对象,该对象使用时才执行sql获得该对象
session.load(A.class,2l);
load方法的延迟加载属性,可以在配置class时,加 lazy属性,默认为turn,false为不延迟

关联级别查询 &  属性抓取策略
(  为了提高效率,用lazy属性和fetch属性,达到查询关联的
    效果,在一对多或多对多、多表查询中 通过一个对象,获取与之关联的其它对象)
 获取的一个对象,在获取与之关联的对象或对象集合 (get方法)
    LinkMan lm = session.get(LinkMan.class, 3l);
    Customer customer = lm.getCustomer();

 

 



    
    
        
        
    

原生sql查询 :
String sql = “select * from A”; //sql语句
SQLQuery query = session.createSQLQuery(sql); //创建一个查询

a.add(Restrictions.ideq(1)); //add添加条件(Restrictions.xx) 查询id为1
List list = query.list();  

==========================================================================

你可能感兴趣的:(hibernate,数据库,spring,ssh,面向对象,学习笔记)