hiberante学习笔记

 

1、配置文件(hibernate映射文件):

hibernate知道该怎么样去loadstore持久化对象;

1.1 数据库忌讳的字段名

1) User

2) index

 

2、数据库表中一对多,多对一的关系解释:

一个省份本身就有一个表。一个城市本身也是一个表。

一个省份拥有多个城市,也就是说一个省份要对应多张城市表;

由此可见省份和城市的关系是:多对 一;

同理可以推出:城市和市民的关系是 一 对 多;

 

3在数据库中:

省份往往以ID的形式放在城市中作为索引;也就是说 往往只有多对一;

 

4SessionFactory和 Configuration都是静态的,线程安全的对象;

Session不是线程安全对象,所以一般情况下只能有一个Session;

Threadlocal.set(session):在ThreadLocal中创建一个Session对象变量副本

 

5Transaction

是数据库一个操作单元,具有4个特性:

1、原子性:同一个单元操作,要么全部录入,要么全部不要录入;

2、一致性:保证从一个一致状态迁移到另一个一致状态与原子性相关。

3、隔离性:多个并发事务之间不能相互干扰并发不影响事务的执行

4、持久性:一旦事务成功完成(Commit),它对数据库的更新应该是持久即使在写入磁盘之前,系统发生故障在下次启动之后,也应保障数据更新的有效

 

6、在配置中

property name = “propertyName”〉 

name指的是实体类中的属性propertyName,如果没有指定此属性在数据库 中列的名字和数据类型,那就按照缺省模式;(即按照实体类属性来定义)。

 

<property name = “propertyName type = “string”>

这里的type指的是hibernate锁定的属性;

 

8set的应用:

例如人与活动的关系:人和活动是多对多的关系;

那么可以先看一边:在人的表结构中创建一个set集合(用于存放活动)。

 

9持久化类:

只有一些属性和简单的gettersetter方法的简单javabean类;

 

10、一个session代表一个单线程单元操作;

一般这个session单元操作会被绑定到应用程序的java线程,当session被用完之后,hibernate会让session从当前应用程序java线程脱离,并关闭;当你从调用getSessio():你会得到新的Session

 

11、在加载了持久化类之后:

使用普通的集合方法就可以很容易地修改我们定义的集合。Hibernate就会自动检测到集合已经被修改并需要更新回数据库。(自动脏检查)。

 

12Session.load(class,serializable); 加载出来的持久化对象是指数据库里的表,是一个空的实例化对象?

加载出来的对象是根据serializable条件加载出来的持久化对象,并且他并非一个空对象,而是一个加载了数据库里一条记录的持久化对象;

13Java对象在JVM中的生命周期:

创建一个Java对象时,JVM会为这个对象分配一个内存空间,只要这个对象被引用变量引用,就一直存在于内存中,如果一个对象不被任何引用变量引用,就结束生命周期。Java集合(ListMapSet)存放的是Java对象的引用,当向集合中添加一个对象时,其实是把这个对象的引用添加到集合中。因此集合中含有的对象生命周期一直存在。

 

 14理解Session的缓存:

Session接口的实现中定义一系列的Java集合,这些集合构成了Session的缓存。

Session缓存的作用:

1、减少访问数据库的频率,可以提高数据库访问的性能。

2、保证缓存中的对象与数据库中的相关记录保持同步。

3、当缓存中的持久化对象(位于缓存中的对象)之间存在循环关联关系时,Sessioin会保证不出现访问对象的死循环。

 

14、持久化对象的3个状态:

14.1 瞬时(transient)状态:

该实例是刚用new语句创建的,还没有被持久化,不处于任何Session的缓存中。它没有持久化标识(相当于主键值)。处于瞬时状态的实例被称为瞬时对象。它的特点是:

不和任何一个Session实例关联。在数据库中没有对应的记录

没有持久化标识(即没有主键值)

14.2   持久化(persistent)状态:

已经被持久化,加入到Session缓存中。处于持久化状态的实例被称为持久化对象。

实例目前与某个Session有关联。 它拥有持久化标识(相当于主键值),并且可能在数据库中有一个对应的行。 Hibernate保证在同一个Sesion实例的缓存中,数据库中的每条记录只对应唯一的持久化对象。 它的特点是:

       持久化对象总是被一个Session实例关联。持久化对象和数据库中的相关记录对应。Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库

有持久化标识(即有主键值)

14.3 脱管(detached)状态:

已经被持久化过,但不再处于Session的缓存中。处于脱管状态的实例被称为脱管对象。实例曾经与某个持久化上下文发生过关联,不过那个上下文(session被关闭了, 或者这个实例是被序列化(serialize)到另外的进程。 它拥有持久化标识,并且在数据库中可能存在一个对应的行。 对于脱管状态的实例,Hibernate不保证任何持久化标识和Java标识的关系。它的特点是:

不再位于session的缓存中,即它不再和session关联。它拥有持久化标识(即没有主键值)

14.4Session的操作图:

 

151、数据库中是不讲究大小写的;

15.2、不能把表明随便定义为user

 

17.hibernate查询

17.1sqlhql的根本分别

17.1.Hql 以对象为单位,

17.2.sql以数据库字段为单位

17.2外键为空引发的问题

使用select查询的hqlsql语句查询中,若查询字段中出现外键并且此时外键值为空时,会出现结果集也为空的情况;

/*String sql = DAOUtil.generateSql("Goods", condition);*/

/*String sql = "select g.goods_Id,g.goods_No,g.goods_Name,g.goods_Image,g.market_Price," +

"g.VIP_Price,g.discount,g.isVisible,g.stock,g.goods_CateChild.goods_CateChild_Id," +

"g.goods_CateChild.goods_CateChild_Name,g.activityGoodsType.activityGoodsType_Id," +

"g.activityGoodsType.activityGoodsType_Name from Goods g";*/

/*String sql = "select g.goods_Id,g.goods_Name,g.goods_CateChild.goods_CateChild_Name," +

"g.goods_CateChild.goods_CateChild_Id,g.activityGoodsType.activityGoodsType_Id, " +

"g.stop_date from Goods g";*/

/*String sql = "select * from DBQihang.dbo.Goods";*/

/*String sql = "from Goods";*/

/*String sql = "select g.goods_Id,g.goods_No,g.goods_Name,g.goods_Image,g.market_Price," +

"g.VIP_Price,g.discount,g.isVisible,g.stock,gt.goods_CateChild_Id,gt.goods_CateChild_Id," +

"gc.activityGoodsType_Id,gc.activityGoodsType_Name from DBQihang.dbo.Goods g," +

"DBQihang.dbo.Goods_CateChild gt,DBQihang.dbo.ActivityGoodsType gc " +

" where gt.goods_CateChild_Id=g.goods_CateChild_Id and gc.activityGoodsType_Id=g.activityGoodsType_Id" +

" order by goods_Id";*/

//由于外键为空导致的问题

/* String sql = "select g.activityGoodsType.activityGoodsType_Id,g.activityGoodsType.activityGoodsType_Name" +

" from Goods g";*/

17.3外键lazy怎么办?

使用hibernate之初我也非常地疑惑,如果把外键设置为lazy,那么我还能不能拿到外键的id呢,经过验证,是可以的。

事实上,你可以把lazy当成懒惰,就是当你不向它要的时候我就不查,当你查完之后还要这个数据时,他会自己查给你,不需要 你自己去手动查找。

17.4外键为null怎么办?

外键为null,会给你的查询带来诸多不便。在设计的时候必须考虑并事先做好处理报错的一些动作。

 

例如if(list.get(0).getGoods_CateChild() != null){

System.out.println(list.get(0).getGoods_CateChild().getGoods_CateChild_Id());

}

17.5select * 或者 from

前者是sql,或者hql,他们都可以查到这个表里所有的数据。无须再怀疑。

176 sql查询

使用sql查询,需要注意两个点

  1. 确定dababaseschema,表名(Goods,查询时需要写成DBName.dbo.Goods
  2. 面向表,与字段,而不是对象;
原文地址:https://www.cnblogs.com/apem/p/3480853.html