zoukankan      html  css  js  c++  java
  • 【Hibernate】Hibernate的多表查询

    在《【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<Object> 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的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做例如以下的配置:

    <?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>
    		<!--所用的数据库登录password -->
    		<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>  
    能够发现,这没有进行不论什么的參照完整性的指定。

    以下,要查询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中的代码例如以下:

    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<Object> 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();
    		}
    	}
    }
    
    其运行结果例如以下:

  • 相关阅读:
    MarkDown语法总结
    HashMap
    [LeetCode] 102. Binary Tree Level Order Traversal(二叉树的中序遍历)
    [LeetCode] 287. Find the Duplicate Number(寻找重复数字)
    [LeetCode] 215. Kth Largest Element in an Array(数组里的第 k 大元素)
    [LeetCode] 39. Combination Sum(组合的和)
    [LeetCode] 49. Group Anagrams(分组相同字母异序词)
    [LeetCode] 48. Rotate Image(旋转图片)
    [LeetCode] 647. Palindromic Substrings(回文子串)
    [LeetCode] 238. Product of Array Except Self(数组除自身元素外的乘积)
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6917713.html
Copyright © 2011-2022 走看看