【Hibernate】Hibernate的多表查询

2015-07-21 16:27:03 · 作者: · 浏览: 3

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

比如如下的SQL语句:

select t1.Title,t1.Content
from blog as t1 ,usertable as t2
where 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 resultList = session.createQuery(hql).list();  
for (int i = 0; i < resultList.size(); i++) {  
    Object[] obj = (Object[])resultList.get(i);  
    System.out.println(obj[0]+","+obj[1]);  
}
 
核心思想,是把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的Java工程种分别对应如下实体:

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做如下的配置:

  


	
		
		com.mysql.jdbc.Driver
		
		admin
		
		jdbc:mysql://localhost:3306/test
		
		pc
		
		org.hibernate.dialect.MySQLInnoDBDialect
		true
		
		
		update
		
		
		
		
	
  
可以发现,这没有进行任何的参照完整性的指定。

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

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

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

select t1.Title,t1.Content
from blog as t1 ,usertable as t2
where t1.userid=t2.id and t2.username='a'
其查询结果如下:

\

这使用Hibernate则这样写,在HibernateMultiTableTest.java中的代码如下:<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PHByZSBjbGFzcz0="brush:sql;">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 resultList = db .query("select t1.title,t1.content from Blog as t1,Usertable as t2 where t1.userId=t2.id and t2.username='a'") .list();//HQL的多表查询 System.out.println("usertable中username为a的用户,发表的内容如下:"); System.out.println(); for (int i = 0; i < resultList.size(); i++) { Object[] obj = (Object[]) resultList.get(i); System.out.println("标题:" + obj[0]); System.out.println("内容:" + obj[1]); System.out.println(); } } } 其运行结果如下: