在Java的Hibernate框架中使用SQL语句的简单介绍
作者:cxshun 发布时间:2022-06-13 15:54:15
Hibernate中有HQL查询语法。但我们用得比较熟的还是数SQL语句,那么应该怎么来让Hibernate支持SQL呢?这个不用我们去考虑了,Hibernate团队已经早就做好了。
废话不说,直接来例子啦。
select * from t_user usr
上面是一条SQL语句,又是废话,是个人都知道。我们想让Hibernate执行这条语句,怎么办呢?看代码:
Query query = session.createSQLQuery("select * from t_user usr");
就这样,剩下来的,大家应该都知道了,平常的查询。
那查询完之后,返回的是什么东西呢?
while(iter.hasNext()){
Object[] objs = (Object[])iter.next();
for (int i = 0; i < objs.length; i++) {
System.out.print(objs[i]);
}
System.out.println();
}
返回的每个结果都是Object[]数组,
这时又有人跑出来说面向对象啦。对,就是面向对象,唉,没办法。
我们继续看:
select {usr.*} from t_user usr
看到这里,估计某些童鞋开始鸡动啦,那个大括号什么东西啦?
别急,慢慢来。我们先继续看代码。
Query query = session.createSQLQuery("select {usr.*} from t_user usr").addEntity(TUser.class);
我们看到跟前面不同的是,我们加了一个addEntity,是什么意思呢?
我们直接API,看到这样一串解释:
addEntity
SQLQuery addEntity(String tableAlias,
Class entityType)
Declare a "root" entity
Parameters:
tableAlias - The SQL table alias
entityType - The java type of the entity to add as a root
有跟没一个样,杯具。只能自己动手用用。
第一个参数是指表的别名,就像上面的语句,我们表的别名是usr,所以第一个参数为usr,而第二个是指查询到的结果需要映射到哪个类,这里由于我们在映射文件中是通过TUser映射到t_user表,所以我们这里当然也就是TUser啦。然后一查,有SQL语句出来,而且查到的结果是TUser类型的。
我们查到的结果是:
org.hibernate.tutorial.domain6.TUser@198cb3d
当然,你们的肯定跟我不一样的。不要鸡动。
也许我们并不需要全部进行查出,这时,我们需要的只是设定别名即可:
select u.id as {usr.id},u.name as {usr.name},u.age as {usr.age} from t_user u
我们看到我们用了as指定了字段的别名,程序中还是一样:
Query query = session.createSQLQuery("select u.id as {usr.id},u.name as {usr.name},u.age as {usr.age} from t_user u").addEntity("usr",TUser.class);
这个简单,不多说。
以前我们讲到,有些团队会规定不给在代码中写SQL语句,这又需要配置文件出马啦。
我们可以在配置文件中添加:
<sql-query name="queryTUser">
<return alias="usr" entity-name="org.hibernate.tutorial.domain6.TUser" />
select {usr.*} from t_user usr where name=:name
</sql-query>
注意,这里的entity-name需要写完整的包名,不然会报错的。这里我们有子标签return,它指定了表的别名和类名,这样我们在运行时就不需要再addEntity了。
看代码:
Query query = session.getNamedQuery("queryTUser");
query.setParameter("name","shun");
List list = query.list();
Iterator iter = list.iterator();
我们直接这样就OK了,注意,我们并没有加addEntity了,主要还是归功于配置文件中的配置。
注意,如果在配置文件中配置,一定要有return子标签指定表别名和类名。这个主要是避免了我们读取语句时的重复判断。
上面讲了这么久,我们一直在讲有别名的表,那么如果我们的表没有别名,但又想返回的结果封装在对象内,我们应该怎样呢?
select * from t_user usr
很简单,只要调用addEntity的重载方法addEntity(Class clazz)就行了,只需要提供一个类名,而不需要表别名。
当然,hibernate也支持存储过程,只需要在配置文件中把sql-query的callable属性设为true即表示当前调用的是存储过程,由于存储过程我接触地不多,以后多研究一下再跟大家一起研究。
我们在调用session.save等相应的对数据操作的方法时,它会转换成hibernate内置的SQL语句,但如果我们想自己控制SQL语句的格式呢,怎么办?
Hibernate实际上也想到了。
我们直接在映射文件中加入:
<sql-insert>
INSERT INTO T_USER (NAME,AGE) values (?,?)
</sql-insert>
<sql-update>
UPDATE USER SET USER_NAME=?,AGE=? WHERE uSER_ID=?
</sql-update>
注意,这个需要添加在class标签内,作为子标签。我们这里全部是大写字母,是为了跟hibernate默认的语句分清,没有其他意思。
我们先来看一下insert的调用:
User user = new User();
user.setName("shun123123");
user.setAge(23);
当我们调用保存时,hibernate的语句是:
Hibernate:
INSERT INTO USER(USER_NAME,AGE) values(?,?)
它调用了我们配置的sql-insert标签内的语句
我们再来看一下update的调用:
User user = (User)session.get(User.class,new Long(29));
user.setName("shun123123");
user.setAge(23);
session.save(user);
我们调用保存,它会自动调用更新,此时的语句是:
Hibernate:
UPDATE USER SET USER_NAME=?,AGE=? WHERE uSER_ID=?
我们看到输出的语句是大写的,也就是调用了我们配置的语句。
delete语句也是同样的配置。
猜你喜欢
- java简易小游戏制作游戏思路:设置人物移动,游戏规则,积分系统,随机移动的怪物,游戏胜负判定,定时器。游戏内容部分package 代码部分
- 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机
- 要求: * 判断用户输入的年份是平年还是闰年实现代码:import java.util.Scanner;/** * 要
- 今天在做数据分页显示的时候遇到了一个问题,经过测试,证实是Tomcat 6的一个bug,我所用的版本为:apache-tomcat-6.0.
- 先看MVC模式流程图(其实MVC设计模式就是java中的model2。): &nb
- CancellationTokenCancellationToken有一个构造函数,可以传入一个bool类型表示当前的Cancellatio
- 目录一、前言二、JMH概述1、什么是JMH2、JMH适用的典型场景3、JMH基本概念三、JMH的使用1、快速跑起来2、JMH常用注解详细介绍
- 由于经常用到文件处理,便自己封装了下 分享给大家。 包含写入文本 批量删除文件 下载文件 。--可直接使用/// <summary&g
- 本文实例为大家分享了C++实现图书馆管理系统的具体代码,供大家参考,具体内容如下总体思想用C++开发图书馆管理系统需要对学生和图书分别建立c
- 不记得从哪找的了,修改了部分代码,修复在Android平台下使用时,时区时间格式异常的问题。package cn.aikongmeng.de
- java控制台输入有如下几个方法1、JDK 1.4 及以下版本读取的方法JDK 1.4 及以下的版本中要想从控制台中输入数据只有一种办法,即
- 页面提交请求参数有两种,一种是form格式提交,一种json格式提交通常情况下我们使用的都是form格式提交的数据,数据格式:k=v&
- 1、SerialPortHelper「Android串口通信」介绍原项目地址https://github.com/freyskill/Ser
- 前言在做项目的时候,如果项目是前后分离的,后端一定要和前端或者是移动端对接接口,那么问题来了,接口是不是要自己写给他们看,一般的会采用Exc
- 1.准备工作1、新建一个SpringBoot项目加上web依赖, 所有依赖<dependency><groupId>
- Unity2018已经把打包过程简化很多了我们只需要关心两个API:1.BuildPipline.BuildAssetBundles() 打
- ImageView是用于界面上显示图片的控件。属性1、为ImageView设置图片①android:src="@drawable/
- 本文将是JVM 性能优化系列的第二篇文章(第一篇:传送门),Java 编译器将是本文讨论的核心内容。本文中,作者(Eva Andreasso
- 目录实现基础_routeNamed_flushHistoryUpdatesaddpushpopremove总结整个 flutter 应用的运
- 我们平时使用的一些常见队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了De