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 ...
随机推荐
- HDU 2601An easy problem-素数的运用,暴力求解
id=17433" target="_blank" style="color:blue; text-decoration:none">An ea ...
- 最长公共字序列.cpp
<span style="color:#993399;">/* By yuan 2014/6/21 At nwpu.xf 1041.最长公共子序列 时限:1000ms ...
- LeetCode(3)题解: Longest Palindromic Substring
https://leetcode.com/problems/longest-palindromic-substring/ 题目: Given a string S, find the longest ...
- CodeForces 24D Broken robot(期望+高斯消元)
CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...
- BAPI_PO_CEATE 与PO_1
- ie下文件上传无权访问的问题
最近项目遇到个问题,ie下文件上传无权访问,在网上找了很久才找到答案,原来是因为ie下不能用js触发input=file的点击事件,必须手动点击才可以.
- 一个简单的servlet
1.创建一个自己的servlet文件,继承HttpServlet MyServlet.java package com.jmu.ccjoin.controller; import java.io.IO ...
- POJ1300 Door Man —— 欧拉回路(无向图)
题目链接:http://poj.org/problem?id=1300 Door Man Time Limit: 1000MS Memory Limit: 10000K Total Submiss ...
- POJ3104 Drying —— 二分
题目链接:http://poj.org/problem?id=3104 Drying Time Limit: 2000MS Memory Limit: 65536K Total Submissio ...
- RedisCluster集群搭建
搭建集群方案 安装部署任何一个应用其实都很简单,只要安装步骤一步一步来就行了.下面说一下 Redis 集群搭建规划,由于集群至少需要6个节点(3主3从模式),所以,没有这么多机器给我玩,我本地也起不了 ...