hibernate一对多查询问题实例讲解

hibernate 一对多 查询问题

product物品表,photo物品照片表,一个物品对应5张照片



双向关联映射已经做好了,查product的时候用的criteria条件查询



怎么在查 所有的 product的时候,同时把每个product对应的一张photo也查出来 ?
代码在这里
Goods物品表,photo物品照片表,一个物品对应5张照片



双向关联映射已经做好了,查goods的时候用的criteria条件查询



怎么在查 所有的 goods的时候,同时把每个goods对应的一张photo也查出来 ?
贴代码了,太多了,不爱看的不看吧,高手们帮我看一下,我应该怎么写代码,才能在后台和页面取得photoName。
就是html代码部分我要<img src='../images/<s:property value="photos"/>拿到photoName,这里怎么改才能正确显示图片,怎么做呢?
问题已经解决,更新代码了。
html代码

[xhtml] view plaincopy

  1. <form id=”searchForm” name=”searchForm” action=”retrieveGoodsAction_retrieveAllGoods”>
  2.             <s:hidden name=”frontGoodsQueryCriteria.sortHelper.colIndex” id=”index” value=”0″></s:hidden>
  3.             <s:hidden name=”frontGoodsQueryCriteria.sortHelper.colName” id=”colName” value=”goodsId”></s:hidden>
  4.             <s:hidden name=”frontGoodsQueryCriteria.sortHelper.sortedType” id=”colType” value=”asc”></s:hidden>
  5. <s:hidden name=”page.pageNo” value=”1″></s:hidden>
  6. 省略提交按钮
  7. <s:iterator value=”page.content”  id=”l”>
  8.                             <li> 0
  9.                                 <div class=”pro_disp pro_104px”>
  10.                                     <a href=’retrieveGoodsAction_retrieveGoodsById?goodsId=<s:property value=”goodsId”></a>’ target=”_blank”>
  11.                                         <img src=’../imagesGoods/<s:iterator value=”photos”><s:property value=”photoName”/></s:iterator>’ alt=”图片不正确” />
  12.                                     </a>
  13.                                 </div>
  14.                                 <b class=”p_overflow”>
  15.                                     <a href=’retrieveGoodsAction_retrieveGoodsById?goodsId=<s:property value=”goodsId”></a>’ target=”_blank” title=’<s:property value=”goodsName”/>’>
  16.                                         <s:property value=”goodsName”/>
  17.                                     </a>
  18.                                 </b>
  19.                             </li>
  20.                         </s:iterator>
  21. </form>
action代码

[java] view plaincopy

  1. public class RetrieveGoodsAction extends BaseAction{
  2.     private Integer cateId;
  3.     private Integer goodsId;
  4.     private List<Goods> lgoods;
  5.     private Set<Photo> photos = new HashSet<Photo>(0);
  6.     // 创建page对象,保存分页信息
  7.     Page page = new Page();
  8.     // 创建查询条件,接收页面的adminName,adminDesc,并默认根据adminID排序
  9.     private GoodsQueryCriteria frontGoodsQueryCriteria=
  10.         new GoodsQueryCriteria(new SortHelper(“goodsId”));//默认排序ID
  11.     /**
  12.     * @Title: retrieveAllGoods
  13.     * @Description: (分页查询所有物品,显示在首页上)
  14.     * @return String error or success
  15.     * @throws Exception
  16.     */
  17.     public String retrieveAllGoods() throws Exception{
  18.         page = fgmi.goodsInfoByPage(page, frontGoodsQueryCriteria);
  19.         Iterator itr = page.getContent().iterator();
  20.         while(itr.hasNext()){
  21.             Goods goods = (Goods) itr.next();
  22.             photos = goods.getPhotos();
  23.             System.out.println( ”物品名称:” + goods.getGoodsName());
  24.             Iterator it = goods.getPhotos().iterator();
  25.             while(it.hasNext()){
  26.                 Photo ph =(Photo)it.next();
  27.                 System.out.println(“图片名:” + ph.getPhotoName());
  28.             }
  29.             //setPhotos(goods.getPhotos());
  30.             System.out.println(“———111++++++++==”);
  31.         }
  32.         if(page != null){
  33.             return ”retrieveSuccess”;
  34.         }
  35.         return ERROR;
  36.     }
  37.     public Integer getCateId() {
  38.         return cateId;
  39.     }
  40.     public void setCateId(Integer cateId) {
  41.         this.cateId = cateId;
  42.     }
  43.     public Integer getGoodsId() {
  44.         return goodsId;
  45.     }
  46.     public void setGoodsId(Integer goodsId) {
  47.         this.goodsId = goodsId;
  48.     }
  49.     public List<Goods> getLgoods() {
  50.         return lgoods;
  51.     }
  52.     public void setLgoods(List<Goods> lgoods) {
  53.         this.lgoods = lgoods;
  54.     }
  55.     public Page getPage() {
  56.         return page;
  57.     }
  58.     public void setPage(Page page) {
  59.         this.page = page;
  60.     }
  61.     public GoodsQueryCriteria getFrontGoodsQueryCriteria() {
  62.         return frontGoodsQueryCriteria;
  63.     }
  64.     public void setFrontGoodsQueryCriteria(
  65.             GoodsQueryCriteria frontGoodsQueryCriteria) {
  66.         this.frontGoodsQueryCriteria = frontGoodsQueryCriteria;
  67.     }
  68.     public Set<Photo> getPhotos() {
  69.         return photos;
  70.     }
  71.     public void setPhotos(Set<Photo> photos) {
  72.         this.photos = photos;
  73.     }
  74. }
ManagerImpl里的方法

[java] view plaincopy

  1. /**
  2.     * @Title: goodsInfoByPage
  3.     * @Description: (分页查询)
  4.     * @param  page  Page对象
  5.     * @param  goodsQueryCriteria 查询条件
  6.     * @return page Page对象
  7.     * @throws CampusException
  8.     */
  9.     public Page goodsInfoByPage(Page page, GoodsQueryCriteria frontGoodsQueryCriteria) throws CampusException {
  10.         try{
  11.             page.setTotalRecNum(new Long(frontGoodsDao.queryGoodsTotal(frontGoodsQueryCriteria)));
  12.             page.setContent(frontGoodsDao.queryGoodsByPage(page.getStartIndex().intValue(), page
  13.                 .getPageSize(), frontGoodsQueryCriteria));
  14.             return page;
  15.         }catch (Exception e){
  16.             e.printStackTrace();
  17.             //log.debug(e.getMessage());
  18.             throw new CampusException();
  19.         }
  20.     }
dao代码

[java] view plaincopy

  1. /**
  2.      * @Title: queryGoodsByPage
  3.      * @Description: (分页查询符合条件的Goods实例)
  4.      * @param startIndex 当前页面显示的第一条记录的索引
  5.      * @param fetchSize  页面显示的条数
  6.      * @param frontGoodsQueryCriteria 查询条件
  7.      * @return  符合条件的Goods实例
  8.      * @throws
  9.      */
  10.     public List<Goods> queryGoodsByPage(int startIndex, int fetchSize, GoodsQueryCriteria frontGoodsQueryCriteria) {
  11.         DetachedCriteria criteria=this.buildCriteria(frontGoodsQueryCriteria);
  12.         List<Goods> goods = this.getHibernateTemplate().findByCriteria(criteria, startIndex - 1, fetchSize);
  13.         return goods;
  14.     }
  15.     /**
  16.     * @Title: queryGoodsTotal
  17.     * @Description: (查询符合条件的Goods实例记录数)
  18.     * @param  frontGoodsQueryCriteria 查询条件
  19.     * @return integer,符合条件的数目
  20.     * @throws
  21.     */
  22.     public Integer queryGoodsTotal(GoodsQueryCriteria frontGoodsQueryCriteria){
  23.         DetachedCriteria criteria=this.buildCriteria(frontGoodsQueryCriteria);
  24.         criteria.setProjection(Projections.rowCount());
  25.         return (Integer)this.getHibernateTemplate().findByCriteria(criteria).get(0);
  26.     }
  27.     /**
  28.      * @Title: buildCriteria
  29.      * @Description: (创建hibernate查询条件,完成多条件查询功能)
  30.      * @param frontGoodsQueryCriteria 查询条件
  31.      * @return  符合条件的DetachedCriteria实例
  32.      * @throws
  33.      */
  34.     private DetachedCriteria buildCriteria(GoodsQueryCriteria frontGoodsQueryCriteria)
  35.     {
  36.         DetachedCriteria criteria=DetachedCriteria.forClass(Goods.class);
  37.         // 查询条件物品Id
  38.         if (frontGoodsQueryCriteria.getGoodsId() != null){
  39.             criteria.add(Restrictions.like(“goodsId”,frontGoodsQueryCriteria.getGoodsId().trim(), MatchMode.ANYWHERE));
  40.         }
  41.         // 查询条件物品名称
  42.         if (StringUtils.isNotEmpty(frontGoodsQueryCriteria.getGoodsName())){
  43.             criteria.add(Restrictions.like(“goodsName”, frontGoodsQueryCriteria.getGoodsName().trim(), MatchMode.ANYWHERE));
  44.         }
  45.         // 查询条件物品状态
  46.         if (frontGoodsQueryCriteria.getGoodsStatus() != null){
  47.             criteria.add(Restrictions.like(“goodsStatus”,frontGoodsQueryCriteria.getGoodsStatus()));
  48.         }
  49.         // 查询条件物品是否在架
  50.         if (frontGoodsQueryCriteria.getGoodsShelf() != null){
  51.             criteria.add(Restrictions.like(“goodsShelf”,frontGoodsQueryCriteria.getGoodsShelf()));
  52.         }
  53.         if (frontGoodsQueryCriteria.getSortHelper() != null){
  54.             if(frontGoodsQueryCriteria.getSortHelper().getSortedType().equals(“desc”))
  55.                    criteria.addOrder(Property.forName(frontGoodsQueryCriteria.getSortHelper().getColName()).desc());
  56.                 else
  57.                    criteria.addOrder(Property.forName(frontGoodsQueryCriteria.getSortHelper().getColName()).asc());
  58.             }
  59.         return criteria;
  60.     }
映射文件photo.hbm.xml

[xhtml] view plaincopy

  1. <?xml version=”1.0″?>
  2. <!DOCTYPE hibernate-mapping PUBLIC ”-//Hibernate/Hibernate Mapping DTD 3.0//EN”
  3. “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>
  4. <!– Generated 2011-5-30 18:47:47 by Hibernate Tools 3.3.0.GA –>
  5. <hibernate-mapping  package=”com.campus.back.model”>
  6.     <class name=”Photo” table=”t_photo”>
  7.         <id name=”photoId” type=”int”>
  8.             <column name=”photo_id” />
  9.             <generator class=”increment” />
  10.         </id>
  11.         <many-to-one name=”goods” class=”Goods” fetch=”select” lazy=”false”>
  12.             <column name=”goods_id” />
  13.         </many-to-one>
  14.         <property name=”photoName” type=”string”>
  15.             <column name=”photo_name” length=”50″ />
  16.         </property>
  17.         <property name=”photoCaption” type=”string”>
  18.             <column name=”photo_caption” length=”50″ />
  19.         </property>
  20.     </class>
  21. </hibernate-mapping>
Photo.java

[java] view plaincopy

  1. public class Photo implements java.io.Serializable {
  2.     private int photoId;
  3.     private Goods goods;
  4.     private String photoName;
  5.     private String photoCaption;
  6. }
Goods.hbm.xml

[xhtml] view plaincopy

  1. <?xml version=”1.0″ encoding=”UTF-8″?>
  2. <!DOCTYPE hibernate-mapping
  3.     PUBLIC ”-//Hibernate/Hibernate Mapping DTD 3.0//EN”
  4.     ”http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>
  5. <!– Hibernate映射文件的根元素 –>
  6. <hibernate-mapping package=”com.campus.back.model”>
  7.     <class name=”Goods” table=”t_goods”>
  8.         <!– 映射标识属性 –>
  9.         <id  name=”goodsId” type=”string” column=”goods_id”>
  10.             <!– 指定主键生成策略 –>
  11.             <generator class=”assigned”/>
  12.         </id>
  13.         <!– 映射普通属性 –>
  14.         <property name=”goodsName” column=”goods_name” type=”string”
  15.              length=”60″ not-null=”false”/>
  16.         <property name=”goodsNew” column=”goods_new” type=”string”
  17.              length=”1″ />
  18.         <property name=”goodsDetail” column=”goods_detail” type=”string”
  19.              length=”65535″ />
  20.         <property name=”goodsStatus” column=”goods_status” type=”string”
  21.              length=”1″ not-null=”false”/>
  22.         <property name=”goodsRegist”>
  23.             <column name=”goods_regist” sql-type=”datetime”/>
  24.         </property>
  25.         <property name=”goodsValidity” column=”goods_validity” type=”string”
  26.              length=”3″ />
  27.         <property name=”goodsStart”>
  28.              <column name=”goods_start” sql-type=”datetime”/>
  29.         </property>
  30.         <property name=”goodsEnd”>
  31.             <column name=”goods_end” sql-type=”datetime”/>
  32.         </property>
  33.         <property name=”goodsShelf” column=”goods_shelf” type=”string”
  34.              length=”1″ />
  35.         <many-to-one name=”cate” class=”Cate” fetch=”select” lazy=”false”>
  36.             <column name=”category_id”/>
  37.         </many-to-one>
  38.         <many-to-one name=”user” class=”User” fetch=”select” lazy=”false”>
  39.             <column name=”user_id”/>
  40.         </many-to-one>
  41.         <set name=”photos” table=”t_photo” inverse=”true” lazy=”false” fetch=”select”>
  42.             <key>
  43.                 <column name=”goods_id” not-null=”false” />
  44.             </key>
  45.             <one-to-many class=”Photo” />
  46.         </set>
  47.     </class>
  48. </hibernate-mapping>
Goods.java

[java] view plaincopy

  1. import java.util.Date;
  2. import java.util.HashSet;
  3. import java.util.Set;
  4. /**
  5.  * @ClassName: Goods
  6.  * @Description: TODO(定义持久化PO类,映射t_goods表)
  7.  * @author neo-dong
  8.  * @date 2011-4-10 下午09:06:47
  9.  * @version v1.0
  10.  *
  11.  */
  12. public class Goods {
  13.     /** 物品ID */
  14.     private String goodsId;
  15.     /** 物品名称 */
  16.     private String goodsName;
  17.     /** 物品新旧程度  */
  18.     private String goodsNew;
  19.     /** 物品详情 */
  20.     private String goodsDetail;
  21.     /** 物品状态 */
  22.     private String goodsStatus;
  23.     /** 物品登记日期 */
  24.     private Date goodsRegist;
  25.     /** 物品是否上架 */
  26.     private String goodsShelf;
  27.     /** 物品有效日期,自登记日期开始计算 */
  28.     private String goodsValidity;
  29.     /** 物品开始交换日期*/
  30.     private Date goodsStart;
  31.     /** 物品结束交换日期 */
  32.     private Date goodsEnd;
  33.     private Cate cate;
  34.     private User user;
  35.     private Set<Photo> photos = new HashSet<Photo>(0);
  36. }
实现分页功能的相关的类
Page.java

[java] view plaincopy

  1. package com.campus.common;
  2. import java.util.Collection;
  3. /**
  4.  * @ClassName: Page
  5.  * @Description: TODO(分页所需的类,一个javabean,包含所需的page属性)
  6.  * @date 2011-4-8 下午09:00:20
  7.  * @version v1.0
  8.  *
  9.  */
  10. public class Page {
  11.     private Integer pageNo = new Integer(1); // 当前页号
  12.     private Integer pageSize; // 每页记录条数
  13.     private Collection content; // 本页记录集
  14.     private Long totalRecNum; // 总记录条数
  15. //  private Integer totalPageNum; // 总页面数量
  16. //  private Boolean prePage; // 是否有上一页
  17. //  private Boolean nextPage; // 是否有下一页
  18. //  private Integer startIndex; // 本页记录开始编号
  19. //  private Integer endIndex; // 本页记录结束编号
  20.     public Page(Integer pageNo)
  21.     {
  22.         super();
  23.         this.pageNo=pageNo;
  24.         this.pageSize=10;
  25.     }
  26.     public Page()
  27.     {
  28.         this(new Integer(1));
  29.     }
  30.     public Integer getPageNo() {
  31.         return pageNo;
  32.     }
  33.     public void setPageNo(Integer pageNo) {
  34.         this.pageNo = pageNo;
  35.     }
  36.     public Integer getPageSize() {
  37.         return pageSize;
  38.     }
  39.     public void setPageSize(Integer pageSize) {
  40.         this.pageSize = pageSize;
  41.     }
  42.     public Collection getContent() {
  43.         return content;
  44.     }
  45.     public void setContent(Collection content) {
  46.         this.content = content;
  47.     }
  48.     public Long getTotalRecNum() {
  49.         return totalRecNum;
  50.     }
  51.     public void setTotalRecNum(Long totalRecNum) {
  52.         this.totalRecNum = totalRecNum;
  53.     }
  54.     public Integer getTotalPageNum() {
  55.         return totalRecNum%pageSize!=0?(int)(totalRecNum/pageSize+1):(int)(totalRecNum/pageSize);
  56.     }
  57.     public Boolean getPrePage() {
  58.         return pageNo>1;
  59.     }
  60.     public Boolean getNextPage() {
  61.         return pageNo<this.getTotalPageNum();
  62.     }
  63.     public Long getStartIndex() {
  64.         return 1L*pageSize*(pageNo-1)+1;
  65.     }
  66.     public Long getEndIndex() {
  67.         return pageSize*pageNo>this.getTotalRecNum()?this.getTotalRecNum():pageSize*pageNo;
  68.     }
  69. }
SortHelper.java

[java] view plaincopy

  1. /**
  2.  * @ClassName: SortHelper
  3.  * @Description: TODO(用于分页结果排序,决定根据哪列排序)
  4.  * @date 2011-4-8 下午09:02:28
  5.  * @version v1.0
  6.  *
  7.  */
  8. public class SortHelper {
  9.     private Integer colIndex;
  10.     private String colName;
  11.     private String sortedType;
  12.     public SortHelper() {
  13.     }
  14.     public SortHelper(String colName) {
  15.         colIndex = 0;
  16.         sortedType = ”asc”;
  17.         this.colName = colName;
  18.     }
  19.     public Integer getColIndex() {
  20.         return colIndex;
  21.     }
  22.     public void setColIndex(Integer colIndex) {
  23.         this.colIndex = colIndex;
  24.     }
  25.     public String getColName() {
  26.         return colName;
  27.     }
  28.     public void setColName(String colName) {
  29.         this.colName = colName;
  30.     }
  31.     public String getSortedType() {
  32.         return sortedType;
  33.     }
  34.     public void setSortedType(String sortedType) {
  35.         this.sortedType = sortedType;
  36.     }
  37. }
FrontGoodsQueryCriteria.java

[java] view plaincopy

  1. package com.campus.front.criteria;
  2. import java.util.Date;
  3. import com.campus.common.SortHelper;
  4. /**
  5.  * @ClassName: FrontGoodsQueryCriteria
  6.  * @Description: TODO(这里用一句话描述这个类的作用)
  7.  * @date 2011-6-3 下午08:56:00
  8.  * @version v1.0
  9.  *
  10.  */
  11. public class FrontGoodsQueryCriteria {
  12.     private SortHelper sortHelper;
  13.     /** 物品id*/
  14.     private String goodsId;
  15.     /** 物品名称 */
  16.     private String goodsName;
  17.     /** 物品状态 */
  18.     private String goodsStatus;
  19.     /** 物品登记日期 */
  20.     private Date goodsRegist;
  21.     /** 物品上架日期 */
  22.     private String goodsShelf;
  23.     /** 物品开始交换日期*/
  24.     private Date goodsStart;
  25.     /** 物品结束交换日期 */
  26.     private Date goodsEnd;
  27.     public FrontGoodsQueryCriteria(SortHelper sortHelper) {
  28.         this.sortHelper = sortHelper;
  29.     }
  30.     public String getGoodsId() {
  31.         return goodsId;
  32.     }
  33.     public void setGoodsId(String goodsId) {
  34.         this.goodsId = goodsId;
  35.     }
  36.     public String getGoodsName() {
  37.         return goodsName;
  38.     }
  39.     public void setGoodsName(String goodsName) {
  40.         this.goodsName = goodsName;
  41.     }
  42.     public String getGoodsStatus() {
  43.         return goodsStatus;
  44.     }
  45.     public void setGoodsStatus(String goodsStatus) {
  46.         this.goodsStatus = goodsStatus;
  47.     }
  48.     public Date getGoodsRegist() {
  49.         return goodsRegist;
  50.     }
  51.     public void setGoodsRegist(Date goodsRegist) {
  52.         this.goodsRegist = goodsRegist;
  53.     }
  54.     public String getGoodsShelf() {
  55.         return goodsShelf;
  56.     }
  57.     public void setGoodsShelf(String goodsShelf) {
  58.         this.goodsShelf = goodsShelf;
  59.     }
  60.     public Date getGoodsStart() {
  61.         return goodsStart;
  62.     }
  63.     public void setGoodsStart(Date goodsStart) {
  64.         this.goodsStart = goodsStart;
  65.     }
  66.     public Date getGoodsEnd() {
  67.         return goodsEnd;
  68.     }
  69.     public void setGoodsEnd(Date goodsEnd) {
  70.         this.goodsEnd = goodsEnd;
  71.     }
  72.     public void setSortHelper(SortHelper sortHelper) {
  73.         this.sortHelper = sortHelper;
  74.     }
  75.     public SortHelper getSortHelper() {
  76.         return sortHelper;
  77.     }
  78. }
提问者采纳
你不是已经做好映射了?直接取出就ok了.

你在product类中声明一个set类型的变量,存储类型为photo类型

在你的xxx.hib.xml中配置出这个<set>映射

然后在你查询product,调用里面的那个set变量,hibernate就会自动关联到photo表..
追问
做好了,也许会有点问题,刚才有报懒加载异常

问题说不清,能帮我看看代码吗


http://blog.csdn.net/neosmemory/archive/2011/06/10/6535968.aspx
回答
你的photo类写getter/setter了吗?
追问
这些getter setter的就不贴了好吧,占篇幅。
回答
你的<set>里的一对多:column列  对应的不是photo表中的goods_id外键吗?
追问
哦,谢谢你用心帮我,那里写错了,可页面上和action里怎么得到photoName
回答
你测试能运行出现结果吗?

你在action中是用lgoods来存储查询出的结果吗?

如果是的话,你在action中对lgoods进行getter/setter

然后在页面使用

<s:iterator value="lgoods">  //在这里调用action中的lgoods 

<s:property value ="goodsname"/>  //这里是goods的goodsname属性

<s:iterator value="photos">   //这里是你goods类中的photos Set.从photos中获取photo对象

     <s:property value="photoName"/> //photo中的photoname属性

</s:iterator>

   //在这里遍历 你的lgoods里面获取的

</s:iterator>

遍历.



-------------

其实你的dao类中的那个查询方法,可以直接使用一个万能查询方法..不用那么麻烦的.
追问
在action里可以拿到photoName了

action里用的是page存储查询结果

jsp页面里用<s:iterator value="page.content"></s:iterator>来显示,物品id的都能拿到

我想应该嵌套查photoName,可是嵌套的这个<s:iterator value=""></s:iterator> value里不知道写什么? 写photos不好使,写page.content.photos也不好使,这东西对photos对象这种set类型不管用吗?
回答
<s:iterator value="page.content">

  //你的content中存放的是goods对象吧

   //你不是可以直接使用<s:property value="goodsid"/>吗,那肯定也可以直接用到goods中photos.

   <s:iterator value="photos">  //那你直接遍历你的photos

         <s:property value="photoname"/> //在这直接显示你的photoname

   </s:iterator>

</s:iterator>
追问
应该是这样吧<s:iterator value="page.content" id="test">然后<s:iterator value="#test.photos">不过不管用

后来再action里加了 private Set<Photo> photos = new HashSet<Photo>(0);和它的getter setter

然后给photos赋page里的值

页面就有photos了,然后用你那个iterator就行了

谢谢你,花这么久的时间帮我解答。
提问者评价
问题终于解决了,感谢update_all的耐心帮忙,女孩子就是热心,太感谢了。

也谢谢其它的朋友,
本文链接地址: hibernate一对多查询问题实例讲解