j2EE hibernate

hibernate 执行流程

154722_fOfD_81653.jpg

211719_3rzy_81653.gif

读取Hibernate 的配置信息-〉创建SessionFactory

1)创建Configuration类的实例。

 它的构造方法:将配置信息(Hibernate config.xml)读入到内存。

 一个Configuration 实例代表Hibernate 所有Java类到Sql数据库映射的集合。

2)创建SessionFactory实例

 把Configuration 对象中的所有配置信息拷贝到SessionFactory的缓存中。

 SessionFactory的实例代表一个数据库存储源,创建后不再与Configuration 对象关联。

缓存(cache):指Java对象的属性(通常是一些集合类型的属性--占用内存空间。

     SessionFactory的缓存中:Hibernate 配置信息。O\R映射元数据。

3)调用SessionFactory创建Session的方法

  Session s=sessionFactory.openSession();

4)通过Session 接口提供的各种方法来操纵数据库访问


JPA(Java Persistence API)

JPA通过注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

02210641_Dnsa.jpg


注解

@Entity ,注册在类头上,将一个类声明为一个实体bean(即一个持久化POJO类) 。

@Table ,注册在类头上,注解声明了该实体bean映射指定的表(table)。

@Id用来注册主属性,

@GeneratedValue用来注册主属性的生成策略,

@Column用来注册属性,

@Version用来注册乐观锁,

@Transient用来注册不是属性。

 以上的@Id、@GeneratedValue、 @Column 、 @Version,可以用来注册属性,既可以写在Java类的属性上,也可以注册在属性对应的getter上。

@Transient注册在多余的属性或多余的getter上,但是必须与以上的@Column等对应。 @Column 标识属性对应的字段,示例:@Column(name=“userName")

@Column的说明:

 @Column(

    name="columnName";                                (1)

    boolean unique() default false;                   (2)

    boolean nullable() default true;                  (3)

    boolean insertable() default true;                (4)

    boolean updatable() default true;                 (5)

    String columnDefinition() default "";             (6)

    String table() default "";                        (7)

    int length() default 255;                         (8)

    int precision() default 0; // decimal precision   (9)

    int scale() default 0; // decimal scale           (10)


(1) name 可选,列名(默认值是属性名) 

(2) unique 可选,是否在该列上设置唯一约束(默认值false) 

(3) nullable 可选,是否设置该列的值可以为空(默认值false) 

(4) insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true) 

(5) updatable 可选,该列是否作为生成的update语句中的一个列(默认值true) 

(6) columnDefinition 可选: 为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植) 

(7) table 可选,定义对应的表(默认为主表) 

(8) length 可选,列长度(默认值255) 

(9) precision 可选,列十进制精度(decimal precision)(默认值0) 

(10) scale 可选,如果列十进制数值范围(decimal scale)可用,在此设置(默认值0) 

@Id,标识这个属性是实体类的唯一识别的值。 

注意:这个注解只能标注单一列构成的主键,

如tbl_grade那种有两个字段组成的联合主键由其他注解标识


hibernate 接口

Configuration

进行配置信息的管理(数据库连接,映射)

用来产生SessionFactory

可以在configure方法中指定hibernate配置文件

只需关注一个方法即:buildSessionFactory

    private static org.hibernate.SessionFactory sessionFactory;	
    private static Configuration configuration = new Configuration();
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
    private static String configFile = CONFIG_FILE_LOCATION;

	static {
    	try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory();
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
    }

 SessoinFactory(维护数据库连接池)

a)   用来产生和管理Session(生产和管理连接)

b)   通常情况下每个应用只需要一个SessionFactory

c)   除非要访间多个数据库的情况

d)   关注两个方法即:openSession getCurrentsession

          i.   open session每次都是新的,需要close

        ii.   getCurrentsession从上下文找,如果有,用旧的,如果没有,建新的,可以使用事务(session.getTransaction().commit()提交后,session就不存在了)

getCurrentSession创建的session会和绑定到当前线程,而openSession不会

getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭

上下文配置(即在hibernate.cfg.xml)中,需要配置:

    <property name="current_session_context_class">thread</property>

(需要注意,这里的current_session_context_class属性有几个属性值:jta 、 thread 常用 , custom、managed 少用  )

a).thread使用connection 单数据库连接管理事务

b).jta (java  transaction api) Java 分布式事务管理 (多数据库访问),jta 由中间件提供(JBoss WebLogic 等, 但是tomcat 不支持)

                Session session = sf.openSession();
		session.beginTransaction();
		session.save(tea);
		session.getTransaction().commit();
		session.close();

1      Session

a)    管理一个数据库的任务单元(简单说就是增 删 改 查)

b)    方法(CRUD)

         i.   Save()

        ii.   delete

       iii.   load 从数据库中取出一条记录到内存中,转换为javabean(persistent状态)。返回代理对象,然后使用属性的时候才会真正从数据库中拿

       iv.   get 直接向数据库发送sql语句拿到对象,直接加载,不会延迟。

hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要第一时间获取到真实的数据,否则返回null。无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找,调用clear()方法可以强制清除session缓存。调用clear()方法可以强制清除session缓存。

        vi.  updates

用来更新detached对象,更新完成后转为persistent状态; 更新transient对象会报错; 更新自己设定id的transient对象可以(数据库有对应记录); persistent状态的对象只要设定(如:t.setName…)不同字段就会发生更新

或者通过sql语句

Query q = session.createQuery("update Teacher t set t.name='wangee' where t.id=1");
q.executeUpdate();

       vii.  flush()

tea.setName("new111");
session.flush();
tea.setName("new111111");

当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!



对象的三种状态

123523_4f7t_81653.jpg

三种状态:

a)    transient(瞬态):内存中一个对象,没ID,缓存中也没有

在数据库中没有与之匹配的数据,只是一个普通的JavaBean

没有纳入session的管理

b)    persistent(持久态):内存中有,缓存中有,数据库有(ID)

persistent状态的对象在数据库中有与之匹配的数据

纳入了session的管理(session中有map数据结构,map中的key对应id,value对应存储的对象引用,相当于缓存的作用,提高效率)

在清理缓存(脏数据检查)的时候,会和数据库同步

c)    detached(脱管态):内存有,缓存没有,数据库有ID

在数据库中有与之匹配的数据

session关闭了,没有纳入session的管理(没有缓存了,session中的map没有了)


关系映射

one to one

one to many

many to many


hibernate缓存体系

一级缓存

 Session 有一个内置的缓存,其中存放了被当前工作单元加载的对象。

 每个Session 都有自己独立的缓存,且只能被当前工作单元访问。

一个线程对应一个session,一个线程可以看成一个用户。也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了

list与iterator

list:每次使用都重新发送sql语句,不使用session缓存,取全部数据。

iterator:可以使用session缓存,每次查询都先取出id,将id对应的对象放在缓存中。

二级缓存

 SessionFactory的外置的可插拔的缓存插件。其中的数据可被多个Session共享访问。sessionFactory控制的进程级缓存是全局共享的缓存

 SessionFactory的内置缓存:存放了映射元数据,预定义的Sql语句

经常被访问,改动不大,数量有限的对象是很适合放在二级缓存中

load默认使用二级缓存,iterator默认使用二级缓存

list默认向二级缓存中添加数据,查询的时候不用

查询时使用缓存的实现过程为:首先查询一级缓存中是否具有需要的数据,如果没有,查询二级缓存,如果二级缓存中也没有,此时再执行查询数据库的工作。要注意的是:此3种方式的查询速度是依次降低的。

<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>//cache category
<property name="cache.use_query_cache">true</property>//list会将结果放入缓存

另外需要在javabean中做注解@cache

一级缓存与二级缓存

Session的生命期往往很短,存在于Session内部的第一级最快缓存的生命期当然也很短,所以第一级缓存的命中率是很低的。其对系统性能的改善也是很有限的。当然,这个Session内部缓存的主要作用是保持Session内部数据状态同步。并非是hibernate为了大幅提高系统性能所提供的





转载于:https://my.oschina.net/hnuweiwei/blog/297432

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值