1、配置文件(hibernate映射文件):
让hibernate知道该怎么样去load,store持久化对象;
1.1 数据库忌讳的字段名
1) User
2) index
2、数据库表中一对多,多对一的关系解释:
一个省份本身就有一个表。一个城市本身也是一个表。
一个省份拥有多个城市,也就是说一个省份要对应多张城市表;
由此可见省份和城市的关系是:多对 一;
同理可以推出:城市和市民的关系是 一 对 多;
3在数据库中:
省份往往以ID的形式放在城市中作为索引;也就是说 往往只有多对一;
4、SessionFactory和 Configuration都是静态的,线程安全的对象;
而Session不是线程安全对象,所以一般情况下只能有一个Session;
Threadlocal.set(session):在ThreadLocal中创建一个Session对象变量副本
5、Transaction:
是数据库一个操作单元,具有4个特性:
1、原子性:同一个单元操作,要么全部录入,要么全部不要录入;
2、一致性:保证从一个一致状态迁移到另一个一致状态与原子性相关。
3、隔离性:多个并发事务之间不能相互干扰并发不影响事务的执行
4、持久性:一旦事务成功完成(Commit),它对数据库的更新应该是持久即使在写入磁盘之前,系统发生故障在下次启动之后,也应保障数据更新的有效
6、在配置中
〈property name = “propertyName”〉
name指的是实体类中的属性propertyName,如果没有指定此属性在数据库 中列的名字和数据类型,那就按照缺省模式;(即按照实体类属性来定义)。
<property name = “propertyName type = “string”>
这里的type指的是hibernate锁定的属性;
8、set的应用:
例如人与活动的关系:人和活动是多对多的关系;
那么可以先看一边:在人的表结构中创建一个set集合(用于存放活动)。
9、持久化类:
只有一些属性和简单的getter、setter方法的简单javabean类;
10、一个session代表一个单线程单元操作;
一般这个session单元操作会被绑定到应用程序的java线程,当session被用完之后,hibernate会让session从当前应用程序java线程脱离,并关闭;当你从调用getSessio():你会得到新的Session
11、在加载了持久化类之后:
使用普通的集合方法就可以很容易地修改我们定义的集合。Hibernate就会自动检测到集合已经被修改并需要更新回数据库。(自动脏检查)。
12、Session.load(class,serializable); 加载出来的持久化对象是指数据库里的表,是一个空的实例化对象?
加载出来的对象是根据serializable条件加载出来的持久化对象,并且他并非一个空对象,而是一个加载了数据库里一条记录的持久化对象;
13、Java对象在JVM中的生命周期:
创建一个Java对象时,JVM会为这个对象分配一个内存空间,只要这个对象被引用变量引用,就一直存在于内存中,如果一个对象不被任何引用变量引用,就结束生命周期。Java集合(List、Map、Set)存放的是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.4、Session的操作图:
15.1、数据库中是不讲究大小写的;
15.2、不能把表明随便定义为user;
17.hibernate查询
17.1sql与hql的根本分别
17.1.Hql 以对象为单位,
17.2.sql以数据库字段为单位
17.2外键为空引发的问题
使用select查询的hql和sql语句查询中,若查询字段中出现外键并且此时外键值为空时,会出现结果集也为空的情况;
/*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,他们都可以查到这个表里所有的数据。无须再怀疑。
17.6 sql查询
使用sql查询,需要注意两个点
- 确定dababase与schema,表名(Goods),查询时需要写成DBName.dbo.Goods
- 面向表,与字段,而不是对象;