hibernate

1.

核心配置

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <!--配置链接池-->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/station</property>
    <property name="connection.username">root</property>
    <property name="connection.password">admin</property>

    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <!--展示sql语句-->
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>
    <mapping resource="mapper/loginuser.hbm.xml"/>
</session-factory>
</hibernate-configuration>

 

2.建立映射文件

<?xml version="1.0" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.model">
<!--class表示一个由hibernate管理的持久对象,对应数据库的一个表-->
<!--LoginUser模型的名称-->
<!--table 数据库表名-->
<class name="LoginUser" table="login_user">
<!--id元素节点是必须的,是代表表的主键-->
<id name="id" column="id">
<!--generator表示主键生成的方式,多数是用native-->
<!--native自动选择数据库本地的策略-->
<!--mysql:AUTO_INTCREMENT自增-->
<!--oracle 序列-->
<generator class="native"/>
</id>
<!--非主键对象-->
<property name="userName" column="`username`"/>
<property name="passWord" column="`password`"/>
</class>
</hibernate-mapping>

 3.dao实现

public class LoginUserDao implements ILoginUserDao{

@Override
public void save(LoginUser loginUser) {
//读取并且解析配置文件
Configuration configuration = new Configuration();
//加载非默认配置文件 默认配置文件是hibernate.cfg.xml configuration.configure();
configuration.configure("hibernate.cfg.xml");
//生成会话工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
//获取对象
Session session = sessionFactory.openSession();
//开启事务管理
Transaction transaction = session.getTransaction();//必须写
transaction.begin();//必须写
// transaction.commit();
//操作CRUD
session.save(loginUser);
transaction.commit();//必须写 不然不报警且数据库没数据 但id被占用
session.close();
sessionFactory.close();

}
}

 4.

@Test
public void testsave(){
LoginUserDao loginUserDao = new LoginUserDao();
LoginUser loginUser = new LoginUser();
loginUser.setUserName("pioqkl");
loginUser.setPassWord("123456");
loginUserDao.save(loginUser);
}

 5.SessionFactory


主要作用:负责创建Session对象
概念:SessionFactory对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。同时,SessionFactory还负责维护Hibernate的二级缓存,查询缓存。

注意
1.SessionFactory对象的创建会有较大的开销,因为SessionFactory内部采取了线程安全的设计方式,因此在实际中SessionFactory对象可以尽量的共享,在大多数情况下,一个应用中针对一个数据库可以共享一个SessionFactory实例。
2.一个请求:一个Session对象(包含一个连接对象,一个事务对象,一个一级缓存)

重要的方法

openSession:这个方法代表,开启一个全新的Session

1)全新的连接
2)全新的事务
3)全新的一级缓存

getCurrentSession:得到当前上下文中的session
1)如果当前上下文中存在session,则使用该session;
2)如果当前上下文中不存在session,则使用opensession创建一个新的session;放到当前线程
3)要使用getCurrentSessoin,必须在hibernate.cfg.xml中配置thread
  <property name="current_session_context_class">thread</property>
4)getCurrentSession得到的session是和事务绑定的;
   无论是DML(数据操作语言)还是DQL(数据查询语言) ,都必须开启事务

   提交事务的时候就是关闭session

注意:getCurrentSession使用场景(如下)

本行转账业务:达到一致性,要不都成功,要不都失败保证在service层,在dao层获取的session都是同一个,对应就是同一个事务对象

 

列:

 

5.2org.hibernate.NonUniqueObjectException异常

 

下面这个是正确的

 

 

 

 结论: 先从一级缓存取,取不到,发出sql获取,放入一级缓存
// 一级缓存命中:只会发出一条sql
// 一级缓存命中条件:同一个session的OID是否相同
// 一级缓存内部的结构:
// OID:Object ID,hibernate里面定义
// 操作的持久对象全限定类名+"#"+数据库主键的值
// com.hibernate.day01.model.LoginUser#1
//存放在 Map<String,Object> cacheMap

 6.  状态的 理解

临时状态(transient):瞬时状态刚刚用new语句创建,没有和session发生关系没有被持久化,不处于session中。该对象成为临时对象
持久化状态(persistent):托管状态和session发生关系已经被持久化,加入到session的一级缓存中。该状态的对象为持久化对象。
游离状态(detached):脱管状态已经被持久化,但不处于session中。该状态的对象为游离对象。
删除状态(removed):从jpa出现,才有的状态只有调用了session.delete(domain对象)方法对象有关联的ID,并且在Session管理下,但是已经被计划删除(真正删除是提交事务的时候)

 7.脏数据更新

 

 8.      延迟加载(懒加载):

真正需要非主键属性,才发出sql,获取非主键属性值提高性能,但是如果把session提前关闭,会出现(延迟加载)延迟初始化异常

 

 

GET与load的区别

 

 

 

 9.状态转变原理图

 

 

 

 

 

 

 

posted on 2018-03-20 14:14  好名字被谁用了  阅读(115)  评论(0编辑  收藏  举报

导航