Hibernate 内容记录

Session概述:

-Session接口是Hibernate向应用程序各供的操作数据库的最主要的接口,它提供了基本的保存、更新、删除和加载Java对象的方法。

-Session具有一个缓存,位于缓存中的对象称为持久化对象,它和数据库中相关记录对应。Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被称为刷新缓存(flush)

-站在持久化的角度,Hibernate把对象分为4种状态:持久化状态,临时状态,游离状态,删除状态。Session的特定方法能使对象从一个状态转换到另一个状态

Session缓存:

什么是缓存?

  即使就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中。再次获取的时候,直接从缓存中获取。可以提升程序的性能!

Hibernate框架提供了两种缓存:

  一级缓存---自带的不可卸载的,一级缓存的声明周期与Session一致。一级缓存称为Session级别的缓存。

  二级缓存---默认没有开启,需要手动配置才可以使用的。二级缓存可以在多个Session中共享数据,二级缓存称为SessionFactory级别的缓存.

Session对象的缓存概述:

-在Session接口的实现中包含一系列的java集合,这些Java集合构成了Session缓存,只要Session实例没有结束生命周期,且没有清理缓存,则存放在它缓存中的对象也

不会结束生命周期.

-Session缓存可减少Hibernate应用程序访问数据库的频率。

证明:只向数据库发送了一条SQL,而查询了2次,并且是同一个对象。

事务:

什么是事务?

  事务就是逻辑上的一组操作,组成事务的各个执行单元,操作要么全部成功,要么全部失败。

  例子:转账的例子;A给B转钱,扣钱,加钱。两个操作组成了一个事务!

事务对的特性:

  原子性----事务不可分割。

  一致性----事务执行的前后数据的完整性保持一致。

  隔离性----一个事务执行的过程中,不应该受到其他的事务的干扰

  持久性----一旦事务提交,数据就永久保存到数据库中。

如果不考虑 数据库的隔离级别:对于同时运行的多个事物,当这些事物访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:

-脏读:对于两个事物T1,T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的。

-不可重复读:对于两个事物T1,T2,  T1读取了一个字段,然后T2更新了该字段之后,T1再次读取同一个字段,值就不同了(就是读取了T2 update操作之前之后的操作)

-幻读:对于两个事物T1,T2 ,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行之后,如果T1再次读取同一个表,就会多出几行。(就是读取了T2 insert操作之前之后的操作)

设置数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使他们不会相互影响,避免各种并发问题。(来解决上面的问题)

一个事务与其他事务隔离的成都称为隔离级别,数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱

-未提交读:以上的读的问题都有可能发生

-已提交读:避免脏读,但是不可重复读,虚读都有可能发生

-可重复读:避免脏读,不可重复读,但是虚读是可能发生的

-串行化:以上读的情况都可以避免

如果想在Hibernate的框架中来设置隔离级别,需要在hibernate.cfg.xml的配置文件中通过标签来配置

  通过:hibernate.connection.isolation=4(一般用4)来配置

    1-Read uncommitted isolation

    2-Read committed isolation

    4-Repeatable read isolation

    8-Serializable isolation

参考博客:https://www.cnblogs.com/fjdingsd/p/5273008.html

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <!-- 配置连接数据库的基本信息 -->
 8         <property name="connection.username">root</property>
 9         <property name="connection.password">root</property>
10         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
11         <property name="connection.url">jdbc:mysql:///hibernate5</property>
12
13         <!-- 配置hibernate的基本信息 -->
14         <!-- hibernate所使用的数据库方言 -->
15         <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
16
17         <!-- 执行操作时是否在控制台打印SQL -->
18         <property name="show_sql">true</property>
19         <!-- 是否对SQL进行格式化 (分行显示)-->
20         <property name="format_sql">true</property>
21         <!-- 指定自动生成数据表的策略 -->
22         <property name="hbm2ddl.auto">update</property>
23
24         <!-- 设置Hibernate的事务隔离级别 -->
25         <property name="connection.isolation">2</property>
26
27         <!-- 指定关联的.hbm.xml文件 -->
28         <mapping resource="com/tzy/hibernate/News.hbm.xml"/>
29
30     </session-factory>
31 </hibernate-configuration>

hibernate.cfg.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2017-11-19 16:22:35 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping>
 6     <class name="com.tzy.hibernate.News" table="NEWS">
 7         <id name="id" type="java.lang.Integer">
 8             <column name="ID" />
 9             <!-- 指定逐渐生成的方式,native:使用数据库本地方式 -->
10             <generator class="native" />
11         </id>
12
13         <property name="title" type="java.lang.String">
14             <column name="TITLE" />
15         </property>
16
17         <property name="author" type="java.lang.String">
18             <column name="AUTHOR" />
19         </property>
20
21         <property name="date" type="java.util.Date">
22             <column name="DATE" />
23         </property>
24
25     </class>
26 </hibernate-mapping>

News.hbm.xml

 1 package com.tzy.hibernate;
 2
 3 import java.util.Date;
 4
 5 public class News {
 6 private Integer id;
 7 private String title;
 8 private String author;
 9 private Date date;
10 public Integer getId() {
11     return id;
12 }
13 public void setId(Integer id) {
14     this.id = id;
15 }
16 public String getTitle() {
17     return title;
18 }
19 public void setTitle(String title) {
20     this.title = title;
21 }
22 public String getAuthor() {
23     return author;
24 }
25 public void setAuthor(String author) {
26     this.author = author;
27 }
28 public Date getDate() {
29     return date;
30 }
31 public void setDate(Date date) {
32     this.date = date;
33 }
34
35 public News(String title, String author, Date date) {
36     super();
37     this.title = title;
38     this.author = author;
39     this.date = date;
40 }
41 public News() {
42     super();
43 }
44 @Override
45 public String toString() {
46     return "News [id=" + id + ", title=" + title + ", author=" + author + ", date=" + date + "]";
47 }
48
49 }

News

 1 package com.tzy.hibernate;
 2
 3 import java.util.Date;
 4
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.hibernate.Transaction;
 8 import org.hibernate.boot.MetadataSources;
 9 import org.hibernate.boot.registry.StandardServiceRegistry;
10 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
11 import org.junit.Test;
12
13 public class HibernateTest {
14
15     @Test
16     public void test() {
17         //1.创建一个SessionFactory对象
18         SessionFactory sessionFactory = null;
19
20         //hibernate4获取sessionFactory办法
21         //1).创建Configuration对象:对应hibernate的基本配置信息和关系映射信息
22         //Configuration configuration = new Configuration().configure();
23         //4.0之前这样创建
24         //sessionFactory = configuration.buildSessionFactory();
25         //2).创建一个ServiceRegistry对象:hibernate 4.x新添加的对象
26         //hibernate的任何配置和服务都需要在该对象中注册后才能有效。
27         //ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
28         //                                                                .buildServiceRegistry();
29         //3).
30         //sessionFactory = configuration.buildSessionFactory(serviceRegistry);
31
32         //4).
33         //hibernate5获取sessionFactory办法
34         //创建StandardServiceRegistry对象(标准服务注册)
35         StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
36
37         sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
38         //2.创建一个Session对象
39         Session session = sessionFactory.openSession();
40
41         //3.开启事物
42         Transaction transaction = session.beginTransaction();
43
44         //4.执行保存操作
45         News news = new News("Java", "Tzy", new Date());
46         session.save(news);
47
48         News news2 = session.get(News.class, 1);
49         System.out.println(news2);
50         //5.提交事物
51         transaction.commit();
52
53         //6.关闭Session
54         session.close();
55
56         //7.关闭SessionFactory对象
57         sessionFactory.close();
58     }
59
60 }

HibernateTest

 绑定本地Session

1、hibetnate是通过把session绑定到线程中,来解决事务问题的(通过ThreadLocal)

2、现在的Hibernate框架中,使用session对象开启事务,所以需要来传递session对象,框架提供了ThreadLocal的方式

  需要在hibernate.cdg.xml的配置文件中提供配置<property name="hibernate.current_session_context_class">thread</property>

  修改session的获取方式为 SessionFactory.getCurrentSession();

3、这样在Transaction(事务)提交的时候可以通过抛异常的方式执行transaction.rollback();方法,回滚事务,

  注意:使用这种session的事务执行提交操作过后,hibernate会帮助我们在线程执行完毕将session关闭。我们就不需要在finally里面去关闭session了

持久化对象的状态

-站在持久化的角度,Hibernate把对象分为4种状态:持久化状态,临时状态,删除状态。Session的特定方法能使对象从一个状态转换到另一个状态

  临时对象(Transient)

  •   在使用代理主键的情况下,OID通常为null
  •   不处于Session的缓存中
  •   在数据库中没有对应的记录

  持久化对象(也叫“托管”)(Persist)

  •   OID不为null
  •   位于Session缓存中
  •   若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
  •   Session在flush缓存时,会根据持久化对象的属性变化,来同步更新数据库
  •   在同一个Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象

  删除对象(Removed)

  • 在数据库中没有和其OID对应的记录
  • 不再处于Session缓存中
  • 一般情况下,应用程序不该在使用被删除的对象

  游离对象(也叫“脱管”)(Detached)

  • OID不为null
  • 不再处于Session缓存中
  • 一般情况下,游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录

Hibernate框架的查询方式

Criteria查询接口(做条件查询非常合适)

  1、QBC:Query By Criteria  -----按条件经行查询

  2、QBC:查询方式的使用

    ---先创建查询接口         Criteria   c = session.createCriteria(User.class);

    ---设置查询的条件   c.add(Restrictions.gt("age",10));                     查询年龄大于10的       

               模糊查询用c.like(Restrictions.gt("name","%熊%"));

          多条件查询(and) c.like(Restrictions.gt("name","%熊%"));       c.add(Restrictions.gt("age",10));  查询出来的就是名字有熊的年龄大于10的

          多条件查询(ro)   c.add(Restrictions.or(Restrictions.gt("name","%熊%"),Restrictions.gt("age",10)));

          在什么之间查询      c.like(Restrictions.between("age",10,30));            查询年龄10-30之间的

    ----查询数据      List<User> list = c.list();

    ----分页    c.setFirstResult(2);   //第三条数据开始     c.setMaxResult(2);  //每页数据2条

一对多,多对一:

新建一个客户和两个联系人

  Customer c = new Customer();

  c.setCust_name("马妹妹");

  LinkMan m1 = new LinkMan();

  m1.setLkm_name("强哥");

    LinkMan m2 = new LinkMan();

  m1.setLkm_name("小宋");

双向关联

  客户关联联系人(获取联系人引用的set集合添加元素)

  c.getLinkmans().add(m1);

  c.getLinkmans().add(m1);

  联系人关联客户(设置客户引用的元素)

  m1.setCustomer(c);

  m2.setCustomer(c);

   使用session保存

   session.save(c);

  session.save(m1);

  session.save(m2);

  提交事务

  tr.commit();

单项关联

  客户关联联系人(获取联系人引用的set集合添加元素)

  c.getLinkmans().add(m1);

  c.getLinkmans().add(m1);

   使用session保存

   session.save(c);

  提交事务

  tr.commit();

 注意:由于m1,m2创建出来为临时状态(顺时态),没有OID,不能保存到数据库,故需要配置在Customer.hbm.xml文件的set标签中添加

   cascade="save-update" 属性,使customer在添加linkMans引用的时候让m1,m2从顺时态变成持久态

还可以通过session保存m1,m2让hibernate访问数据库的频率降低

  联系人关联客户(设置客户引用的元素)

  m1.setCustomer(c);

  m2.setCustomer(c);

   使用session保存

  session.save(m1);

  session.save(m2);

  提交事务

  tr.commit();

 那么需要在LinkMans.hbm.xml文件的<many-to-one>标签中设置cascade="save-update" 属性,使linkMans在添加customer引用的时候让c从顺时态变成持久态

 ************在开发的角度(一般采用在多对一的多方设置该属性)*************

相应的在做级联删除的时候就添加cascade="delete" 属性(但是要配置在一方,不然如果配置在多方,多方会有数据残留,故开发配在单方)

cascade取值:

none-----不使用级联    save-update----级联保存或者更新    delete----级联删除   delete-orphan----孤儿删除(只能应用在一对多关系)

all---除了delete-orphan的所有情况(包含save-update  delete)   all-delete-orphan-----包含了delete-orphan的所有情况(包含seve-update delete delete-orphan)

孤儿删除解释:在一对多的方腊中,可以将一的一方认为是父方,将多的一方认为是子方,孤儿删除就是在解除父子关系的时候,将子房记录直接删除。

 那么 如果我们只想删除多方的一条数据,就要使用到孤儿删除,例子:在Customer.hbm.xml文件中的set标签里设置cascade="delete-orphan" 属性

  获取客户

  Customer c = session.get(Customer.class,1);

  获取2号联系人

  LinkMan m2 = session.get(LinkMan.class,2);

  然后解除关系(获取客户引用的联系人集合,集合操作remove掉联系人2,然后利用hibernate快照机制就可以使联系人2被删除)

  c.getLinkMans().remove(m2);

**inverse属性可以用来维护外键,true的时候为放弃,flase时候为不放弃,设置在一方***

多对多:

User u1 = new User("霆锋");

 User u2 = new User("柏芝");

 Role r1 = new Role("演员");

 Role r2 = new Role("歌手");

 双向级联

//霆锋演员+演员

u1.getRoles().add(r1);

u1.getRoles().add(r2);

r1.getUsers().add(u1);

r2.getUsers().add(u2);

 //柏芝演员

 u2.getRoles().add(r1);

 r1.getUsers().add(u2);

 //session保存

session.save(u1);

session.save(u2);

session.save(r1);

session.save(r2);

 运行报错,原因是因为2个多方都进行了外键的维护,所以要让一方放弃外键的维护,在set标签中加入inverse=“true”属性

 

单向级联

配置单项级联属性cascade="save-update" 

//霆锋演员+演员

u1.getRoles().add(r1);

u1.getRoles().add(r2);

 //柏芝演员

 u2.getRoles().add(r1);

 //session保存

session.save(u1);

session.save(u2);

 

    

时间: 2024-11-08 12:06:02

Hibernate 内容记录的相关文章

struts2,json,ajax整合内容记录

使用ssh三大框架整合时关于struts2,json,ajax整合内容记录.这里写主要部分代码 action部分: 注意事项,action部分的返回值要有set和get方法,否则会报错. package com.hcj.action; import net.sf.json.JSONObject; import com.hcj.dto.User; import com.hcj.service.UserService; import com.opensymphony.xwork2.ActionSup

Cs231n课堂内容记录-Lecture3

Lecture 3 课程内容记录:(上)https://zhuanlan.zhihu.com/p/20918580?refer=intelligentunit (中)https://zhuanlan.zhihu.com/p/20945670?refer=intelligentunit (下)https://zhuanlan.zhihu.com/p/21102293?refer=intelligentunit 1.线性分类器(linear classifer): 我们总是希望得到一个函数f(x,w

Cs231n课堂内容记录-Lecture 6 神经网络一

Lecture 6 神经网络一 课程内容记录: (上)https://zhuanlan.zhihu.com/p/21462488?refer=intelligentunit (下)https://zhuanlan.zhihu.com/p/21513367?refer=intelligentunit 1.视频弹幕中关于课堂例子的解释: 1:我们通过学习训练集得到权重W1,对应于可以识别一些feature的模板. 2:输入新的数据X,结合W1,计算得到一个得分score(中间过程可能会再经过一些非线

Cs231n课堂内容记录-Lecture 7 神经网络二

Lecture 7 神经网络二 课程内容记录:https://zhuanlan.zhihu.com/p/21560667?refer=intelligentunit 1.协方差矩阵: 协方差(Covariance)在概率论和统计学中用于衡量两个变量的总体误差.而方差是协方差的一种特殊情况,即当两个变量是相同的情况. 协方差表示的是两个变量的总体的误差,这与只表示一个变量误差的方差不同. 如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值,另外一个也大于自身的期望值,那么两个变量之间

Mybatis内容记录

MyBatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .2013年11月迁移到Github. MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创建statement.手动设置参数.结果集检索等jdbc繁杂的过程代码.

http协议的一些内容记录

HTTP协议的官方定义进行归纳,得出4个关键点: 1.HTTP是建立在tcp/ip协议之上,面向应用层的超文本传输协议. 2.它由请求和响应组成,完全符合标准的客户端服务器的请求响应模型. 3.协议很轻便简单,并且请求与请求之间没有关联,是无状态的协议. 4.为了弥补这种无状态就需要使用http协议的扩展cookie,session等方法建立关联. 标准的http协议指的是不包含session,cookie是,application的http协议(无状态). 之所以说是无状态,服务器上肯定会有用

Hibernate ORM(2):Hibernate使用记录之一

#1 ORM文件中,<property>元素的access属性可以指定待持久化类属性的访问方式 1 <property name="userName" type="string" access="property"> 2 3 <column name="USER_NAME" length="20" not-null="true" /> 4 5 <

暑期完善 短学期实践工程 内容记录一

因先前一直在备考雅思,前不久刚刚告一段落,最近终于有时间把短学期内的工程内容捡起来完善.因为时隔已久不少技术性的内容遗忘情况还是挺重的. 近期主要优化完善了登录/注册页面的代码,添加了背景图片和一些细节上的改动,增加了返回主界面的按钮,修复了登录.注册两个功能块有时不能跳转的BUG,更改了使用的CSS样式并解决了有时样式不能正常显示等问题 下面附上代码 <login.jsp> <head> <base href="<%=basePath%>"&

Elasticsearch 权威指南 ---内容记录

第一节Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields 1.6小节"match" : { "about" : "rock climbing" } 会hit到两条记录如下: { ... "hits": { &