在《【Hibernate】Hibernate的聚类查询、分组查询、排序与时间之差》(点击打开链接)一文中已经讲述过怎样利用HQL语句代替SQL语句。进行聚类查询、分组查询、排序与时间之差的查询,同一时候指出hql能代替sql语句做不论什么事情。我原本以为hql语句的多表查询,要先对里面的实体做Java与xml的改动,事实上并不须要,相同是一句HQL语句就能搞定的事情。SQL的多表查询已经在《【Mysql】利用内连接与嵌套查询实现多表查询。主键、外键的基本概念》(点击打开链接)讲过。

比方例如以下的SQL语句:

  1. select t1.Title,t1.Content
  2. from blog as t1 ,usertable as t2
  3. where t1.userid=t2.id and t2.username='a'

转换成HQL语句则例如以下:

  1. String hql="select t1.title,t1.content from Blog as t1,Usertable as t2 where t1.userId=t2.id and t2.username='a'"
  2. List<Object> resultList = session.createQuery(hql).list();
  3. for (int i = 0; i < resultList.size(); i++) {
  4. Object[] obj = (Object[])resultList.get(i);
  5. System.out.println(obj[0]+","+obj[1]);
  6. }

核心思想,是把sql语句中的表,写成Hibernate的实体。sql语句中的字段、列,写成Hibernate的实体的成员变量,同一时候必须把表使用as进行t1,t2等标记,不能使用Blog.XX字段来简化。如上,就是Blog,Usertable两张表转化为t1,t2标记,把sql的字段、列,表相应转化为Hibernate的实体成员变量,实体进行查询。

Hibernate查询出来的结果是一个存放Object数组的List,也就是说List的每项都是一个Object数组,Object数组的第n项相应查询结果的第n项。

能够再进行下一步的处理。

以下用一个样例,来说明HQL语句的多表查询。

如图,Blog记录了用户发表的博客,usertable记录了用户的基本信息。

Blog表中的userid与usertable的主键id形成參照完整性。

这两张表在Hibernate的Javaproject种分别相应例如以下实体:

Blog.java

  1. import javax.persistence.*;
  2.  
  3. @Entity
  4. @Table(name = "blog")
  5. public class Blog {
  6. private int id;
  7. private String title;
  8. private String content;
  9. private int userId;
  10.  
  11. @Id
  12. @GeneratedValue
  13. public int getId() {
  14. return id;
  15. }
  16.  
  17. public void setId(int id) {
  18. this.id = id;
  19. }
  20.  
  21. @Column(name = "Title")
  22. public String getTitle() {
  23. return title;
  24. }
  25.  
  26. public void setTitle(String title) {
  27. this.title = title;
  28. }
  29.  
  30. @Column(name = "Content")
  31. public String getContent() {
  32. return content;
  33. }
  34.  
  35. public void setContent(String content) {
  36. this.content = content;
  37. }
  38.  
  39. @Column(name = "userid")
  40. public int getUserId() {
  41. return userId;
  42. }
  43.  
  44. public void setUserId(int userId) {
  45. this.userId = userId;
  46. }
  47.  
  48. @Override
  49. public String toString() {
  50. return id + "," + title + "," + content + "," + userId;
  51. }
  52.  
  53. }

Usertable.java

  1. import javax.persistence.*;
  2.  
  3. @Entity
  4. @Table(name = "usertable")
  5. public class Usertable {
  6. private int id;
  7. private String username;
  8. private String password;
  9.  
  10. @Id
  11. @GeneratedValue
  12. public int getId() {
  13. return id;
  14. }
  15.  
  16. public void setId(int id) {
  17. this.id = id;
  18. }
  19.  
  20. @Column(name = "username")
  21. public String getUsername() {
  22. return username;
  23. }
  24.  
  25. public void setUsername(String username) {
  26. this.username = username;
  27. }
  28.  
  29. @Column(name = "password")
  30. public String getPassword() {
  31. return password;
  32. }
  33.  
  34. public void setPassword(String password) {
  35. this.password = password;
  36. }
  37.  
  38. @Override
  39. public String toString() {
  40. return id + "," + username + "," + password;
  41. }
  42. }

同一时候,hibernate.cfg.xml做例如以下的配置:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-configuration PUBLIC
  3. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
  5. <hibernate-configuration>
  6. <session-factory>
  7. <!--所用的数据库驱动 -->
  8. <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  9. <!--所用的数据库登录password -->
  10. <property name="hibernate.connection.password">admin</property>
  11. <!--所用的数据库名称为test,依据实际更改 -->
  12. <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
  13. <!--所用的数据库用户名 -->
  14. <property name="hibernate.connection.username">pc</property>
  15. <!--所用的数据库方言,与所用数据库驱动一样,能够在网上查到。这里是mysql -->
  16. <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
  17. <property name="hibernate.format_sql">true</property>
  18. <!--假设是update表明Hibernate将保留原来的数据记录,插入时把新记录加入到已有的表, -->
  19. <!--假设是create。则总是创建新的表,假设原来数据库已有的这个表。则这个表的记录会被所有清洗 -->
  20. <property name="hibernate.hbm2ddl.auto">update</property>
  21. <!--罗列Testtable表与Java文件的映射 -->
  22. <!--将数据库中的usertable表,blog表映射到Usertable.java与Blog.java两个实体 -->
  23. <mapping class="Usertable" />
  24. <mapping class="Blog" />
  25. </session-factory>
  26. </hibernate-configuration>

能够发现,这没有进行不论什么的參照完整性的指定。

以下,要查询usertable中username为a的用户。发表的Blog。

我们知道先要查询username为a的用户的id。之后利用这个查出来的id到Blog表中查询。

用sql语句完毕这个多表查询,则这样写:

  1. select t1.Title,t1.Content
  2. from blog as t1 ,usertable as t2
  3. where t1.userid=t2.id and t2.username='a'

其查询结果例如以下:

这使用Hibernate则这样写,在HibernateMultiTableTest.java中的代码例如以下:

  1. import java.util.List;
  2.  
  3. import org.hibernate.*;
  4. import org.hibernate.cfg.*;
  5.  
  6. class dbDAO {
  7. private Session session;
  8.  
  9. // 构造函数,初始化Session,相当于连接数据库
  10. public dbDAO() {
  11. // new Configuration().configure()是吧hibernate.cfg.xml中的全部配置读取进来
  12. // .buildSessionFactory().openSession()是创建Session工厂并实例化session
  13. this.session = new Configuration().configure().buildSessionFactory()
  14. .openSession();
  15. }
  16.  
  17. // 运行查询
  18. public Query query(String hql) {
  19. return session.createQuery(hql);
  20. }
  21.  
  22. // 运行插入、改动
  23. public void save(Object object) {
  24. Transaction transaction = session.beginTransaction();
  25. session.save(object);
  26. transaction.commit();
  27. }
  28.  
  29. // 运行删除
  30. public void delete(Object object) {
  31. Transaction transaction = session.beginTransaction();
  32. session.delete(object);
  33. transaction.commit();
  34. }
  35.  
  36. // 析构函数,中断Session,相当于中断数据库的连接
  37. protected void finalize() throws Exception {
  38. if (session.isConnected() || session != null) {
  39. session.close();
  40. }
  41. }
  42.  
  43. }
  44.  
  45. @SuppressWarnings("unchecked")
  46. public class HibernateMultiTableTest {
  47. public static void main(String args[]) {
  48. dbDAO db = new dbDAO();
  49. List<Object> resultList = db
  50. .query("select t1.title,t1.content from Blog as t1,Usertable as t2 where t1.userId=t2.id and t2.username='a'")
  51. .list();//HQL的多表查询
  52. System.out.println("usertable中username为a的用户,发表的内容例如以下:");
  53. System.out.println();
  54. for (int i = 0; i < resultList.size(); i++) {
  55. Object[] obj = (Object[]) resultList.get(i);
  56. System.out.println("标题:" + obj[0]);
  57. System.out.println("内容:" + obj[1]);
  58. System.out.println();
  59. }
  60. }
  61. }

其运行结果例如以下:

【Hibernate】Hibernate的多表查询的更多相关文章

  1. Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...

  2. Hibernate的HQL多表查询

    HQL的内连接查询 对于HQL内链接查询,查询的是两张表的数据,这两张表的数据首先是保存在数组之中,然后在将每一个数组保存在List集合之中进行返回 代码片段: @Test // 内连接 public ...

  3. Hibernate学习---单表查询

    我们都知道SQL是非常强大的,为什么这么说呢?相信学过数据库原理的同学们都深有体会,SQL语句变化无穷,好毫不夸张的说可以实现任意符合我们需要的数据库操作,既然前面讲到Hibernate非常强大,所以 ...

  4. hibernate多表查询封装实体

    以前用sql实现联合查询 是非常简单的事,只需要写sql语句就可以,第一次遇到hibernate要实现多表联合查询的时候还楞了一下.最后看了下资料,才恍然大悟,hibernate实现多表联合查询跟SQ ...

  5. Java面试题:Hibernate的二级缓存与Hibernate多表查询

    我们来看两个有关Java框架之Hibernate的面试题,这是关于Hibernate的常考知识点. 1.请介绍一下Hibernate的二级缓存 解题按照以下思路来回答: (1)首先说清楚什么是缓存: ...

  6. hibernate框架学习之多表查询helloworld

    package cn.itcast.h3.hql; import java.util.List; import org.hibernate.Query; import org.hibernate.Se ...

  7. Spring Hibernate JPA 联表查询 复杂查询(转)

    今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的? 是.如果hibernate认为jpa的注解够用,就直接用.否则会弄一个自己的出来作为补充. 2)jpa和hibern ...

  8. Hibernate中的HQL的基本常用小例子,单表查询与多表查询

    <span style="font-size:24px;color:#3366ff;">本文章实现HQL的以下功能:</span> /** * hql语法: ...

  9. Spring Hibernate JPA 联表查询 复杂查询

    今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的? 是.如果hibernate认为jpa的注解够用,就直接用.否则会弄一个自己的出来作为补充. 2)jpa和hibern ...

随机推荐

  1. js 类似于移动端购物车删除,左移动删除

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Go语言 之md5加密

    //方式一 func getMd5String1(str string) string { m := md5.New() _, err := io.WriteString(m, str) if err ...

  3. bat运行当前路径下程序

    批处理中获取当前路径的方法可能有好几种,具体有几种我没有研究过,本文只是对其中的两种之间的差别进行简单说明 本文涉及的两个当前路径标示为:%cd%.%~dp0 注:我的系统是win7旗舰版,其它系统没 ...

  4. caffe编译

    用make -j带一个参数,可以把项目在进行并行编译,比如在一台双核的机器上,完全可以用make -j4,让make最多允许4个编译命令同时执行,这样可以更有效的利用CPU资源 也就是说make -j ...

  5. spring cloud Bug之was unable to refresh its cache! status = Cannot execute request on any known server

    可能原因: 1.application.yml server: port: 10001spring: application: name: microservice-consumer-movieeur ...

  6. 网络爬虫之框架(Scrapy)

    Scrapy爬虫框架 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合. 爬虫框架是一个半成品,能够帮助用户实现专业网络爬虫. Scrapy爬虫框架结构:

  7. Android突破64K限制

    1.添加依赖 android{ defaultConfig{ ... multiDexEnabled true ... } } dependencies{ compile 'com.android.s ...

  8. codevs1288 埃及分数

    题目描述: 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/b,表示方法 ...

  9. python3.x Day5 subprocess模块!!

    subprocess模块: # subprocess用来替换多个旧模块和函数 os.system os.spawn* os.popen* popen2.* commands.* subprocess简 ...

  10. 初学微信小程序 TodoList

    微信小程序的学习 微信小程序的开始尝试 TodoList 微信开发者工具生成 目录如下: . |-- app.js |-- app.json |-- app.wxss |-- pages | |-- ...