Hibernate的了解、Hibernate的搭建、Hibernate的基本使用流程等内容请阅读21-Java-Hibernate框架(一)

五、Hibernate的Query查询接口(重中之重)

  1.HQL语言了解:Hibernate Query Language(HQL),是hibernate的查询语言,和SQL语句结构一样,不同点注意点如下:

      (1)HQL是面向对象查询,SQL是面向结构查询

      (2)在HQL使用类名和属性名,替代了原有的表名和字段名  

      (3)在HQL语句中类型名和属性名大小写敏感  

      (4)如果需要select * 查询所有字段的值,在HQL语句中可以省略select *语句。例如:from User;

      (5)如果需要join...on表连接,需要建立关联映射关系使用,不支持on子句

      (6)不要使用数据库提供的字符串函数、日期函数和一些特有的函数。一些基础的函数可以使用,例如:max(),min(),sum(),avg(),count()等。

      (7)若只查询字体类中某几个字段,返回的结果是泛型,值的集合

  2.具体Query常用的相关接口看代码演示

 package com.hibernatetest.test;

 import java.util.List;

 import org.hibernate.Query;
import org.hibernate.Session;
import com.hibernatetest.entity.User;
import HibernatenateUtils.hibernateUtils;
/*
* Query接口的常用方法:
* 1.setXXX():用于设置HQL语句中问号或变量的值
* 2.uniqueResult():得到单个对象(返回Object类型),在已知查询结果中只有一个或零个才能用此函数,若有多个满足条件的结果则报异常
* 3.executeUpdate():执行更新和删除语句(返回int型作为操作成功的次数)
* 4.分页查询
* 5.list():获取结果集(返回List类型)
* 6.iterate():获取结果集(返回Iterator类型)
* */
public class QueryTest {
public static void main(String[] args) {
//第一步:Query对象是通过Session获取的,所以先要通过之前写hibernate工具类获取Session对象
Session session = hibernateUtils.getSession(); //第二步:CreateQuery("HQL语句"):用于创建Query对象。
Query query = session.createQuery("from User where uname='zhangsan'"); /*查询参数设值setXXX(): (两种方式)
* 1.问号设值
* Query query = session.createQuery("from User where uid between ? and ?");
* query.setInteger(0,5);//给第一个问号处赋值5
* query.setInteger(1,10);//给第一个问号处赋值10
*
* 2.变量设值
* Query query = session.createQuery("from User where uname=:name");
* query.setString(name,"zhangsan");//给name变量赋值
*
* 3.模糊查询
* Query query = session.createQuery("from User where uname likt %?%");错!!!!!
* Query query = session.createQuery("from User where uname like ?");对!!!!
* query.setString(0,"%" +"zhang"+ "%");
*
* 4.分页查询
* Query query = session.createQuery("from User where uname='zhangsan'");
* query.setFirstResult(0);从满足条件的数据中的第一条数据开始抓取
* query.setMaxResult(2);从满足条件的数据中只抓取前两条数据
*
* 5.获取单个对象
* Query query = session.createQuery("select count(*) from User where uname='zhangsan'");
* Object object = query.uniqueResult();
*
* 6.构造查询
* Query query = session.createQuery("select new User(5,"zhangsan") from User where uname='zhangsan'");
* Object object = query.uniqueResult();
* */ /*数据库更新和删除操作executeUpdate()
* 1.删除
* Query query = session.createQuery("delete from User where uid in(1,6)");//删除id为1和6的数据,即使数据库中没有符合条件的数据也不会报错
* int execute = query.executeUpdate();//返回成功操作的次数
* */ //第三步:Query获取结果集
//1.list()获取
List<?> list = query.list();
for(Object u:list){
User user = (User)u;
System.out.println(user);
}
/*2.iterate()获取
* Iterator<?> iterator = query.iterate();
* while(iterator.hasNext()){
* User user = (User)iterator.next();
* System.out.println(user);
* }
* */
/*面试要考:list()和iterate()获取结果集的区别:
* list():一次把所有数据从数据库中取出来
* iterate():先从数据库中查询满足条件的id,如果缓存中包含全部要查询的id的数据,就无需再查数据库,直接从缓存中取数据,否则,根据id从数据库中取
* */ //第四步:记得将Session关闭
session.close();
}
}

六、Hibernate的三个状态

    对象(持久化类的实例)处于session对象的管理中才能与数据库发生联系。在Hibernate框架应用中,我们依据对象对象与session对象的关系不同情况,

  把对象的状态分为人的三种:瞬时状态、游离状态、持久状态。

    Transient(瞬时状态|临时状态):在new之后,save()之前,数据库没有应用的数据

      如果对象未与session对象关联过,我们称该对象处于瞬时状态

    Persistent(持久状态):在save()之后,在session关闭之前,数据库有相对应的数据

      如果对象与session关联起来了,且该对象对应到数据库记录,则称该对象处于持久状态

    

  三状态结构图:

          

  三状态转换关系:

      1.瞬时状态转换为持久状态:

          使用session的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态

          使用session的get()或load()方法获取对象后,该对象的状态为持久状态

      2.持久状态转换为瞬时状态

          执行session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因此该对象没有与任何的数据库数据有关联

      3.持久状态变为游离状态

          执行session对象的evict()、clear()、close()方法,对象由原来的持久状态变为游离状态。

      4.游离状态变为持久状态

          重新获取对象session对象,执行session对象的update()或saveOrUpdate方法,由游离状态转换为持久状态,该对象再次与session关联

      5.游离状态转换为瞬时状态

          执行session的delete()方法,对象有游离状态变为瞬时状态

          对瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机按照垃圾回收机制处理

七、Hibernate根据实体自动构建生成表

  第一步:在hibernate.cfg.xml中添加<property name="hibernate.hbm2ddl.auto">update</property>,设置自动生成表

 <?xml version="1.0" encoding="UTF-8"?>
<!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>
<!--hibernate 方言 区分身份 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 数据库连接信息 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernatetest</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property> <!-- hibernate自动生成表 update:如果数据库不存在这张表自动创建一张表,如果存在不创建-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- hibernate在控制台显示SQL语句 -->
<property name="show_sql">true</property>
<!-- hibernate格式化SQL,控制台看起来更整齐 -->
<property name="format_sql">true</property>
<!-- 设置自动提交 -->
<property name="connection.autocommit">true</property> <!-- <property name="connection.characterEncoding">UTF-8</property> -->
<!--加载hibernate映射 -->
<mapping resource="com/hibernatetest/entity/Entity.hbm.xml" />
</session-factory> </hibernate-configuration>

  第二步:编写实体类

  第三步:配置映射文件

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name:对应的实体类的权限定名称,table:对应数据库表名称 -->
<class name="com.hibernatetest.entity.Entity" table="hibernateEntity">
<!-- id标签用于配置主键属性
name属性:对应实体类中属性名称
type属性:可以省略,如果省略默认实体类中属性的对应类型
-->
<id name="userid" type="java.lang.Integer">
<!-- column用于设置对应数据库表中字段名。不写column标签,数据库中的字段名则和Entity类中的属性名一致
name:数据库表中的字段名
length:设置字段长度
-->
<column name="userid"></column>
<!-- generator用于设置主键生成策略
native:数据库本地生成策略,适用于多个数据库
sequence:序列(Oracle使用)
imcrement:主要mysql数据库使用,适用于所有数据库,先查询出最大的id,在此基础上+1,有可能出现并发的问题
uuid:生成32位,不会重复的主键,可以达到真正的跨数据库
foreign:通常在一对一关联的时候使用
自增长:identity,适用于mysql,db2,sql server。
-->
<generator class="native"></generator>
</id> <!-- property标签用于配置其他属性
name:对应实体类中属性名称
type:可以省略,如果省略默认实体类中属性的对应类型
-->
<property name="username" type="java.lang.String">
<column name="username" length="32"></column>
</property>
<property name="password" type="java.lang.String" >
<column name="password" length="32"></column>
</property> </class> </hibernate-mapping>

  第四步:编写测试类测试

    控制台显示hibernate在数据库没找到hibernateEntity表

          

    于是它便会在数据库自动生成一张表

          

八、Hibernate的关联映射

    实体与实体之间有一对一、多对一、多对多的关系,Hibernate也因此需要对表与表之间进行关联映射配置。

     假设:有一张表为Entity,表中有userid,username,password三个字段,另一张表Grade,表中有gradeid,userid,grade。

     我现在通过userid查询对应另一张表中的grade(此处可以理解为多对一)。步骤如下:

      第一步:搭建Hibernate,配置hibernate.cfg.xml,此处由于我们有两张表,所以需要加载两个映射文件

 <?xml version="1.0" encoding="UTF-8"?>
<!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>
<!--hibernate 方言 区分身份 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 数据库连接信息 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernatetest</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property> <!-- hibernate自动生成表 update:如果数据库不存在这张表自动创建一张表,如果存在不创建-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- hibernate在控制台显示SQL语句 -->
<property name="show_sql">true</property>
<!-- hibernate格式化SQL,控制台看起来更整齐 -->
<property name="format_sql">true</property>
<!-- 设置自动提交 -->
<property name="connection.autocommit">true</property> <!-- <property name="connection.characterEncoding">UTF-8</property> --> <!--加载hibernate映射文件 -->
<mapping resource="com/hibernatetest/entity/Entity.hbm.xml" />
<mapping resource="com/hibernate/grade/Grade.hbm.xml" />
</session-factory> </hibernate-configuration>

     第二步:配置两张表对应的映射文件

Entity.hbm.xml:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name:对应的实体类的权限定名称,table:对应数据库表名称 -->
<class name="com.hibernatetest.entity.Entity" table="hibernateEntity">
<!-- id标签用于配置主键属性
name属性:对应实体类中属性名称
type属性:可以省略,如果省略默认实体类中属性的对应类型
-->
<id name="userid" type="java.lang.Integer">
<!-- column用于设置对应数据库表中字段名。不写column标签,数据库中的字段名则和Entity类中的属性名一致
name:数据库表中的字段名
length:设置字段长度
-->
<column name="userid"></column>
<!-- generator用于设置主键生成策略
native:数据库本地生成策略,适用于多个数据库
sequence:序列(Oracle使用)
imcrement:主要mysql数据库使用,适用于所有数据库,先查询出最大的id,在此基础上+1,有可能出现并发的问题
uuid:生成32位,不会重复的主键,可以达到真正的跨数据库
foreign:通常在一对一关联的时候使用
自增长:identity,适用于mysql,db2,sql server。
-->
<generator class="native"></generator>
</id> <!-- property标签用于配置其他属性
name:对应实体类中属性名称
type:可以省略,如果省略默认实体类中属性的对应类型
-->
<property name="username" type="java.lang.String">
<column name="username" length="32"></column>
</property>
<property name="password" type="java.lang.String" >
<column name="password" length="32"></column>
</property>
</class> </hibernate-mapping>

Grade.hbm.xml:(此处需要加入对grade表的多对一的映射关系)

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name:对应的实体类的权限定名称,table:对应数据库表名称 -->
<class name="com.hibernate.grade.Grade" table="hibernateGrade">
<!-- id标签用于配置主键属性
name属性:对应实体类中属性名称
type属性:可以省略,如果省略默认实体类中属性的对应类型
-->
<id name="gradeid" type="java.lang.Integer">
<!-- column用于设置对应数据库表中字段名。不写column标签,数据库中的字段名则和Entity类中的属性名一致
name:数据库表中的字段名
length:设置字段长度
-->
<column name="gradeid"></column>
<!-- generator用于设置主键生成策略
native:数据库本地生成策略,适用于多个数据库
sequence:序列(Oracle使用)
imcrement:主要mysql数据库使用,适用于所有数据库,先查询出最大的id,在此基础上+1,有可能出现并发的问题
uuid:生成32位,不会重复的主键,可以达到真正的跨数据库
foreign:通常在一对一关联的时候使用
自增长:identity,适用于mysql,db2,sql server。
-->
<generator class="native"></generator>
</id> <!-- property标签用于配置其他属性
name:对应实体类中属性名称
type:可以省略,如果省略默认实体类中属性的对应类型
--> <!-- 多对一映射关系 -->
<!-- name:当前Grade类的Entity属性
column:Grade类的外键
fetch:有join和select.默认为select
select:查了当前表之后,再查外键所在的那张表
join:在多对一将原本需要两条sql语句以left outer join(左外连接)方式用一条语句解决
cascade:级联操作关联表:慎用
save-update:在添加或操作的时候使用级联操作关联表
delete:在删除的时候使用级联操作关联表
all:在所有操作的时候使用级联操作关联表
none:任何时候都不使用
-->
<many-to-one name="entity" column="userid" fetch="join"></many-to-one> <property name="grade" type="java.lang.Double" >
<column name="grade"></column>
</property>
</class> </hibernate-mapping>

      第三步:编写两张表对应的实体类

Entity类:

 package com.hibernatetest.entity;

 public class Entity {
private Integer userid;
private String username;
private String password;
public Entity() {
super();
// TODO Auto-generated constructor stub
}
public Entity(Integer userid, String username, String password) {
super();
this.userid = userid;
this.username = username;
this.password = password;
}
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((password == null) ? 0 : password.hashCode());
result = prime * result + ((userid == null) ? 0 : userid.hashCode());
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Entity other = (Entity) obj;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (userid == null) {
if (other.userid != null)
return false;
} else if (!userid.equals(other.userid))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
@Override
public String toString() {
return "Entity [userid=" + userid + ", username=" + username
+ ", password=" + password + "]";
} }

Grade类:

 package com.hibernate.grade;

 import com.hibernatetest.entity.Entity;

 public class Grade {
private Integer gradeid;
private Entity entity;
private Double grade;
public Grade() {
super();
// TODO Auto-generated constructor stub
}
public Grade(Integer gradeid, Entity entity, Double grade) {
super();
this.gradeid = gradeid;
this.entity = entity;
this.grade = grade;
}
public Integer getGradeid() {
return gradeid;
}
public void setGradeid(Integer gradeid) {
this.gradeid = gradeid;
}
public Entity getEntity() {
return entity;
}
public void setEntity(Entity entity) {
this.entity = entity;
}
public Double getGrade() {
return grade;
}
public void setGrade(Double grade) {
this.grade = grade;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((entity == null) ? 0 : entity.hashCode());
result = prime * result + ((grade == null) ? 0 : grade.hashCode());
result = prime * result + ((gradeid == null) ? 0 : gradeid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Grade other = (Grade) obj;
if (entity == null) {
if (other.entity != null)
return false;
} else if (!entity.equals(other.entity))
return false;
if (grade == null) {
if (other.grade != null)
return false;
} else if (!grade.equals(other.grade))
return false;
if (gradeid == null) {
if (other.gradeid != null)
return false;
} else if (!gradeid.equals(other.gradeid))
return false;
return true;
}
@Override
public String toString() {
return "Grade [gradeid=" + gradeid + ", entity=" + entity + ", grade="
+ grade + "]";
} }

      第四步:编写HibernateUtils工具类和测试类

测试类:

 package Hibernatetest;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction; import com.hibernate.grade.Grade;
import com.hibernatetest.entity.Entity; import HibernatenateUtils.hibernateUtils; public class annotationtest { public void test(){ }
public static void main(String[] args) {
Session session = hibernateUtils.getSession(); //先制造两条记录在数据库中
Transaction transaction = session.beginTransaction();
Entity user1 = new Entity(null,"zhangsan","1111");
Grade grade1 = new Grade(null,user1,Double.valueOf(85));
session.save(user1);
session.save(grade1);
transaction.commit(); transaction = session.beginTransaction();
Entity user2 = new Entity(null,"lisi","2222");
Grade grade2 = new Grade(null,user2,Double.valueOf(100));
session.save(user2);
session.save(grade2);
transaction.commit(); //查询测试
Grade grade = session.get(Grade.class,1);
System.out.println(grade);
session.close();
}
}

运行结果:

    

22-Java-Hibernate框架(二)的更多相关文章

  1. (Set, Map, Collections工具类)JAVA集合框架二

    Java集合框架部分细节总结二 Set 实现类:HashSet,TreeSet HashSet 基于HashCode计算元素存放位置,当计算得出哈希码相同时,会调用equals判断是否相同,相同则拒绝 ...

  2. java 集合框架(二)Iterable接口

    Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...

  3. Java集合框架(二)

    Set Set:无序,不可以重复元素. |--------HashSet:数据结构是哈希表. 线程是非同步的.保证元素唯一性的原理是:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的 ...

  4. Java日志框架(二)

    最流行的日志框架解决方案 按笔者理解,现在最流的日志框架解决方案莫过于SLF4J + LogBack.其有以下几个优点: LogBack 自身实现了 SLF4J 的日志接口,不需要 SLF4J 去做进 ...

  5. Java - Struts框架教程 Hibernate框架教程 Spring框架入门教程(新版) sping mvc spring boot spring cloud Mybatis

    https://www.zhihu.com/question/21142149 http://how2j.cn/k/hibernate/hibernate-tutorial/31.html?tid=6 ...

  6. [ SSH框架 ] Hibernate框架学习之二

    一.Hibernate持久化类的编写规范 1.什么是持久化类 Hibernate是持久层的ORM影射框架,专注于数据的持久化工作.所谓持久化,就是将内存中的数据永久存储到关系型数据库中.那么知道了什么 ...

  7. SSH框架之hibernate《二》

    Hibernate第二天     一.hibernate的持久化类和对象标识符         1.1持久化类的编写规范             1.1.1什么是持久化类:               ...

  8. Hibernate框架简介(二)基本使用增、删、改、查

    一.Hibernate框架简介 Hibernate是一个优秀的Java持久化层解决方案,是当今主流的对象-关系映射(ORM,ObjectRelationalMapping)工具 1.1.理解持久化 瞬 ...

  9. java三大框架——Struts + Hibernate + Spring

    Struts主要负责表示层的显示 Spring利用它的IOC和AOP来处理控制业务(负责对数据库的操作) Hibernate主要是数据持久化到数据库 再用jsp的servlet做网页开发的时候有个 w ...

  10. Hibernate框架(二)POJO对象的操作

    POJO对象其实就是我们的实体,这篇博客总结一下框架对POJO对象对应数据库主键的生成策略,和一些对POJO对象的简单增删改查的操作. 一,Hibernate框架中主键的生成策略有三种方式: 1,数据 ...

随机推荐

  1. [Flink] Flink的waterMark的通俗理解

    导读 Flink 为实时计算提供了三种时间,即事件时间(event time).摄入时间(ingestion time)和处理时间(processing time). 遇到的问题: 假设在一个5秒的T ...

  2. 如何删除Python中文本文件的文件内容?

    在python中: open('file.txt', 'w').close() 或者,如果你已经打开了一个文件: f = open('file.txt', 'r+') f.truncate(0) # ...

  3. JSOI 2016 病毒感染 辅助Dp问题

    原题链接:https://www.luogu.com.cn/problem/P5774 分析 直接看这道题,第一个困惑点,那个绝对值的比较是什么东西,根据数学知识,我们可以知道这个意思是k到i的距离小 ...

  4. OpenCV-Python OpenCV中的K-Means聚类 | 五十八

    目标 了解如何在OpenCV中使用cv.kmeans()函数进行数据聚类 理解参数 输入参数 sample:它应该是np.float32数据类型,并且每个功能都应该放在单个列中. nclusters( ...

  5. 硬货 | 手把手带你构建视频分类模型(附Python演练))

    译者 | VK 来源 | Analytics Vidhya 概述 了解如何使用计算机视觉和深度学习技术处理视频数据 我们将在Python中构建自己的视频分类模型 这是一个非常实用的视频分类教程,所以准 ...

  6. 累加数的贡献 CodeForces - 1213D2

    题意: 第一行输入n,k,表示有n个数,可以进行整除2操作,要是数组有k个相等的数,最少需要几次操作. 思路: 用一个数组记录每一个数出现的次数,如果一开始大于等于k,直接输出0,否则对这n个数进行从 ...

  7. shell getopts 用法

    http://www.cnblogs.com/xupeizhi/archive/2013/02/18/2915659.html http://blog.csdn.net/xluren/article/ ...

  8. F - F HDU - 1173(二维化一维-思维)

    F - F HDU - 1173 一个邮递员每次只能从邮局拿走一封信送信.在一个二维的直角坐标系中,邮递员只能朝四个方向移动,正北.正东.正南.正西. 有n个需要收信的地址,现在需要你帮助找到一个地方 ...

  9. Vertica的这些事(十四)——Vertica实时消费kafka实现

    一. 安装环境 Vertica官方提供了消费kafka的方法,需要注意版本对应 消费kafka原理,是Vertica提供的Udx 首先需要安装相应的环境 /${vertica}/packages/ka ...

  10. Window.requestAnimationFrame()动画更新

    概述 Window.requestAnimationFrame()方法告诉浏览器你希望执行动画,并且再下一次重绘之前要求浏览器调用一个特定的函数去更新动画.该方法把一个回调函数作为参数,该回调函数会在 ...