Hibernate学习小结



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)
  //删除操作(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不延迟加载
 (开发中常用延迟加载)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值