hibernate框架技术重点学习笔记
1.针对不同的数据库,有不同的数据库实现类,使其符号对应的数据库?
mysqlDaoImpl oracleDaoImpl ... ...
2.对象和表记录的转换存在着转换问题->orm,对象和关系的一种映射
3.框架:解决一种问题的方案集合!
4..配置文件
Xxx.cfg.xml 主配置文件
xxx.hbm.xml映射文件:
映射基础
普通属性
主键
集合属性
关联关系:一对多 多对一 多对多 一对一
继承结构
5.其他特性:数据库连接池 懒加载 二级缓存 一级缓存
6.hibernnate中主要的API:
configuration :配置对象
Configure()
Configure(String resource)//读取指定位置处的配置文件
AddResource(String Resource)//导入指定位置的配置文件
addClass(Class class) //导入与指定类在同一个包中的以类名为前缀,后缀为.hbm.xml的映射文件
buildSessionFactory:session工厂
sessionFactory:session 工厂
openSession//打开session
getCurrentSession//得到当前的session
Close()//关闭session
session对象:
Save(object) update(object) delete() createQuery() createCriteria()
Transaction事务
Commit() rollback()
Query:查询
List() 查询一个结果集合
uniqueResult() 查询一个唯一的结果 只有一个结果就返回 没有就返回null 多个就抛异常
7.hibernate.cfg.xml的配置文件:
基础6项:方言+jdbcurl+驱动类+用户名+密码+导入映射文件
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置数据库 -->
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/myhibernate</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 导入映射文件 -->
<mapping resource="user.hbm.xml"/>
</session-factory>
</hibernate-configuration>
8.对象名.hbm.xml文件:
对象和数据库表的对应关系
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="domain">
<!-- class元素是指定的类与表的对应关系 -->
<class name="User" table="tb_user">
<id name="id" type="integer" column="id">
<generator class="native"/>
</id>
<property name="name" type="string"></property>
</class>
</hibernate-mapping>
-------------------------------------------------------
Name属性:对象的属性名
Type属性:如果不写会自动检测,为了避免歧义会写。
可以写java中类的全名java.lang.String
Hibernate中string
Column:对应表中的 列名,如果没有的话,对应属性名
Length:长度属性:如果不写,默认为255,varchar有。
9.自动建表技术:
在配置文件中加入<property name=”hbm2ddl.auto”>create</property>
Create:先删除,再创建
Update:如果表不存在就创建,不一样就进行更新,一样,就不做.
Create-drop:初始化时建表,sessionFactory执行close(),删除表。
Validate:验证表结构是否一致,如果不一致,就抛异常。
10.主键生成策略:
Identity sequence hilo native assigned uuid foreigns
Identify:使用数据库自己的主键的生成策略。
11.映射:
在自动建表的情况下,利用set list map集合关联数据表
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="ysDao">
<!--类与表的对应关系 -->
<!--User实体类对应与user_addressSet表和user_addressList表 -->
<!-- table是集合表的名称 element:子元素存放集合元素的列的信息 key:引入的外键信息 index:索引信息-->
<class name="User" table="my_user2">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- addressSet属性 set集合 -->
<set name="addressSet" table="user_addressSet">
<key column="userId"></key>
<element type="string" column="address"></element>
</set>
<!-- addressList属性 list集合 -->
<list name="addressList" table="user_addressList">
<key column="userId"></key>
<list-index column="idx"></list-index>
<element type="string" column="address"></element>
</list>
</class>
</hibernate-mapping>
12.维护关联关系:
一对多/多对一内涵:
修改和设置外键的值
多对多内涵:
就是在中间表中修改和删除记录。
13.casade:级联
默认为none,代表不级联,是指操作对象时,对关联的对象也做相同的操作,
可以设为save-update delete all none.
14.单向关联:多项关联:
15.临时状态
与数据库没有对应,和session没有关联
一般是新new出的对象
16.持久化状态
再session的管理之中,最终会有对应的数据库记录
对对象的修改会同步到数据库中。
18.游离状态
数据库中有对应的记录,但对象不在session的管理内。
19.
Update: 把游离状态转换为持久状态
SaveOrUpdate:把临时或者游离状态转换为持久状态
Delete: 把持久或者游离状态转换为删除状态
Get: 持久化状态
Load: 持久化
20.
Session.refresh();刷新session缓存,重新去select下
21.
在hibernate.cfg.xml配置:
<property name=”xonnection.isolation”></property>
数据库隔离级别:
读未提交:1 0001
读已提交:2 0010
可重复读:4 0100
串行化: 8 1000
22.
单向关联:
单向一对多 单向多对一 单向多对多
在单向一对一的关联关系中,只能做从有外键方到无外键方的单向的关联。
维护关系时,必须从有外键方去设置关系。
23.
hibernate检索对象的方式:
Get()方法
OID方法 session.get()/session.load()
HQL检索方法,使用面向对象hql检索方法
QBC:使用query by criteria api检索对象,分装了基于字符串形式的查询语句。
24.使用hql语句进行查询
特点:
1)与sql语句相似
2)sql查询表和表中的列,hql查询对象和对象的属性
3)Hql关键字不去区分大小写,类名和属性名是区分大小写的
4)Select 可以省略不写
25.
//hql简单查询:
Hql=”select * from baoming.User”;
//是否写全限定名,是由实体类的映射文件中,auto-import决定的,默认为true,表示不用显式写包名,为false时,必须查询实体类的全限定名。
Hql=”FROM baoming.User”;
//执行查询
Query query = session.createQuery(hql);
List list = query.list();
//显示结果
for(Object obj:list){
System.out.prinltn(obj);
}
//使用别名
Hql=”FROM employee as e”;
//加入条件
Hql=”FROM employee e where e.id<10 AND e.id>5”;
//加入排序条件,按照name进行降序排序
Hql=”FROM employee e where e.id<10 ORDER BY e.name DESC”;
//先按照第一个进行排序,相同按照第二个排序
Hql=”FROM employee e where e.id<10 ORDER BY e.name DESC,id ASC”;
//查询某个列,查询name和id
Hql=”select e.name e.id from employee e”;
//通过new 方法,将查询出的属性 作为对象的构造参数
Hql=”select new Employee(e.id,e.name) from employee e”;
//输出时:
List list=Session.createQuery(HQl);
For(Object obj :list){
If(obj.getClass().isArray()){
Sop(Array.toString((Object[]) obj)_;
}else{
Syso(obj);
}
}
//执行分页查询
Query query= session.createQuery(“FROM Employee”).
query.setFirstResult(0);
Query.setMaxResults(10);
List list = query.list();
//需要查询的结果唯一时,没有查询到的结果就null,有多个就报错,一个就正常返回
Employee employee = (Employee)query.uniqueResult();
//hql高级查询
26.聚集函数:
Count() max() min() avg() sum()
//数目
Hql=”select count(*) from Employee”;
Long result = session.createQuery(Hql).uniqueResult;
//最大值
Hql=”select max(id) from Employee”;
//最小值
Hql=”select min(id) from Employee”;
//分组查询,按照名字来分组,查询的是名字和该组下的id数目值
Hql=”select e.name,COUNT(e.id) FROM Employee e where e.id<9 GROUP BY e.name”;
注意:
在查询过程中,聚合语句要比having子句优先执行,比where子句后执行。
Where 是具体来进行分组的,having 是对分组后的结果进行过滤的,比如控制分组中,内容大于1条才显示等。
例如:
Hql=”select e.name,COUNT(e.id) FROM Employee e where e.id<9 GROUP 27.级联查询,有外键关系。
//基本sql语句
employee表中有departmentId外键属性列,使用on查询条件指定查询范围
inner内部连接:都有记录才查询
Select e.id,e.name,d.name FROM employee e join department d on e.departmentId=d.id;
left连接: 以左边为准
Right连接: 以右边为准
//hql语句,进行连接查询
Select e.id,e.name,e.department.name from Employee e;
//查询时设置参数
使用?占位
如:Hql=”FROM Employee e where id=?”;
List list=session.createQuery(hql).setParameter(0,5).list();
设置第一个参数的值为5,第一个参数索引为0
如:Hql=”FROM Employee e where id between ? And ?”;
List list=session.createQuery(hql).setParameter(0,5).setParameter(1,10).list();
查询id位于5到10之间的
使用变量名
当id值是多个的时候,利用设置参数列表,第一个参数为变量名,第二个参数为id的变量集合
Hql=”FROM Employee e where id IN(:ids)”;
List list = session.createQuery(hql).setParameterList(“ids”,new Object[]{1,2,3,4,5}).list();
27.使用update和delete
Int result=session.createQuery(“UPDATE Employee e SET e.name =? Where e.id>10”).setParameter(0,”xjq”).executeUpdate();
执行更新和删除的语句,设置第一个?占位符为xjq,并执行更新。
返回一个int型的结果,表示影响了多少行。
注意:update和delete不去去通知缓存的,当更新数据库了,但是如果这个时候去直接查询的话,查的是session中的值,所以必须去更新obj对象,再去查询!
刷新要查询的对象:Session.refresh(obj);
28.回顾总结:
1)一对一的关联关系映射(外键+唯一性约束)
基于外键的关联映射
有外键方:
<many-to-one name=”obj” class=”...” column=”...” unique=”true”>
</many-to-one>
无外键方:
<one-to-one name=”...” class=”...” property-ref=”obj”>
</one-to-one>
基于主键的映射
有外键方:
<one-to-one></one-to-one>
无外键方:
<one-to-one></one-to-one>
2)hql查询对象,属性,写的时候全部为类名和属性名
关键字不区分大小写,类名和属性名区分大小写。
语法顺序:
SELECT 别名/属性名/表达式
FROM 实体 AS 别名
Where 过滤条件
Group by 分组条件
Having 分组后结果的查询条件
Order by 排序条件
29.懒加载:
不是在执行获取操作时马上去生成sql语句,而是在真正需要时才去查询数据库生成sql语句
级别:类级别
<class ...lazy=”true”>
属性级别
<set/list/map/bag...lazy=”true”>
<many-to-one>
<one-to-one>
理解:对于一定会用到的就直接去全部加载,对于可能不会用到的就去懒加载。
对应于load方法,在真正需要时才去查数据库
Lazy属性:默认为true
True:在第一次使用时就去加载,在真正去查get时才去执行真正的select语句
False:立即加载,在获取本对象时就去加载
Extra:增强的懒加载策略
懒加载异常:就是将要查询的东西放在了session关闭之后,session已经关闭了,将不会去重新查数据库
解决方案:
1)调整查询语句的位置,让session真正加载后再去关闭
2)Hibernate.initialize(obj);先去初始化对象
30.缓存机制:
一级缓存:session中的缓存
二级缓存:sessionFactory中的缓存,不经常被更新的,又是常用的。省市联动的情况。
使用二级缓存(应用级别的缓存):
在主配置文件中:
<property name=”cache.provider_class”>指定缓存提供商 </property>
//指定要缓存的实体类,对其使用的操作读写,全限定名
<class-cache usage=”read-write” class=”包名.Employee”>
//指定要缓存的集合,对其使用的操作读写,全限定名
<collection-cache usage=”read-write” collection=”包名.实体类.集合名”>
注意:
只有使用oid时,即get load 方法时才会去使用一级和二级缓存,
对于queryList()查询方式则不会使用从缓存中取,但是会将查询结果放在缓存中。