在《【Hibernate】Hibernate的聚类查询、分组查询、排序与时间之差》()一文中已经讲述过怎样利用HQL语句代替SQL语句。进行聚类查询、分组查询、排序与时间之差的查询,同一时候指出hql能代替sql语句做不论什么事情。我原本以为hql语句的多表查询,要先对里面的实体做Java与xml的改动,事实上并不须要,相同是一句HQL语句就能搞定的事情。SQL的多表查询已经在《【Mysql】利用内连接与嵌套查询实现多表查询。主键、外键的基本概念》()讲过。
比方例如以下的SQL语句:
select t1.Title,t1.Contentfrom blog as t1 ,usertable as t2where t1.userid=t2.id and t2.username='a'转换成HQL语句则例如以下:
String hql="select t1.title,t1.content from Blog as t1,Usertable as t2 where t1.userId=t2.id and t2.username='a'" List核心思想,是把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
import javax.persistence.*;@Entity@Table(name = "blog")public class Blog { private int id; private String title; private String content; private int userId; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @Column(name = "Content") public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Column(name = "userid") public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } @Override public String toString() { return id + "," + title + "," + content + "," + userId; }}Usertable.java
import javax.persistence.*;@Entity@Table(name = "usertable")public class Usertable { private int id; private String username; private String password; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "username") public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Column(name = "password") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return id + "," + username + "," + password; }}
同一时候,hibernate.cfg.xml做例如以下的配置:
能够发现,这没有进行不论什么的參照完整性的指定。 以下,要查询usertable中username为a的用户。发表的Blog。com.mysql.jdbc.Driver admin jdbc:mysql://localhost:3306/test pc org.hibernate.dialect.MySQLInnoDBDialect true update
我们知道先要查询username为a的用户的id。之后利用这个查出来的id到Blog表中查询。
用sql语句完毕这个多表查询,则这样写:
select t1.Title,t1.Contentfrom blog as t1 ,usertable as t2where t1.userid=t2.id and t2.username='a'其查询结果例如以下:
这使用Hibernate则这样写,在HibernateMultiTableTest.java中的代码例如以下:
import java.util.List;import org.hibernate.*;import org.hibernate.cfg.*;class dbDAO { private Session session; // 构造函数,初始化Session,相当于连接数据库 public dbDAO() { // new Configuration().configure()是吧hibernate.cfg.xml中的全部配置读取进来 // .buildSessionFactory().openSession()是创建Session工厂并实例化session this.session = new Configuration().configure().buildSessionFactory() .openSession(); } // 运行查询 public Query query(String hql) { return session.createQuery(hql); } // 运行插入、改动 public void save(Object object) { Transaction transaction = session.beginTransaction(); session.save(object); transaction.commit(); } // 运行删除 public void delete(Object object) { Transaction transaction = session.beginTransaction(); session.delete(object); transaction.commit(); } // 析构函数,中断Session,相当于中断数据库的连接 protected void finalize() throws Exception { if (session.isConnected() || session != null) { session.close(); } }}@SuppressWarnings("unchecked")public class HibernateMultiTableTest { public static void main(String args[]) { dbDAO db = new dbDAO(); List其运行结果例如以下: