您的位置:首页 > 其它

利用hibernate的动态模型进行多表查询

2016-03-21 13:43 393 查看
实验条件:实验所用的数据库软件为Mysql,数据库store包含user( userID int, userName varchar(45), phone varchar(45))和goods(goodsID int, goodsName varchar(45), userID int)两个表。

实验目的:利用hibernate的动态模型进行多表查询。

项目的结构如下:

1.在没有使用动态模型的时候。要为user和goods两个表分别建立一个po类,并为多表查询的结果建立UserGoods.java这个po类,然后进行查询(此时po包中有User.java,user.hbm.xml,Goods.java,goods.hbm.xml,UserGoods.java):

Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
<strong>String hql = "select new po.UserGoods(u.userName, u.phone, g.goodsName) from <span style="color:#ff0000;">User u, Goods g</span> where u.userID=g.userID";	</strong>
Query query = session.createQuery(hql);
List<<span style="font-family: Arial, Helvetica, sans-serif; "><strong>UserGoods</strong></span><span style="font-family: Arial, Helvetica, sans-serif;">> list = query.list();</span>
for (<span style="font-family: Arial, Helvetica, sans-serif; "><strong>UserGoods<span style="color:#ff0000;"> </span></strong></span><span style="font-family: Arial, Helvetica, sans-serif;">entry : list) {</span>
System.out.println(entry.getUserName() + ":" + entry.getGoodsName() + ":" + entry.getPhone());
}
session.close();
sessionFactory.close();
这里要注意的是hql语句中“new po.UserGoods(u.userName, u.phone, g.goodsName)”要求UserGoods.java中有相应的构造函数。

2.使用动态模型。此时po包中只有user.hbm.xml,goods.hbm.xml,UserGoods.java,但是hbm.xml中的内容和原来的有些区别(1.没有使用动态模型的hbm.xml文件的class标签中的name属性指定的是在po包中的User类,而动态模型的entity-name指定的是一个实体名,2.id和property标签的使用不同):

原来:
<class name="po.User" table="user">
 <id name="userID" column="userID" type="java.lang.Integer"/>
<property name="userName"column="userName" type="java.lang.String"/>
<property name="phone"column="phone" type="java.lang.String"/>
</property>
</class>
现在:
<class entity-name="User" table="user">
        <id name="userID" type="java.lang.Integer">
            <column name="userID" />
        </id>
        <property name="userName" type="java.lang.String">
            <column name="userName"/>
        </property>
        <property name="phone" type="java.lang.String">
            <column name="phone"/>
        </property>
</class>
执行代码:

.............
String hql = "select new po.UserGoods(u.userName, u.phone, g.goodsName) from User u, Goods g where u.userID=g.userID";
//String hql = "from Usergoods2";
Query query = session.createQuery(hql);
List<UserGoods> list = query.list();
for (UserGoods entry : list) {
<span style="white-space:pre">	</span>System.out.println(entry.getUserName() + ":" + entry.getGoodsName() + ":" + entry.getPhone());
} 
.............


hql语句是一样的,但是Goods.java和User.java类已经删除了,User u, Goods g现在只是两个HashMap对象我还担心from子句会出问题,没想到hibernate会自动处理。

3.动态模型+view。因为一个hbm.xml映射文件只对应一个表的全部或者多个列,不能对应多个表,因此,我先在数据库创建一个view,然后在po包中添加了一个映射文件new_view.hbm.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class entity-name="Usergoods2" table="new_view" >
<id name="userName" type="java.lang.String">
<column name="userName" />
</id>
<property name="phone" type="java.lang.String">
<column name="phone" />
</property>
<property name="goodsName" type="java.lang.String">
<column name="goodsName" />
</property>
</class></hibernate-mapping>
table指定为创建的view而不是表,entity-name改成Usergoods2,不使用原来的Usergoods.java类。执行代码:

<span style="white-space:pre">		</span>String hql = "from Usergoods2";
Query query = session.createQuery(hql);
List<HashMap> list = query.list();
for (HashMap entry : list) {
System.out.println(entry.get("userName") + ":" + entry.get("goodsName") + ":" + entry.get("phone"));
}
query.list()返回的对象变成List<HashMap>,而不是实体类。但是出现了一个问题,前面两种方法查询的结果都是正确的,返回的结果:

Tom:薯片:1234234
Jack:薯片:243354
<span style="color:#ff0000;">Tom:面包:1234234
Jack:棒棒糖:243354</span>


但是使用这个方法返回的则是:

Tom:薯片:1234234
Jack:薯片:243354
<pre name="code" class="plain"><span style="color:#ff0000;">Tom:薯片:1234234
Jack:薯片:243354</span>


下面两个只是上面两个的重复,网上的说view中的条目是不需要有主键的,但是在hibernate中却必须指定主键,上面指定userName为主键,但是userName在view中重复出现,此时就会造成上面的情况,想避免的话,要把goodsID添加进去并作为主键才行。

综上,还是使用第二种方法会比较好:基本表使用动态模型,为多表查询建立一个实体类,使用hql语句:

select new po.UserGoods(u.userName, u.phone, g.goodsName) from <span style="color: rgb(255, 0, 0);">User u, Goods g</span> where u.userID=g.userID;
select new 包名.实体类(参数) from 基本表动态实体 a[,<span style="font-family: Arial, Helvetica, sans-serif;">基本表动态实体 b, </span><span style="font-family: Arial, Helvetica, sans-serif;"> ...</span><span style="font-family: Arial, Helvetica, sans-serif;">]  where 条件;</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: