Annotation:注解
注解是写个程序看的,是给别的程序看的.不是给人看的 ,是对代码的说明
如果想把一个类交给hibernate来处理,在类前加@Entity即可. 表示将由hibernate来管理这个类
hq语句关键字大小写不敏感 但对类名 包名 属性名 敏感
将查询语句查询的结果封装到list中,不要存在result里. 存在result中如果连接被关闭,则数据不能使用. 存在list中如果连接关闭则数据依然可以被其他类使用.
在sesssion的一级缓存中 ,什么样的数据可以放在缓存中?
(1 不经常改动的数据放在缓存 中. 如果一个数据从数据库取出来就一定会发生变化的话 ,那么这个数据不应该放在缓存中. 因为数据发生变化后如果不立即写入数据库而又不从缓存清楚它 ,再次去数据时 ,框架先重缓存中查找,
这时查出的数据可能是没有经过改变的数据.
在类定义前写: @Cache(usage=CacheConcurrencyStartegy.READ_WRITE) 表示所有的该类对象都会被放进二级缓存
get 和 load 都会使用二级缓存
如果查询不到结果 , get返回 一个Null load返回一个异常
如果查询班级对象, 班级对象里有关联很多学生(n个) ,那么底层会发送一个查询班级的语句, 发送 n个查询学生的语句 . 即n+1条语句. 效率不高.
这是可以对班级里的学生属性用 OneToMany ( fetch) 属性设置为懒加载 , 只向数据库发送一条查询班级的语句, 对于学生属性则返回一个代理 ,当真正要是要学生属性数据时在生成sql语句去查询.
或者用list将数据放入二级缓存 ,这样即使第一次查询数据较慢 ,但之后数据查询会向二级缓存查询, 命中率高 .也可以提高效率.
list直接向数据库取数据 ,并将其放入二级缓存 ,但它在查询时不去找二级缓存, 直接去数据库找 , iterate 在查询时则依赖于二级缓存 .
事物隔离级别:
从低到高: 读取未提交 读取已提交 可重复读 序列化
读取未提交: 读数据不会阻塞读数据和写数据 写数据不会阻塞读数据 ,但会阻塞写数据. 写事物不阻塞读事物,读事物可以读取未提交的数据,容易造成脏读现象.
读取已提交: 写事物会阻塞读事物和写事物 读事物不会阻塞写事物和读事物 读事物不阻塞写事物,但有可能造成数据不可重复
可重复读: 读事物不会阻塞读事物 , 但会阻塞写事物. 写事物会阻塞读事物和写事物 读事物不阻塞读事物,会造成幻读问题
序列化: 最严格的隔离机制 , 不会出现脏读,幻读, 不可重复读的现象 ,通过锁表实现 . 读数据时将整个表锁住. 效率极低
事物隔离级别的二进制: 0001 0010 0100 1000 对应数字: 1 2 4 8
级别越高效率越低
乐观锁:
通过在表中增加一个version版本字段来实现.每次提交完 一个事务version加1.用来表示数据已更新.
一个事务在读写操作时 ,会查看version字段, 在最初读取时version为1, 事务在经过一系列数据更新后,准备将更新过的数据向数据库提交,再提交前 ,会重新检查数据库中的version字段,如果为2 ,表示在 事务
操作数据的过程中已经有其他事务更改了数据库中的数据,那么该事务则不再提交数据, 更新失败. 如果检查的version字段为1 ,表示该事物在更新过程中没有其他事务对数据进行操作.则可以继续提交事务.
悲观锁:
悲观锁是直接在数据库中加锁, 写法上, get方法里传一个参数即可. 悲观锁提供4个参数.具体百度