j2EE hibernate

Wesley13
• 阅读 679

hibernate 执行流程

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

j2EE hibernate

j2EE hibernate

读取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描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

j2EE hibernate

注解

@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)中,需要配置:

    thread

(需要注意,这里的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)时才同步!

对象的三种状态

j2EE hibernate

三种状态:

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为了大幅提高系统性能所提供的

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java——20171121
!(http://a.51jsoft.com/uploads/default/original/1X/c542896b094a42a5653fb75adf6cdacd6e35d12e.png)!(https://static.oschina.net/uploads/space/2017/1121/210719_G80Z_3715033.png)
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这