hibernate Day2

Day2
1 实体类编写规则
(1 ) 实体类中的属性是私有属性
(2) 私有属性要生成get与set方法
(3) 实体类中有属性作为唯一值(一般使用id值)
(4) 实体类属性建议不要使用基本数据类型, 应当使用基本数据类型的包装类
int ----> Integer
为什么建议我们使用包装类呢?
比如表示学生的分数, 如 int score;
-- 如果学生得了0分, int score=0;
-- 如果学生没有参加考试, 那么用int score=0; 不能准确表示学生是否参考试
-- 如果使用 Integer score;这样就要以解决缺考的问题 Integer score=null;
2 hibernate主键生成策略
(1 ) hibernate中要求实体类里面有一个属性作为唯一值, 对应表的主键, 主键可以有不同的生成策略
(2) hibernate中主键生成策略有很多种
(3) 在generator标签的class属性取值有多种,表示了不同的主键生成策略
http://blog.csdn.net/wenzhihui_201 0/article/details/1 3769827
-- native : 根据使用的数据库帮助我们选择哪个值
CREATE TABLE `t_person` (
`uid` int(1 1 ) NOT NULL AUTO_INCREMENT,
`uname` varchar(255) DEFAULT NULL,
`pword` varchar(255) DEFAULT NULL,
`addr` varchar(255) DEFAULT NULL,
PRIMARY KEY (`uid`)
)-
- uuid : 由hibernate帮助我们生成相应的UUID值
>使用uuid生成策略, 那么实体类的id类型必须是String
CREATE TABLE `t_person` (
`uid` varchar(255) NOT NULL,
`uname` varchar(255) DEFAULT NULL,
`pword` varchar(255) DEFAULT NULL,
`addr` varchar(255) DEFAULT NULL,
PRIMARY KEY (`uid`)
)
3 实体类操作n
(1 ) CRUD操作
-- 添加操作
-- 根据 id 查询返回一个对象
表中的现有的数据, 可以手动添加, 或通过session.save()方法添加
@Test
public void getPersonById(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4 根据id查询 调用session中的get方法
// Session.get(Class<Person> clazz, Serializable id)
// Class<Person> clazz : 类的class对象
// Serializable id : id值, 注意要求这个id类型是可序列化的
Person p1 =session.get(Person.class, 1 );
System.out.println(p1 );
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}-
- 更新对象
先根据id查询到对象, 再更新对象
@Test
public void updatePerson(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4.1 根据id查询 调用session中的get方法
Person p1 =session.get(Person.class, 2);
// 4.2 修改对象信息
p1 .setUname("张天明");
p1 .setPword("1 2345");
p1 .setAddr("中国南京");
// 4.3 调用 session的update()方法修改
// 修改过程, 到person表中, 根据id找到指定对象, 然后执行update语句完成修改
session.update(p1 );
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}
方法执行后显示的SQL语句
结果对比
-- 删除对象
@Test
public void deletePerson(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4 删除操作
// 第一种方式(常用的方式)
// 4.1 根据id查询 调用session中的get方法
Person p3=session.get(Person.class, 3);
// 4.2 对查询到的对象执行删除操作
session.delete(p3);
// 第二种方式(不常用)
// Person p2=new Person();
// p2.setUid(2);
// session.delete(2);
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}
结果查看
-- 添加或更新操作
@Test
public void saveOrUpdate_Person(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4 添加操作
Person person=new Person();
// 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
person.setUid(1 );
person.setUname("东方不败");
person.setPword("5201 31 4");
person.setAddr("黑木崖");
// 执行添加
session.save(person);
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}
// 4 添加操作
Person person=new Person();
// 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
person.setUid(1 );
person.setUname("东方不败");
person.setPword("5201 31 4");
person.setAddr("黑木崖");
// 执行添加
session.save(person);
上面的save操作并不是更新, 而是执行了保存操作, 且它能够自动处理id的问题
@Test
public void save_Update_Person(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4 添加操作
Person person=new Person();
// 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
person.setUid(1 );
person.setUname("东方不败");
//person.setPword("5201 31 4");
person.setAddr("黑木崖");
// 执行修改操作
// 现在一般是先查再改, 我们也可以直接创建对象, 然后直接改, 但要给出准确的id
// 要注意了, 执行修改是对一个对象所有属性进行修改, 如果你有部分属性没有设置, 那么会置null
session.update(person);
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}
这是执行前后的结果比对
(2) 实体类对象状态(概念)
实体类状态有三种
--瞬时态:对象里面没有id值, 对象与session没有关联,一般是做添加操作
--持久态:对象有id值, 对象与seesion有关联
--托管态:对象有id值, 但对象与session没有关联
(3) saveOrUpdate方法;实现添加、 实现修改
--该方法很简单, 它会根据对象不同的状态做相应的操作
@Test
public void saveOrUpdate_Person(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4 添加操作
Person person=new Person();
// 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
person.setUname("小龙女");
person.setPword("5201 31 4");
person.setAddr("古墓");
// 由于person是瞬时态, 那么saveOrUpdate()这时是做insert操作
session.saveOrUpdate(person);
Person p1 =session.get(Person.class, 1 );
p1 .setUname("杨过");
p1 .setPword("1 31 4520");
p1 .setAddr("古墓");
// 由于p1 是持久态, 那么saveOrUpdate()这时是做update操作
session.saveOrUpdate(p1 );
Person p2=new Person();
p2.setUid(2);
p2.setUname("乔峰");
p2.setPword("778899");
p2.setAddr("大辽");
// 由于p2是托管态, 那么saveOrUpdate()这时是做update操作
session.saveOrUpdate(p2);
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}
操作结果
4 hibernate的一级缓存
(1 ) 什么是缓存
-- 数据存到数据库里面, 数据库本身就是文件系统, 使用流的方式操作文件效率不高
-- 把数据存到内存里面, 不需要使用流方式, 可以直接读取内存中数据
-- 把数据放到内存中, 提高读取效率
(2) hibernate缓存
-- hibernate框架中提供很多优化方式, hibernate的缓存就是一个优化方式
-- hibernate缓存特点
第一类 hibernate一级缓存
> hibernate一级缓存默认打开
> hibernate一级缓存使用范围(有点类似于web阶段的requestScope,seeionScope)
一级缓存就是从session创建到session关闭的范围
> hibernate一级缓存中, 存储的数据必须是持久态的数据, 瞬时态与托管态的数据不会存储到一级缓存中
第二类 hibernate二级缓存
> 目前已经不使用了, 替代技术redis
> 二级缓存默认不是打开的, 需要通过配置打开
> 二级缓存使用范围, 是SessionFactory范围( 项目范围)
(3) 验证一级缓存存在
验证方式:
> 首先根据uid=1 查询, 返回对象 ( 查询数据库, 会有sql输出)
> 其次再根据uid=1 查询, 又会返回对象 (瞧一瞧会不会有sql 输出)
控制台输出
(4) 一级缓存执行过程
// 4 验证一级缓存
// 根据uid进行第一次查询,是否有sql语句输出
Person p1 =session.get(Person.class, 1 );
System.out.println(p1 );
// 再根据uid进行第二次查询,是否有sql语句输出
Person p2=session.get(Person.class, 1 );
System.out.println(p2);
步骤:
-- 首先查询一级缓存, 查询一级缓存如果没发现有相应的数据, 就去执行数据库查询
-- 查询数据库后, 会把查询得到的结果放到一级缓存中
-- 第二次进行查询时, 也会首先进行一级缓存查询, 这时发现数据已经在一级缓存中了, 直接取出就结果, 不会
再做数据库的查询
注意: 一级缓存中并不是存储某个对象, 而是把对象的属性值给存到缓存中, 当我们进行第二次查询时, 返回的
p2,其实是用之前存放的属性值给重新构建出来的一个新的对象噢, 这一点大家了解
(4) hibernate一级缓存特性
> 持久态会自动更新数据库
@Test
public void persistentUpdate(){
// 1 获取SessionFactory
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 2 获取session
Session session=sessionFactory.openSession();
// 3 开启事务
Transaction tx=session.beginTransaction();
// 4 持久态更新数据库
Person p5=session.get(Person.class, 5);
// 更新对象信息
p5.setUname("小师妹");
p5.setAddr("华山");
// 写入数据库,由于p5是持久态的, 所以下面的update方法调用可以省去
// session.update(p5);
// 5 提交事务
tx.commit();
// 6 关闭连接
session.close();
sessionFactory.close();
}
> 持久态会自动更新数据库的执行过程(了解)
5 hibernate的事务操作
(1 ) 什么是事务
数据库事务(Database Transaction) , 是指作为单个逻辑工作单元执行的一系列操作, 要么完全地执行, 要么完全地不执行。 事务
处理可以确保除非事务性单元内的所有操作都成功完成, 否则不会永久更新面向数据的资源。
http://baike.baidu.com/link?url=89WXbjUBGS86Qy9G2ynAxr97mBbnDHVmauvYQ_EGJ65CupbnF2TwUZiH9XvfhXuxEQUy9xBbJYWgnw_On8TJLRCbpXOuNQdHuLqJDlotPKjR_rPeBFHTmUmMAOVFDeEIKfSsUmimPHm2V5-F4r-dq
http://www.cnblogs.com/fjdingsd/p/5273008.html
hibernate设置事务隔离级别 http://www.cnblogs.com/jerryxing/archive/201 2/04/24/2468999.html
(2) 事务代码规则写法(重点掌握)
> 结构
try{
开启事务
处理代码
提交事务
}c
atch(){
回滚事务
}f
inally{
释放资源
}
@Test
public void addPerson_Standard() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
// 使用SessionFactory创建session对象
// 类似于jdbc连接, 只是这个地方hibernate做了封装
session = sessionFactory.openSession();
// 开启事务
tx = session.beginTransaction();
// 添加功能
Person person = new Person();
person.setUname("韦小宝");
person.setPword("weixiaobao");
person.setAddr("紫禁城");
// 调用session对象的实现方法,完成添加
session.save(person);
// 可以模拟一个异常
int a=1 0/0;
// 提交事务
tx.commit();
} catch (Exception e) {
// 输出异常
e.printStackTrace();
// 有异常, 则回滚事务
if(tx!=null){
tx.rollback();
}
} finally {
//关闭资源
if(session!=null && session.isOpen()){
session.close();
}if
(sessionFactory!=null && !sessionFactory.isClosed()){
sessionFactory.close();
}
}
}(2
) hibernate绑定session(重点掌握)
> session类似于jdbc的connection, 为了安全可以使用threadLocal
> hibernate已经帮助我们实现了与本地线程的绑定的session
> 获取与本地线程绑定的session
第一步 在hibernate核心配置文件中配置
<!-- 本地线程绑定的session -->
<property name="hibernate.current_session_context_class">thread</property>
第二步 调用SessionFactory里面的方法得到
public class HibernateUtils {
private static SessionFactory sessionFactory = null;
private HibernateUtils() {
}s
tatic{
if (sessionFactory == null) {
Configuration cfg = new Configuration();
cfg.configure();
sessionFactory = cfg.buildSessionFactory();
}
}p
ublic static SessionFactory getSessionFactory() {
return sessionFactory;
}p
ublic static Session getLocalSessioin(){
// 直接返回与本地线程绑定的session
return sessionFactory.getCurrentSession();
}
}@
Test
public void addPerson_Standard2() {
Session session = null;
Transaction tx = null;
try {
// 通过工具类获取本地session
session = HibernateUtils.getLocalSessioin();
// 开启事务
tx = session.beginTransaction();
// 添加功能
Person person = new Person();
person.setUname("韦小宝");
person.setPword("weixiaobao");
person.setAddr("紫禁城");
// 调用session对象的实现方法,完成添加
session.save(person);
// 提交事务
tx.commit();
} catch (Exception e) {
// 输出异常
e.printStackTrace();
// 有异常, 则回滚事务
if(tx!=null){
tx.rollback();
}
} finally {
// 关闭资源(如果session是与本地线程绑定的, 那么它会自动关闭, 这个地方就用关闭了, 这么写也可以)
if(session!=null && session.isOpen()){
session.close();
}/
/ 注意在web项目中SessionFactory对象是不用关闭的, 因为它是大家共用的
}
}
6 hibernate的其他的api(查询)
(1 ) Query对象
> 使用Query对象, 不需要写sql语句, 我们要写hql语句
-- hql : hibernate query language, hibernate框架提供的查询语言, 这个hql和sql语句很相似
-- hql与sql的区别
>> 使用sql操作的是表和字段
>> 使用hql操作的是实体类和属性
-- 查询所有hql语句
>> from 实体类名称
-- Query对象的使用
>> 创建Query对象
>> 调用Query对象方法得到结果
@Test
public void personQuery() {
Session session = null;
Transaction tx = null;
try {
// 得到与本地线程绑定的session
session = HibernateUtils.getLocalSessioin();
// 开启事务
tx = session.beginTransaction();
// 查询person表的hql
String hql = "from Person";
// 创建Query对象
Query query = session.createQuery(hql);
// 通过Query对象得到查询结果
List<Person> persons = query.list();
// 遍历输出查询结果
for (Person p : persons) {
System.out.println(p);
}//
提交事务
tx.commit();
} catch (Exception e) {
// 有异常回滚
if(tx!=null){
tx.rollback();
}
} finally {
// 释放资源(当前的session是本地线程session, 可以不用下面语句)
if(session!=null && session.isOpen()){
session.close();
}
}
}
(2) Criteria对象
> 也可以使用这个对象进行查询操作, 但是使用这个对象时, 不需要写hql, 直接调用方法就可以实现
> 实现过程
-- 使用session对象的createCriteria(类名.class)创建Criteria对象
-- 调用criteria对象的list()方法返回结果集
(3) SQLQuery对象
> 使用hibernate时候, 我们也可以调用原始的sql语句, 它就是通过SQLQuery对象
>实现过程
-- 创建SQLQuery对象
-- 调用SQLQuery对象的方法得到结果
调试的结果
输出结果
怎么样能得到同上样直接返回一个List集合, 且集合中每一个都是Person类的对象呢?

时间: 08-22

hibernate Day2的相关文章

hibernate Day2 笔记

1.主键生成策略 <!--映射配置文件 >映射配置文件名称和位置没法有固定要求 >映射配置文件中的name属性值写实体类相关内容 -- class 标签name属性值实体类全路径 -- id标签和property标签name属性值 实体类的属性名称(注意要完全一样) -- id标签和property标签中的column属性是可以省略的,如果不写,则生成的字段名与属性名一样,建议写 出,这样比较清析. -- property标签中 还有一个属性type属性,用于设定字段的类型,我们可以不用

hibernate Day2 案例代码

1.编写实体类Person package com.icss.pojo; public class Person { private int uid; private String uname; private String pword; private String addr; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUname()

Hibernate - HHH000352: Unable to release batch statement

这是hibernate的一个bug,具体看https://hibernate.atlassian.net/browse/HHH-11732?attachmentViewMode=list When using stateless session with jdbc batch size we get an HHH000352: Unable to release batch statement.. error in session.close() after rollback: Code:Con

Hibernate简述及入门实例

一.Hibernate简述 总的概括,Hibernate是一个ORM的轻量级持久层框架,解决了对象和关系数据库中表的不匹配问题(阻抗不匹配)以及拥有开发代码不用去继承hibernate类或接口的优势(无侵入性).hibernate框架实现使得开发人员可以避免反复地编写javajdbc部分代码,应用面向对象的思维操作关系型数据库. 二.使用myeclipse创建hibernate实例两种方法(以hibernate3.5.2及mysql为例) a)手动编写hibernate.cfg.xml及*.hb

对象序列化和反序列--Hibernate的查询和新增极其相似

Hibernate几个关键字持久化,ORM(关系对象映射)(数据库中关系称作是一张表) 应用在项目中,刘一从写的查询代码,每次都挂掉,想要弄出测试数据,自己想着把查询出来的复杂数据弄到文件里自己要是去造那些复杂数据很麻烦public class Object1 { public static void main(String args[]){ HashMap<String, Object> obj=new HashMap<String,Object>(); obj.put(&quo

Hibernate的七种映射关系之七种关联映射(二)

继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.private Classes classes; 2.Student.hbm.xml里添加many-to-one标签:<many-to-one name="classes" column="classesid"/>.Classes.hbm.xml在例子(六)里的那

Hibernate的七种映射关系之七种关联映射(一)

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 一.Hibernate多对一关联映射:就是在"多"的一端加外键,指向"一"的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1."多"端实体加入引用"一"端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2."多"端配置文

mybatis与hibernate的区别

本文转载自:http://blog.csdn.net/wangpeng047/article/details/17038659 以前没怎么用过mybatis,只知道与hibernate一样是个orm数据库框架.随着使用熟练度的增加,发现它与hibernate区别是非常大的,结合至今为止的经验,总结出以下几点: 1. hibernate是全自动,而mybatis是半自动. hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql

hibernate载入持久化对象的两种方式——get、load

一.get与load对照 在hibernate中get和load方法是依据id取得持久化对象的两种方法.但在实际使用的过程中总会把两者混淆,不知道什么情况下使用get好,什么时候使用load方法效率更高.下边具体说一下get和load的不同,有些时候为了对照也会把find加进来. 1.从返回结果上对照: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回null 2.从检索运行机制上对照: get方法和fin