【Hibernate】Hibernate多表查询后,将查询结果转化为实体

在《【Hibernate】Hibernate的多表查询》(点击打开链接)一文中,已经介绍过,如果利用HQL语句进行多表查询,摆脱查完一张表又取其中的结果再查另一张表的问题。然而,利用HQL语句查询出来的东西,是一个Object数组,我们要进一步对其处理,将其转化为表的实体的实例。

有如下的一个Java工程如《【Hibernate】Hibernate3.x独立运行时的Failed to load class "org.slf4j.impl.StaticLoggerBinder"错误》(点击打开链接)一样配置Hibernate3.x功能:

【Hibernate】Hibernate多表查询后,将查询结果转化为实体_第1张图片

在数据库test中,如图,Blog记录了用户发表的博客,usertable记录了用户的基本信息。Blog表中的userid与usertable的主键id形成参照完整性。

【Hibernate】Hibernate多表查询后,将查询结果转化为实体_第2张图片

这两张表在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做如下的配置:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE hibernate-configuration PUBLIC  
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--所用的数据库驱动 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<!--所用的数据库登陆密码 -->
		<property name="hibernate.connection.password">admin</property>
		<!--所用的数据库名称为test,根据实际更改 -->
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
		<!--所用的数据库用户名 -->
		<property name="hibernate.connection.username">pc</property>
		<!--所用的数据库方言,与所用数据库驱动一样,可以在网上查到,这里是mysql -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
		<property name="hibernate.format_sql">true</property>
		<!--如果是update表明Hibernate将保留原来的数据记录,插入时把新记录添加到已有的表, -->
		<!--如果是create,则总是创建新的表,如果原来数据库已有的这个表,则这个表的记录会被全部清洗 -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		<!--罗列Testtable表与Java文件的映射 -->
		<!--将数据库中的usertable表,blog表映射到Usertable.java与Blog.java两个实体 -->
		<mapping class="Usertable" />
		<mapping class="Blog" />
	</session-factory>
</hibernate-configuration>  
同时在dbDAO.java中定义一系列的数据库操作方法如下:

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();
		}
	}

}

我们接下来要把如下多表查询的sql语句,

select *
from blog as t1 ,usertable as t2  
where t1.userid=t2.id

产生的2张表,对应的14条查询结果,这个查询结果由表blog、usertable连接产生:

【Hibernate】Hibernate多表查询后,将查询结果转化为实体_第3张图片

在HibernateMultiTableTest中利用Hibernate查询出来。整个查询结果就是一个名为resultList存放Object数组的List,那么,每一行查询结果将是一个Object数组。

从上图可以看出查询结果由表blog、usertable连接产生,而这个Object数组中,Hibernate定义,第0项就是查询结果中表blog的部分,可以利用Java强制类型将其转换Java中的Blog实体,同理第1项的查询结果就是表usertable的部分,可以利用Java强制类型将其转换Java中的Usertable实体。

得到这两个实体之后,可以如同Hibernate往常一样的NoSQL一样,对这两个实体进行操作。

import java.util.List;

public class HibernateMultiTableTest {
	@SuppressWarnings("unchecked")
	public static void main(String args[]) {
		dbDAO db = new dbDAO();
		List<Object> resultList = db.query(
				"from Blog as t0,Usertable as t1 where t0.userId=t1.id").list();// HQL的多表查询
		for (int i = 0; i < resultList.size(); i++) {
			Object[] hql_result_arr = (Object[]) resultList.get(i);//取其中一行的查询结果
			//将查询结果分成两半,分别转化为相应的实体
			Blog blog = (Blog) hql_result_arr[0];
			Usertable usertable = (Usertable) hql_result_arr[1];
			//输出
			System.out.println(blog.getId() + "," + blog.getTitle() + ","
					+ blog.getContent() + "," + blog.getUserId() + ","
					+ usertable.getId() + "," + usertable.getUsername() + ","
					+ usertable.getPassword());
		}
	}
}


你可能感兴趣的:(Hibernate,javaweb,多表查询,实体,强制类型转换)