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类的对象呢?
hibernate Day2的更多相关文章
- hibernate Day2 笔记
1.主键生成策略 <!--映射配置文件 >映射配置文件名称和位置没法有固定要求 >映射配置文件中的name属性值写实体类相关内容 -- class 标签name属性值实体类全路径 - ...
- hibernate Day2 案例代码
1.编写实体类Person package com.icss.pojo; public class Person { private int uid; private String uname; pr ...
- Hibernate 配置详解(8)
hibernate.generate_statistics 这个配置大家应该都很熟悉,用于开启Hibernate统计信息,便于对Hibernate相关性能调试提供数据依据.在开发过程当中,可以把这个选 ...
- Hibernate 配置详解(9)
hibernate.cache.use_structured_entries Hibernate文档上介绍,该属性是用于把对象以一种更易读的方式放到二级缓存中,这样,在对二级缓存进行监控的时候就更容易 ...
- HibernateReview Day2–Hibernate体系结构
本文摘自 李刚 著 <Java EE企业应用实战> 现在我们知道了一个概念Hibernate Session,只有处于Session管理下的POJO才具有持久化操作能力.当应用程序对于处于 ...
- 12 Spring Data JPA:orm思想和hibernate以及jpa的概述和jpa的基本操作
spring data jpa day1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理以及基本操作 day3:多表操作,复杂查询 d ...
- hibernate多对多关联映射
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用
问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...
- hibernate多对一双向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
随机推荐
- 不能实现RadioButton默认选择
当用RadioButton时,希望在程序运行的时候默认一个选项: CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO1); //CheckRadioBut ...
- sanic官方文档解析之蓝图
1,蓝图(Blueprints) 蓝图可用于子路由的应用,代替增加路由的存在,蓝图的定义和增加路由的方法相似,灵活的在应用中注册,并且可插拔的方式. 尤其是在大型应用中使用蓝图的时候在你逻辑打断的地方 ...
- ssh免密码访问
ssh-copy-id命令 它可以把本地主机的公钥复制到远程主机的authorized_keys文件上,ssh-copy-id命令也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh ...
- android adapter公共写法
在开发过程中,会写很多的adapter类,其中很多公共的部分,不需要每次都去书写,可以为开发者省下很多时间 提取一个ListViewAdapter public abstract class List ...
- group by where having 联合使用
having子句与where有相似之处但也有区别,都是设定条件的语句.在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行.而where子句在查询过程中执行优 ...
- 在Java中如何正确地终止一个线程
1.使用Thread.stop()? 极力不推荐此方式,此函数不安全且已废弃,具体可参考Java API文档 2.设置终止标识,例如: import static java.lang.System.o ...
- poj 3585 Accumulation Degree(二次扫描和换根法)
Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...
- UISegmentedControl方法与属性的总结
SegmentedControl又被称作分段控制器,是IOS开发中经常用到的一个UI控件. 初始化方法:传入的数组可以是字符串也可以是UIImage对象的图片数组 - (instancetype)in ...
- 【bzoj3282】Tree
LCT模板题: 话说xor和的意思是所有数xor一下: #include<iostream> #include<cstdio> #include<cstring> ...
- bzoj4149: [AMPPZ2014]Global Warming
头都烂了怎么头疼啊 考虑先做出对于一个位置以它作为唯一最小值的最远区间,这个可以单调栈上二分搞出来 那么对于一个位置这个区间而言,一定是选择这个区间的最大数是作为最终的唯一最大数最优的 为什么呢?我们 ...