Hibernate学习小结
2017-07-29 20:45
447 查看
hibernate学习小结
<----------------------------------------------------->
hibernate的持久化
1.狭义的:数据从不能断电的设备保存到能断电的设备上
2.广义上的:指的是和数据库相关的操作,增删改查,加载;加载:指的是根据OID查询数据库中的一条
具体的记录
OID:Object ID,特指java对象中与数据库表的主键相对应的一个属性;即表的id与javabean中表的id
属性一致
<--------------------------------------------------------->
hibernate的搭建环境
1.导入jar包(可以利用maven的依赖,网上下载),数据库驱动(jar包maven依赖)
2.创建hibernate自身的配置文件:hibernate.cfg.xml(文件名字固定,普通项目放在src下。maven项
目放在src/main/resources)
//头部文件
<!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="hibernate.connection.url">jdbc:mysql://localhost:3306/20170610</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 在控制台中打印出sql语句 -->
<property name="show_sql">true</property>
<!-- 映射关系。资源的值是java下的映射表的对应路径-->
<mapping resource="com/qf/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.创建持久化的类对应的关系映射文件:(pojo类,domain,entity,beans,数据模型类)
放在src下或者maven项目的src/main/java下
要求:[1]有无参构造函数。[2]有OID属性;[3]有getter,setter方法;[4]非final类
4.创建持久化类对应的关系映射文件:Xxxx.hbm.xml(固定格式,与实体类放在一起,同一包下)
//头部文件:同hibernate.cfg.xml头部一样
<hibernate-mapping>
<class name="实体类的全类名" table="数据库的表名">
<id name="id" type="int">
<generator class="native"></generator>//class中有多个可选择值
</id>
<!--接下来是实体类的除了id之外的所有属性-->
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
5.Hibernate中重要的API(hibernate4以后版本)
5.1.Configuration:负责管理hibernate的配置信息。
hibernate.cfg.xml文件中的信息:数据库URL地址、用户名、密码、jdbc驱动、数据库连接池的桉
树等。
Xxxx.hbm.xml文件中的信息:持久化类与数据库表之间的对应关系。
5.2.Transaction代表一次数据库事务。
hibernate主张把所有持久化操作都纳入到事务中,哪怕仅仅只是只读操作
5.3.Session代表hibernate应用程序和数据库之间的一次会话。
作用相当于JDBC中的Connection,其中封装了一系列的操作方法,并包含缓存功能
5.4.SessionFactory用于创建Session对象的工厂
SessionFactory对象一旦构造完毕,即被赋予特定的配置信息,构造SessionFactory很消耗资源,
一般情况下一个应用只初始化一个SessionFactory对象;在hibernate4新增了一个ServiceRegister接
口,所有基于hibernate的配置或者服务都必须统一向这个SessionFactory注册后才能生效。
创建SessionFactory的步骤:创建Configuration对象;在ServiceRegister对象中注册配置信息;
通过Configuration对象构建SessionFactory对象
hibernate的hellowolrd:
public class hb_helloworld{
public static void main(String[] args){
Configuration config = new Configuration().configure();
ServiceRegistyBuilder srb = new ServiceRegistyBuilder().applySettings
(config.getProprties ());
ServiceRegisty sr = srb.buildServiceRegisty();
SessionFactory factory = config.buildSessionFacory(sr);
Session session = factory.openSession();
//创建一个实体类对象
Users users = new Users();
users.setName("张四");
users.setSex("男");
users.setAge(22);
//开启事务
Transaction tr = session.beginTransaction();
//保存对象(insert操作)
session.save(user);
//修改操作(update操作)
users.setId(1);
users.setName("qqww");
users.setSex("女");
users.setAge(19);
session.update(users2);
session.saveOrUpdate(users);//当OID为null时。可以执行insert操作
//查询操作(select操作)
Users users2 = (Users) session.get(Users.class,3);
Users users3 = (Users) session.load(Users.class,2);//延迟检索操作。即只
是查询操作,不执行sql语句,当对属性操作时。才执行查询操作
System.out.print(users2+"--"+users3)
c397
//删除操作(delete操作)
users.setId(1);
session.delete(users);
//提交事务
tr.commit();
session.close();
factory.close();
}
}
6.Session的一级缓存
Session接口是hibernate向应用程序提供的操纵数据库的最主要接口,他提供了最基本的增删改查方法
每一个session对象都在内存中维护了一个缓存。被称作一级缓存,即两次调用get方法查询同一条记录
,hibernate只会发送1条sql语句,因为session中有缓存。第二次调用时,直接从session缓存中取得
,从而也减少了多数据库的访问次数
7.持久化对象的四种状态
7.1.临时状态:OID:无;session缓存:无;数据库对应记录:无。刚new出来的对象
7.2.持久化状态:OID:有;session缓存:有;数据库对应记录:有。get查询操作后
7.3.游离状态:OID:有;session缓存:无;数据库对应记录:有。new一个对象,并set与数据一条
记录相同的数据
7.4.删除状态;OID:有(但无效);session缓存:无;数据库对应记录:无
8.Session的核心方法
save():可以将一个临时对象转化成持久化对象,可以不要临时对象中的OID,持久化的对象OID不允
许修改
persist():用处和save()一样,但是不允许保存带有OID的对象,会抛异常
get():根据OID的值。从数据库中立即加载一个对象到内存中,当session缓存中有时,则不会发送sql
语句,直接从缓存中取值
load():采用延迟检索策略。在调用load()后返回一个代理对象,不发生sql语句,在用到非OID值
时,才发送sql语句,当通过OID没有找到时,会报异常
update();对数据库进行更新操作,使用update()更新一个OID不存在的对象会抛出异常
saveOrUpdate():有更新和保存两种功能,当OID不存在时,会执行更新操作。OID存在时,会执行更新
操作
delete():根据OID,进行删除操作;
9.在hibernate环境下执行原生的jdbc代码;
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
//使用传入的Connection对象实现原生的JDBC操作...
}
});
10.表与表之间的映射关系
hibernate中使用 实体类名.hbm.xml.文件来定义持久化类和数据库表之间的映射关系
持久化类对应的数据库中的表,持久化属性对应的是数据库表中的字段
当然除了xml配置文件之外,hibernate也支持注解的形式进行配置
11.xml中<property>中元素属性说明
name:持久化对象的属性名;
type:通常用来指定hibernate映射的数据类型(可以使用java类型,也可以使用hibernate数据类型
);hibernate类型:integer,string,character,date,timestamp,float,object,blob等。
column:对应的数据库的字段名;
not-null:属性中不能为空;
length:属性的长度;
unique:是否唯一;
12.hibernate中的主键生成方式:<generator class="">
此处介绍常用的有:native:由hibernate判断数据库,并且由数据库本身生成主键;
identity:数据库为MySQL的数据库,由数据库本身生成主键id;
increment:由hibernate查询数据库,并在原先数据的id加1生成,和底层数据库的类型没有关系;
foreign:生成的是外键。
13.java中大对象类型的hibernate映射
长字符串:长度超过255的字符串时,用text
二进制数据:图片、音频、视频等文件以二进制保存到数据库;
TinyBlob:255字节;Blob:65kb;MediumBlob:16mb;LongBlob:4GB.
14.在hibernate中对于大的文件,可以以blob的方式存入(如图片直接保存在数据库)
保存
FileInputStream in = new FileInputStream(1.png);
Blob picture = Hibernate.getLobCreator(session).createBlob(in,in.available());
读取
InputStream in = blob.getBinaryStream();
15表关系
[1].表关系之多对一
例如:有一个学生表(student,多)和一张成绩表(score,一);一个学生有多门成绩
单向多对一:首先,分别创建持久化类;齐次,创建对应的实体类.hbm.xml;最后,添加映射关系配
置信息。
双向多对一:设置玩单向多对一后,在one的一段同意步骤设置信息。即形成双向关系。
hibernate.cfg.xml中表的mapping能手动生成
many一端设置:
实体类(Student)中添加上:private Set<Score> scores;然后的对应的getter、setter方法
Student.hbm.xml文件中:
<set name="scores" table="score">
<key>
<column name="对应的外键名或者在score表中的对应学生表的id" />
</key>
<one-to-many class="com.zdl.bean.Student" />
</set>
one的一端设置:
实体类(Score)中添上:private Student studrnt;
Score.hbm.xml文件中:
<many-to-one name="student" class="com.zdl.bean.Student" column="对应的外键名或者在
score表中的对应学生表的id" />
[2].表关系之一对一
例如有部门经理(manager)和部门(department)两张表;一般一个部门只有一个经理(一个经理
也只管一个部门)
分别在把其他类的对象当做属性写在自己的类中
Manager实体类中:private Department department;
Department实体类中:private Manage manager;
hbm.xml文件中:
Manager.hbm.xml中:
<one-to-one name="department" class="com.zdl.bean.Department"/>
Department.hbm.xml中:
设置外键(也可以给manager设置 constrained="true" 为外键约束)
<generator class="foreign">
<param name="property">manager</param>
</genertor>
<one-to-one name="manager" class="com.zdl.bean.Manager" constrained="true"/>
[3].表关系之多对多
例如:一个学生可以学习多门课程,一门课程可以有多个学生
两个实体类设置:需要添加对方的set<类名> 属性;
xml文件中:添加两个<set>和<many-to-many /> 标签
16.当为两张表中同时插入一个学生和他的成绩时,往往会报错(一起save)或者分为两步完成
为了解决一次save报错的问题。需要在many一端的set中添加元素:cascade="save-update"
或者cascade="all";all中包含了多种操作方法;cascade为是否级联其他表,默认为none。
17.inverse属性:inverse="true"表示的是只需要指定另外一方来维护关联的记录
<---hibernate的检索方式------------------------>
18.hibernate中的检索方式
[1].OID检索方式:按照对象的OID来检索对象get/load;
[2].对象图导航检索方式:获取到的当前类的属性是其他类的对象,然后获取其他类对象的属性;
如:user.getBook().getBookName();
[3].HQL检索方式:使用面向对象的hql(hibernate query language)查询语言
hql是使用最广的一种检索语言(hql语句关键字不区分大小写,但是java类名严格区分大小写)
(1)FROM子句(查询员工表中全部员工)
from Employee;//Employee是java类类名,而不是表名;下同。
(2)WHERE子句(此时的后面条件依旧是java类中的属性,而不是表字段)
from Employee e where e.salary>6000;
(3)使用基于位置的占位符参数:?(和sql语句一样)
from Employee e where e.salary>?;
填充占位符:query.setDouble(0,8000.00);0表示参数位置(从0开始!)
使用具名参数:格式为":参数名称(自定义)"
from Employee e where e.salary>:salary;
填充占位符:query.setDouble("salary",8000.00);
以实体类对象作为参数(有表的级联关系)
from Employee e where e.department=?;
Department department = new Department();
department.setDeptId(1);
填充占位符:query.setEntity(0, department)
(4)order by子句(desc:降序;asc(升序,默认))
from Employee e where e.salary>6000 order by e.salary desc
(5)分页查询;当前页的页码:pageNo;一页显示多少条数据:pageSize
Query中定义了两个相关函数
setFirstResult(int index);指定查询结果从index位置开始。可以从0取值
setMaxResult(int maxResult);指定查询结果显示多少条数据
index和pageNo的关系:index=(pageNo-1)*pageSize;
(6)投影查询方式(即查询一张表的部分字段对应的是java类中的部分属性)
方式一:返回值形式是一个泛型为object[]
Query query = session.createQuery(hql);
List<Object[]> objs = query.list();
for(Object[] o :objs){
System.out.println(o[0]+"-"+o[1]);
}
方式二:返回值的泛型任然是实体类的对象,但是需要在实体类中的提供对应的构造器
select new Employee(e.name,e.salary) from Employee e
(7)多表查询(返回泛型的是数组,也可以写个所有属性的实体类,写上构造器,使用对象)
from Student s,Score sc where s.id=sc.stuid;
from Student s inner join Score sc on s.id=sc.stuid;
(8)报表查询使用group by和having配合起来使用进行分组,再结合统计函数进行报表查询)
select min(e.salary),max(e.salary)from Employee e
group by e.department having min(e.salary)>3000;
(9)子查询:查询部门名以A开头的部门的员工姓名和部门名称
select e.name,e.department.deptname from Employee e
where e.department in(from Department d where d.deptname like 'A%');
[4].QBC检索方式:使用qbc(query by criteria)API来检索对象。
//1.创建Criteria对象
Criteria c = session,createCriteria(Employee.class);
//2.取得查询结果
List<Employee> list = c.list();
uniqueResult()方法获取单一的记录的查询结果(例如登录)
(1)条件查询:Restrictions(各种条件都封装这个类中了)
多个条件可以add添加,如c.add(like).add(gt).list();
例如:模糊查询:like;判等:eq;大于:gt;小于:lt;大于等于:ge;
小于等于:le;在两者之间:between num1 and num2;
包含:in;
(2)and 和 or 的使用(也可以互相嵌套使用)
Conjunction表示and;Disjunction()表示or。
//创建and条件对象
Conjunction c = Restrictions.conjunction();(默认的就是and的对象)
//创建or条件对象
Disjunction d = Restrictions.disjunction();
add(d).list();
(3)报表查询Projections(单个统计函数);ProjectionList(多个统计函数)
AggregateProjection max = Projection.max("salary");
AggregateProjection min = Projection.min("salary");
ProjectionList pList = Projections.projectionList();
projectionList.add(max).add(min);
List<Object[]> list session.createCriteria(Employee.class)
.setProjection(pList).list();
(4).group by分组
Criteria c = session,createCriteria(Employee.class);
PropertyProjection pp = Property.groupProperty("department");
c.setProjection(pp).list();
(5)order by排序
Order desc = Order.desc("name");
List<Empolyee> list = session.createCriteria(Employee.class)
.add(desc).list();
(6)分页
int pageNo=3;int pageSize=6;
List<Employee> list = session.createCriteria(Employee.class)
.setFirstResult((pageNo-1)*pageSize).setMaxResult(pageSize).list();
[5].使用本地数据库的sql查询语句。SQLQuery extend Query
见19.[4]
19.执行sql语句
[1].查询
String hql ="";
Session session = hibernate.getSession();
Query query = session.createQuery(hql);
List<Employee> es = query.list();
for(Employee e : es){
System.out.print(e);
}
[2].修改
String hql=" update Employee e set e.name='Tom' where e.id='1'";
session.createQuery(hql).executeUpdate();
[3].删除
String hql ="delete from Employee e where e.id='2'";
session.createQuery(hql).executeUpdate();
[4].执行原生的sql语句
List users = session.createSQLQuery(selet * from user);
for(User e : users){
System.out.print(e);
}
20.hibernate的三种检索策略
[1].立即检索策略:get方法
优点:频繁使用的关联对象能够被加载到缓存中
缺点:1.占用内存。2.select语句过多
[2].延迟检索策略:load方法
在类级别操作时,延迟检索策略,自加载类的OID,不加载类的其他属性,只有当第一次去访问其他属
性时,才会访问数据库的去加载内容。
在关联级别操作时,延迟检索策略,只加载类本身,不加载关联类,直达第一次调用关联对象,才去
加载关联对象(默认的)
优点:由程序决定加载哪些类和内容,避免了大量无用的sql语句和内存消耗
缺点:在session关闭后,就不能访问关联对象了,需要确保session.close调用关联对象。
21.关联级别操作
关联级别操作默认的是延迟加载策略,比如先获取一个对象,但不使用其关联对象,则就默认不会查
询,在xml配置文件中<class>中的lazy属性值默认是true,即默认延迟。
lazy属性可以在class标签中
也可以在set标签中,默认也是true;有三个可选值true.false.extra;
还可以存在many-to-one标签中:默认值是proxy表示延迟加载,false不延迟加载
(开发中常用延迟加载)
hibernate学习小结
<----------------------------------------------------->
hibernate的持久化
1.狭义的:数据从不能断电的设备保存到能断电的设备上
2.广义上的:指的是和数据库相关的操作,增删改查,加载;加载:指的是根据OID查询数据库中的一条
具体的记录
OID:Object ID,特指java对象中与数据库表的主键相对应的一个属性;即表的id与javabean中表的id
属性一致
<--------------------------------------------------------->
hibernate的搭建环境
1.导入jar包(可以利用maven的依赖,网上下载),数据库驱动(jar包maven依赖)
2.创建hibernate自身的配置文件:hibernate.cfg.xml(文件名字固定,普通项目放在src下。maven项
目放在src/main/resources)
//头部文件
<!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="hibernate.connection.url">jdbc:mysql://localhost:3306/20170610</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 在控制台中打印出sql语句 -->
<property name="show_sql">true</property>
<!-- 映射关系。资源的值是java下的映射表的对应路径-->
<mapping resource="com/qf/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.创建持久化的类对应的关系映射文件:(pojo类,domain,entity,beans,数据模型类)
放在src下或者maven项目的src/main/java下
要求:[1]有无参构造函数。[2]有OID属性;[3]有getter,setter方法;[4]非final类
4.创建持久化类对应的关系映射文件:Xxxx.hbm.xml(固定格式,与实体类放在一起,同一包下)
//头部文件:同hibernate.cfg.xml头部一样
<hibernate-mapping>
<class name="实体类的全类名" table="数据库的表名">
<id name="id" type="int">
<generator class="native"></generator>//class中有多个可选择值
</id>
<!--接下来是实体类的除了id之外的所有属性-->
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
5.Hibernate中重要的API(hibernate4以后版本)
5.1.Configuration:负责管理hibernate的配置信息。
hibernate.cfg.xml文件中的信息:数据库URL地址、用户名、密码、jdbc驱动、数据库连接池的桉
树等。
Xxxx.hbm.xml文件中的信息:持久化类与数据库表之间的对应关系。
5.2.Transaction代表一次数据库事务。
hibernate主张把所有持久化操作都纳入到事务中,哪怕仅仅只是只读操作
5.3.Session代表hibernate应用程序和数据库之间的一次会话。
作用相当于JDBC中的Connection,其中封装了一系列的操作方法,并包含缓存功能
5.4.SessionFactory用于创建Session对象的工厂
SessionFactory对象一旦构造完毕,即被赋予特定的配置信息,构造SessionFactory很消耗资源,
一般情况下一个应用只初始化一个SessionFactory对象;在hibernate4新增了一个ServiceRegister接
口,所有基于hibernate的配置或者服务都必须统一向这个SessionFactory注册后才能生效。
创建SessionFactory的步骤:创建Configuration对象;在ServiceRegister对象中注册配置信息;
通过Configuration对象构建SessionFactory对象
hibernate的hellowolrd:
public class hb_helloworld{
public static void main(String[] args){
Configuration config = new Configuration().configure();
ServiceRegistyBuilder srb = new ServiceRegistyBuilder().applySettings
(config.getProprties ());
ServiceRegisty sr = srb.buildServiceRegisty();
SessionFactory factory = config.buildSessionFacory(sr);
Session session = factory.openSession();
//创建一个实体类对象
Users users = new Users();
users.setName("张四");
users.setSex("男");
users.setAge(22);
//开启事务
Transaction tr = session.beginTransaction();
//保存对象(insert操作)
session.save(user);
//修改操作(update操作)
users.setId(1);
users.setName("qqww");
users.setSex("女");
users.setAge(19);
session.update(users2);
session.saveOrUpdate(users);//当OID为null时。可以执行insert操作
//查询操作(select操作)
Users users2 = (Users) session.get(Users.class,3);
Users users3 = (Users) session.load(Users.class,2);//延迟检索操作。即只
是查询操作,不执行sql语句,当对属性操作时。才执行查询操作
System.out.print(users2+"--"+users3)
c397
//删除操作(delete操作)
users.setId(1);
session.delete(users);
//提交事务
tr.commit();
session.close();
factory.close();
}
}
6.Session的一级缓存
Session接口是hibernate向应用程序提供的操纵数据库的最主要接口,他提供了最基本的增删改查方法
每一个session对象都在内存中维护了一个缓存。被称作一级缓存,即两次调用get方法查询同一条记录
,hibernate只会发送1条sql语句,因为session中有缓存。第二次调用时,直接从session缓存中取得
,从而也减少了多数据库的访问次数
7.持久化对象的四种状态
7.1.临时状态:OID:无;session缓存:无;数据库对应记录:无。刚new出来的对象
7.2.持久化状态:OID:有;session缓存:有;数据库对应记录:有。get查询操作后
7.3.游离状态:OID:有;session缓存:无;数据库对应记录:有。new一个对象,并set与数据一条
记录相同的数据
7.4.删除状态;OID:有(但无效);session缓存:无;数据库对应记录:无
8.Session的核心方法
save():可以将一个临时对象转化成持久化对象,可以不要临时对象中的OID,持久化的对象OID不允
许修改
persist():用处和save()一样,但是不允许保存带有OID的对象,会抛异常
get():根据OID的值。从数据库中立即加载一个对象到内存中,当session缓存中有时,则不会发送sql
语句,直接从缓存中取值
load():采用延迟检索策略。在调用load()后返回一个代理对象,不发生sql语句,在用到非OID值
时,才发送sql语句,当通过OID没有找到时,会报异常
update();对数据库进行更新操作,使用update()更新一个OID不存在的对象会抛出异常
saveOrUpdate():有更新和保存两种功能,当OID不存在时,会执行更新操作。OID存在时,会执行更新
操作
delete():根据OID,进行删除操作;
9.在hibernate环境下执行原生的jdbc代码;
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
//使用传入的Connection对象实现原生的JDBC操作...
}
});
10.表与表之间的映射关系
hibernate中使用 实体类名.hbm.xml.文件来定义持久化类和数据库表之间的映射关系
持久化类对应的数据库中的表,持久化属性对应的是数据库表中的字段
当然除了xml配置文件之外,hibernate也支持注解的形式进行配置
11.xml中<property>中元素属性说明
name:持久化对象的属性名;
type:通常用来指定hibernate映射的数据类型(可以使用java类型,也可以使用hibernate数据类型
);hibernate类型:integer,string,character,date,timestamp,float,object,blob等。
column:对应的数据库的字段名;
not-null:属性中不能为空;
length:属性的长度;
unique:是否唯一;
12.hibernate中的主键生成方式:<generator class="">
此处介绍常用的有:native:由hibernate判断数据库,并且由数据库本身生成主键;
identity:数据库为MySQL的数据库,由数据库本身生成主键id;
increment:由hibernate查询数据库,并在原先数据的id加1生成,和底层数据库的类型没有关系;
foreign:生成的是外键。
13.java中大对象类型的hibernate映射
长字符串:长度超过255的字符串时,用text
二进制数据:图片、音频、视频等文件以二进制保存到数据库;
TinyBlob:255字节;Blob:65kb;MediumBlob:16mb;LongBlob:4GB.
14.在hibernate中对于大的文件,可以以blob的方式存入(如图片直接保存在数据库)
保存
FileInputStream in = new FileInputStream(1.png);
Blob picture = Hibernate.getLobCreator(session).createBlob(in,in.available());
读取
InputStream in = blob.getBinaryStream();
15表关系
[1].表关系之多对一
例如:有一个学生表(student,多)和一张成绩表(score,一);一个学生有多门成绩
单向多对一:首先,分别创建持久化类;齐次,创建对应的实体类.hbm.xml;最后,添加映射关系配
置信息。
双向多对一:设置玩单向多对一后,在one的一段同意步骤设置信息。即形成双向关系。
hibernate.cfg.xml中表的mapping能手动生成
many一端设置:
实体类(Student)中添加上:private Set<Score> scores;然后的对应的getter、setter方法
Student.hbm.xml文件中:
<set name="scores" table="score">
<key>
<column name="对应的外键名或者在score表中的对应学生表的id" />
</key>
<one-to-many class="com.zdl.bean.Student" />
</set>
one的一端设置:
实体类(Score)中添上:private Student studrnt;
Score.hbm.xml文件中:
<many-to-one name="student" class="com.zdl.bean.Student" column="对应的外键名或者在
score表中的对应学生表的id" />
[2].表关系之一对一
例如有部门经理(manager)和部门(department)两张表;一般一个部门只有一个经理(一个经理
也只管一个部门)
分别在把其他类的对象当做属性写在自己的类中
Manager实体类中:private Department department;
Department实体类中:private Manage manager;
hbm.xml文件中:
Manager.hbm.xml中:
<one-to-one name="department" class="com.zdl.bean.Department"/>
Department.hbm.xml中:
设置外键(也可以给manager设置 constrained="true" 为外键约束)
<generator class="foreign">
<param name="property">manager</param>
</genertor>
<one-to-one name="manager" class="com.zdl.bean.Manager" constrained="true"/>
[3].表关系之多对多
例如:一个学生可以学习多门课程,一门课程可以有多个学生
两个实体类设置:需要添加对方的set<类名> 属性;
xml文件中:添加两个<set>和<many-to-many /> 标签
16.当为两张表中同时插入一个学生和他的成绩时,往往会报错(一起save)或者分为两步完成
为了解决一次save报错的问题。需要在many一端的set中添加元素:cascade="save-update"
或者cascade="all";all中包含了多种操作方法;cascade为是否级联其他表,默认为none。
17.inverse属性:inverse="true"表示的是只需要指定另外一方来维护关联的记录
<---hibernate的检索方式------------------------>
18.hibernate中的检索方式
[1].OID检索方式:按照对象的OID来检索对象get/load;
[2].对象图导航检索方式:获取到的当前类的属性是其他类的对象,然后获取其他类对象的属性;
如:user.getBook().getBookName();
[3].HQL检索方式:使用面向对象的hql(hibernate query language)查询语言
hql是使用最广的一种检索语言(hql语句关键字不区分大小写,但是java类名严格区分大小写)
(1)FROM子句(查询员工表中全部员工)
from Employee;//Employee是java类类名,而不是表名;下同。
(2)WHERE子句(此时的后面条件依旧是java类中的属性,而不是表字段)
from Employee e where e.salary>6000;
(3)使用基于位置的占位符参数:?(和sql语句一样)
from Employee e where e.salary>?;
填充占位符:query.setDouble(0,8000.00);0表示参数位置(从0开始!)
使用具名参数:格式为":参数名称(自定义)"
from Employee e where e.salary>:salary;
填充占位符:query.setDouble("salary",8000.00);
以实体类对象作为参数(有表的级联关系)
from Employee e where e.department=?;
Department department = new Department();
department.setDeptId(1);
填充占位符:query.setEntity(0, department)
(4)order by子句(desc:降序;asc(升序,默认))
from Employee e where e.salary>6000 order by e.salary desc
(5)分页查询;当前页的页码:pageNo;一页显示多少条数据:pageSize
Query中定义了两个相关函数
setFirstResult(int index);指定查询结果从index位置开始。可以从0取值
setMaxResult(int maxResult);指定查询结果显示多少条数据
index和pageNo的关系:index=(pageNo-1)*pageSize;
(6)投影查询方式(即查询一张表的部分字段对应的是java类中的部分属性)
方式一:返回值形式是一个泛型为object[]
Query query = session.createQuery(hql);
List<Object[]> objs = query.list();
for(Object[] o :objs){
System.out.println(o[0]+"-"+o[1]);
}
方式二:返回值的泛型任然是实体类的对象,但是需要在实体类中的提供对应的构造器
select new Employee(e.name,e.salary) from Employee e
(7)多表查询(返回泛型的是数组,也可以写个所有属性的实体类,写上构造器,使用对象)
from Student s,Score sc where s.id=sc.stuid;
from Student s inner join Score sc on s.id=sc.stuid;
(8)报表查询使用group by和having配合起来使用进行分组,再结合统计函数进行报表查询)
select min(e.salary),max(e.salary)from Employee e
group by e.department having min(e.salary)>3000;
(9)子查询:查询部门名以A开头的部门的员工姓名和部门名称
select e.name,e.department.deptname from Employee e
where e.department in(from Department d where d.deptname like 'A%');
[4].QBC检索方式:使用qbc(query by criteria)API来检索对象。
//1.创建Criteria对象
Criteria c = session,createCriteria(Employee.class);
//2.取得查询结果
List<Employee> list = c.list();
uniqueResult()方法获取单一的记录的查询结果(例如登录)
(1)条件查询:Restrictions(各种条件都封装这个类中了)
多个条件可以add添加,如c.add(like).add(gt).list();
例如:模糊查询:like;判等:eq;大于:gt;小于:lt;大于等于:ge;
小于等于:le;在两者之间:between num1 and num2;
包含:in;
(2)and 和 or 的使用(也可以互相嵌套使用)
Conjunction表示and;Disjunction()表示or。
//创建and条件对象
Conjunction c = Restrictions.conjunction();(默认的就是and的对象)
//创建or条件对象
Disjunction d = Restrictions.disjunction();
add(d).list();
(3)报表查询Projections(单个统计函数);ProjectionList(多个统计函数)
AggregateProjection max = Projection.max("salary");
AggregateProjection min = Projection.min("salary");
ProjectionList pList = Projections.projectionList();
projectionList.add(max).add(min);
List<Object[]> list session.createCriteria(Employee.class)
.setProjection(pList).list();
(4).group by分组
Criteria c = session,createCriteria(Employee.class);
PropertyProjection pp = Property.groupProperty("department");
c.setProjection(pp).list();
(5)order by排序
Order desc = Order.desc("name");
List<Empolyee> list = session.createCriteria(Employee.class)
.add(desc).list();
(6)分页
int pageNo=3;int pageSize=6;
List<Employee> list = session.createCriteria(Employee.class)
.setFirstResult((pageNo-1)*pageSize).setMaxResult(pageSize).list();
[5].使用本地数据库的sql查询语句。SQLQuery extend Query
见19.[4]
19.执行sql语句
[1].查询
String hql ="";
Session session = hibernate.getSession();
Query query = session.createQuery(hql);
List<Employee> es = query.list();
for(Employee e : es){
System.out.print(e);
}
[2].修改
String hql=" update Employee e set e.name='Tom' where e.id='1'";
session.createQuery(hql).executeUpdate();
[3].删除
String hql ="delete from Employee e where e.id='2'";
session.createQuery(hql).executeUpdate();
[4].执行原生的sql语句
List users = session.createSQLQuery(selet * from user);
for(User e : users){
System.out.print(e);
}
20.hibernate的三种检索策略
[1].立即检索策略:get方法
优点:频繁使用的关联对象能够被加载到缓存中
缺点:1.占用内存。2.select语句过多
[2].延迟检索策略:load方法
在类级别操作时,延迟检索策略,自加载类的OID,不加载类的其他属性,只有当第一次去访问其他属
性时,才会访问数据库的去加载内容。
在关联级别操作时,延迟检索策略,只加载类本身,不加载关联类,直达第一次调用关联对象,才去
加载关联对象(默认的)
优点:由程序决定加载哪些类和内容,避免了大量无用的sql语句和内存消耗
缺点:在session关闭后,就不能访问关联对象了,需要确保session.close调用关联对象。
21.关联级别操作
关联级别操作默认的是延迟加载策略,比如先获取一个对象,但不使用其关联对象,则就默认不会查
询,在xml配置文件中<class>中的lazy属性值默认是true,即默认延迟。
lazy属性可以在class标签中
也可以在set标签中,默认也是true;有三个可选值true.false.extra;
还可以存在many-to-one标签中:默认值是proxy表示延迟加载,false不延迟加载
(开发中常用延迟加载)
相关文章推荐
- Hibernate学习小结
- Hibernate 学习小结
- Hibernate学习小结
- Hibernate入门篇<1>hibernate.cfg.xml学习小结
- JPA+Hibernate 3.3 学习小结——第一个JPA程序
- hibernate学习小结
- [学习小结]Hibernate的Helloworld
- [学习小结]Hibernate 的几种映射及映射关系
- hibernate学习小结
- hibernate 深入学习 小结
- hibernate学习小结---hibernate的关联关系映射(Association Mappings)
- JAVA菜鸟 Hibernate学习小结
- hibernate一对多关联映射学习小结
- Hibernate学习小结之实体对象之间关系
- hibernate学习小结
- Hibernate学习小结(一)――Hibernate配置
- Hibernate 学习小结
- Hibernate 学习小结
- Hibernate学习小结(二)――Hibernate正向工程hbm2ddl
- hibernate学习之简单核心概念