Hibernate用法:查询,更新,删除!

2023-11-18

一、基本数据查询

使用Hibernate进行数据查询是一件简单的事,Java程序设计人员可以使用对象操作的方式来进行数据查询,查询时使用一种类似SQL的HQL(Hibernate Query Language)来设定查询的条件,与SQL不同的是,HQL是具备对象导向的继承、多型等特性的语言。

 

直接使用范例来看看如何使用Hibernate进行数据库查询,在这之前,请先照之前介绍过的主题在数据库中新增几笔数据:

在Hibernate中新增资料

 

查询数据时,我们所使用的是Session的find()方法,并在当中指定HQL设定查询条件,查询的结果会装载在List对象中传回,您所需要的是将它们一一取出,一个最简单的例子如下:

HibernateTest.java

import onlyfun.caterpillar.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import java.util.*;

public class HibernateTest {

public static void main(String[] args) throws HibernateException {

SessionFactory sessionFactory =

new Configuration().configure().buildSessionFactory();

Session session = sessionFactory.openSession();

List users = session.find("from User");

session.close();

sessionFactory.close();

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}

}

}

find()中的“from User”即HQL,User指的是User类别,藉由映射文件,它将会查询USER表格中的数据,相当于SQL中的SELECT * FROM USER,实际上我们的User类别是位于onlyfun.caterpillar下,Hibernate会自动看看import中的package名称与类别名称是否符合,您也可以直接指定package名称,例如:

session.find("from onlyfun.caterpillar.User");

这个程序的运行结果可能是这样的:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

user0_.age as age from USER user0_

caterpillar

Age: 28

Sex: M

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

上面所介绍的查询是最简单的,只是从数据表中查询所有的数据,Hibernate所查询得回的数据,是以对象的方式传回,以符合程序中操作的需要,我们也可以限定一些查询条件,并只传回我们指定的字段,例如:

List names = session.find("select user.name from User as user where age = 25");

for (ListIterator iterator = names.listIterator(); iterator.hasNext(); ) {

String name = (String) iterator.next();

System.out.println("name: " + name);

}

在find()中的HQL示范了条件限定的查询,User as user为User类别取了别名,所以我们就可以使用user.name来指定表格传回字段,where相当于SQL中的WHERE子句,我们限定查询age等于25的数据,这次查询的数据只有一个字段,而型态是String,所以传回的List内容都是String对象,一个运行的例子如下:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select user0_.name as x0_0_ from USER user0_ where (age=25 )

name: momor

name: Bush

如果要传回两个以上的字段,也不是什么问题,直接来看个例子:

List results = session.find("select user.name, user.age from User as user where sex = 'F'");

for (ListIterator iterator = results.listIterator(); iterator.hasNext(); ) {

Object[] rows = (Object[]) iterator.next();

String name = (String) rows[0];

Integer age = (Integer) rows[1];

System.out.println("name: " + name + "/n/t" + age);

}

从上面的程序中不难看出,传回两个以上字段时,每一次ListIterator会以Object数组的方式传回一笔数据,我们只要指定数组索引,并转换为适当的型态,即可取得数据,一个查询的结果如下:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select user0_.name as x0_0_, user0_.age as x1_0_ from USER user0_ where (sex='F')

name: momor

25

name: Becky

35

您也可以在HQL中使用一些函数来进行结果统计,例如:

List results = session.find("select count(*), avg(user.age) from User as user");

ListIterator iterator = results.listIterator();

Object[] rows = (Object[]) iterator.next();

System.out.println("资料笔数: " + rows[0] + "/n平均年龄: " + rows[1]);

一个查询的结果如下所示:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select count(*) as x0_0_, avg(user0_.age) as x1_0_ from USER user0_

资料笔数: 4

平均年龄: 28.25

 

二、更新和删除数据

如果您是在同一个Session中取出数据并想要马上进行更新,则只要先查询并取出对象,透过setXXX()方法设定好新的值,然后呼叫session.flush()即可在同一个Session中更新指定的数据,例如:

HibernateTest.java

import onlyfun.caterpillar.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import java.util.*;

public class HibernateTest {

public static void main(String[] args) throws HibernateException {

SessionFactory sessionFactory =

new Configuration().configure().buildSessionFactory();

Session session = sessionFactory.openSession();    

List users = session.find("from User");

User updated = null; 

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();

if(updated == null)

updated = user; 

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}

updated.setName("justin");

session.flush();

users = session.find("from User");  

session.close();

sessionFactory.close();

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();           

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}      

}

}

这个程序会显示数据表中的所有数据,并将数据表中的第一笔数据更新,一个执行的结果如下:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

user0_.age as age from USER user0_

caterpillar

Age: 28

Sex: M

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

Hibernate: update USER set name=?, sex=?, age=? where user_id=?

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

user0_.age as age from USER user0_

justin

Age: 28

Sex: M

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

如果您开启了一个Session,从数据表中取出数据显示到使用者接口上,之后关闭Session,当使用者在接口上操作完毕并按下储存时,这时您要重新开启一个Session,使用update()方法将对象中的数据更新至对应的数据表中,一个例子如下:

HibernateTest.java

import onlyfun.caterpillar.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import java.util.*;

public class HibernateTest {

public static void main(String[] args) throws HibernateException {

SessionFactory sessionFactory =

new Configuration().configure().buildSessionFactory();

Session session = sessionFactory.openSession();    

List users = session.find("from User");

// 关闭这个Session

session.close();

User updated = null;

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();

if(updated == null)

updated = user;

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}

// 使用者作一些操作,之后储存

updated.setName("caterpillar");

// 开启一个新的Session

session = sessionFactory.openSession();  

// 更新数据

session.update(updated);

users = session.find("from User");     

session.close();

sessionFactory.close();

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();           

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}      

}

}

这个程序执行的结果范例如下,您可以看看实际上执行了哪些SQL:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

ser0_.age as age from USER user0_

justin

Age: 28

Sex: M

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

Hibernate: update USER set name=?, sex=?, age=? where user_id=?

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

ser0_.age as age from USER user0_

caterpillar

Age: 28

Sex: M

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

Hibernate提供了一个saveOrUpdate()方法,为数据的储存或更新提供了一个统一的操作接口,藉由定义映像文件时,设定 标签的unsaved-value来决定什么是新的值必需,什么是已有的值必须更新:

User.hbm.xml







unsaved-value

可以设定的值包括:

◆any - 总是储存

◆none - 总是更新

◆null - id为null时储存(预设)

◆valid - id为null或是指定值时储存

 

这样设定之后,您可以使用session.saveOrUpdate(updated);来取代上一个程序的session.update(updated);方法。

 

如果要删除数据,只要使用delete()方法即可,直接看个例子。

HibernateTest.java

import onlyfun.caterpillar.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import java.util.*;

public class HibernateTest {

public static void main(String[] args) throws HibernateException {

SessionFactory sessionFactory =

new Configuration().configure().buildSessionFactory();

Session session = sessionFactory.openSession(); 

List users = session.find("from User");

User updated = null;

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();

if(updated == null)

updated = user;     

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}

session.delete(updated);

users = session.find("from User");

session.close();

sessionFactory.close();

for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {

User user = (User) iterator.next();           

System.out.println(user.getName() +

"/n/tAge: " + user.getAge() +

"/n/tSex: " + user.getSex());

}      

}

}

一个执行的结果范例如下:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

ser0_.age as age from USER user0_

justin

Age: 28

Sex: M

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

Hibernate: delete from USER where user_id=?

Hibernate: select user0_.user_id as user_id, user0_.name as name, user0_.sex as sex,

ser0_.age as age from USER user0_

momor

Age: 25

Sex: F

Bush

Age: 25

Sex: M

Becky

Age: 35

Sex: F

User user = (User) session.load(User.class, id);

Hibernate对于数据的更新、删除等动作,是依赖id值来判定,如果您已知id值,则可以使用load()方法来加载资料。这边我们先介绍的是一些简单的查询动作,将来有机会的话,再介绍一些进阶的查询,如果您想要先认识一些HQL,可以看看参考手册的第11章,当中对于HQL有详细的说明。

(责任编辑 火凤凰 sunsj@51cto.com  TEL:(010)68476636-8007)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate用法:查询,更新,删除! 的相关文章

  • 为什么这不会绘制图像?

    我想做的是 当我运行应用程序时 它会启动线程并且图像显示 3 秒 3000 毫秒 然后线程停止运行 图片路径正确 图片文件存在 线程本身运行 但是 图像似乎没有显示 可能出什么问题了 这是我的代码 package org main impo
  • Encog - 如何加载神经网络的训练数据

    The NeuralDataSet我在实际中看到的对象除了 XOR 之外什么都没有 它只是两个小数据数组 我无法从文档中找出任何内容MLDataSet 似乎所有内容都必须立即加载 但是 我想循环遍历训练数据 直到到达 EOF 然后将其算作
  • Lambda 表达式更慢?

    我有下面这段代码 PriorityQueue
  • 如何将 openapi-generator 中的客户端包含在 gradle java 应用程序中?

    我想创建一个 gradle java 应用程序 它从 openAPI 规范文件生成客户端并使用该客户端 所以我创建了一个java应用程序gradle init 类型 应用程序 语言 Java DSL groovy 测试框架 Junit Ju
  • Android 3.1 USB 主机 - BroadcastReceiver 未收到 USB_DEVICE_ATTACHED

    我经历过USB 主机的描述和示例位于developer android com http developer android com guide topics usb host html检测连接和分离的 USB 设备 如果我在清单文件中使用
  • Spring的@PreDestroy导致随机记录而不记录

    我正在使用 Spring 并且在终止时我让 PreDestroy 清理 bean 我不明白为什么日志记录有时会成功 而有时会失败 Using Log4j2 Logger log LogManager getLogger MyClass cl
  • 将 Spring ModelAttribute 应用于所有使用特定参数类型的控制器

    在 Spring Boot REST 应用程序中 我有一个TableRequest包含表格数据 GET 请求的列排序 筛选和分页详细信息的类型 它是通用的 因为它不关心所请求的具体数据是什么 它只指定通用表参数 因此它适用于许多不同的控制器
  • 在 JUnit 测试中读取资源文件

    我在单元测试中读取文本文件 并将一些输入文本文件放置在资源文件夹中 以下是目录结构 src gt com gt au gt myapp gt util gt MyFileReader 测试 gt com gt au gt myapp gt
  • 如何自定义 JFrame 上的标题栏?

    我想在我的 Java Swing 桌面应用程序中拥有一个自定义的标题栏 最好的方法是什么 我可以通过在 JFrame 的构造函数中使用以下代码来使用 Swing 标题栏 this setUndecorated true this getRo
  • 飞碟中的外部 CSS

    我想知道如何在 Flying Saucer 中包含外部 CSS 在此之前THB我检查了所有可用的链接StackOverflow但它们没有帮助 这就是为什么我自己做这个的原因 TestCSS xhtml重命名版本TestCSS html 所以
  • Android 改造参数化@Headers

    我正在使用 OAuth 每次发出请求时都需要将 OAuth 令牌放入标头中 我看到 Header注释 但是有没有办法让它参数化 以便我可以在运行时传入 这是概念 Header Authorization OAuth var api vers
  • Spring-data-cassandra:创建名称为“sessionFactory”的 bean 时出错,并且无法解析对 bean“cassandraTemplate”的引用

    我有一个 springboot 应用程序 在其中连接到 cassandra DB 我的 pom xml parent gt
  • 具有多个注释的方法上的 AspectJ 切入点

    使用加载时编织 纯 AspectJ 我们有2个注释 Time and Count 以及一些带注释的方法 Time name myMethod1Time Count name myMethod1Count public void myMeth
  • Kotlin 中的枚举类对于 Android 来说是否像 Java 中那样“昂贵”?

    Are EnumKotlin 中的类对于 Android 来说 昂贵 就像 Java 一样 还可以用吗 IntDefs or StringDefs在科特林 当我将 Kotlin Enum 类反编译为 Java 类时 底层仍然使用了 Java
  • 如何在打开导航抽屉时使背景 Activity 变小?

    我想做我的背景Activity打开时稍微小一点Navigation Drawer 模拟存在的效果Airbnb应用 我想最好的解释是截图 但重点不是让 View 变小 而是让它成为与 Drawer 打开 关闭动画同步的动画 因此 如果您开始打
  • 如何在 Google 地图中创建自定义地图?

    我正在尝试创建一个包含我家地图的 Google 地图应用程序 卧室 浴室 厨房等 使用 GPS 我会找到我现在在家里的位置 并尝试获取到我卧室的方向 步行距离 您可以使用Google的API来获取方向 我需要知道的是 如何添加我家的自定义地
  • android中ScrollView中的图像

    在我的应用程序中 我想放置一个 png 文件 并且希望它在横向和纵向模式下都被视为滚动图像 请建议代码或示例 要使您的 Imageview 在高度不适合时滚动 您可以在 xml 中的 ScrollView 内添加一个 ImageView 并
  • Guava MultiSet 与 Map?

    我对Multiset的理解是一个带有频率的集合 但是我总是可以使用Map来表示频率 还有其他原因使用Multiset吗 优点Multiset
  • Java并发锁和条件的使用

    我可以用object wait object notify and synchronized blocks解决生产者消费者类型的问题 同时我可以使用locks and conditions from java util concurrent
  • SWIG C 函数指针和 JAVA

    我有一些 C 代码 其中一个方法有一个函数指针作为参数 我正在尝试在我的 Android 应用程序中使用 C 代码 我决定使用 SWIG 来完成生成我需要的 java 文件的所有工作 一切都适用于常规函数 没有函数指针作为参数的函数 但我不

随机推荐