先建立一个dept对象,然后建立两个emp对象,然后把这两个emp对象加入到dept对象的集合里面,然后保存dept。级联插入只要操作父表,就可以操作子表。前提是要在前面那个cascade="save-update"必须写。
1、实现的功能如下
当用户登陆成功之后,在首页显示所有的一级分类
显示热门商品
显示最新商品
当用户点击某个一级分类的菜单选项的时候,显示当前一级分类菜单项下所有的二级分类,并且按照分页的形式显示该二级分类下的所有商品
第20课:首先显示一级分类
第21课:热门商品的显示
效果如下所示:
第23课:热门最新的商品
第24课:首先点击商品显示商品的详情
在首页的index.jsp中
<s:iterator var="p" value="nList"> <li> <a href="${ pageContext.request.contextPath }/product_findByPid.action?pid=<s:property value="#p.pid"/>" target="_blank"><img src="${pageContext.request.contextPath}/<s:property value="#p.image"/>" data-original="http://storage.shopxx.net/demo-image/3.0/201301/4a51167a-89d5-4710-aca2-7c76edc355b8-thumbnail.jpg" style="display: block;"></a> </li> </li> </s:iterator>
效果如下:
第24课:首页查询一级分类商品(左侧分类显示
当点击首页的一级分类的某个菜单选项的时候,要在页面左侧显示该一级分类下的所有二级分类,并且在右侧按照分页显示当前二级分类下对应的所有的商品信息
这就涉及到hibernate中的一对多的配置
一个一级分类对应多个二级分类,一个二级分类对应多个商品
具体详情查看博客:https://www.cnblogs.com/liuling/archive/2013/01/14/231df213as32.html
昨天初次接触hibernate,仅仅弄懂了一对一关系的映射。今天学习了一天又有了新的收获,弄懂了一对多之间关系的映射。
一、一对多的关系映射
建立一对多关系关系的表的原则是将一的一方的主键加入到多的一方的表作为外键。这里以员工和部门为例子来演示。以前不用hibernate时建立pojo类要在员工类Emp中加入一个属性,即部门编号deptid.使用hibernate则不同了,需要在“一”的一方类中加入一个set集合,里面存放“多”的一方的对象。而在“多”的一方的类中需要加入一个“一”方的对象。也就是说在Dept类中需要加入一个set集合,存放Emp对象,因为一个部门里面对应多个员工,所以用一个集合来表示。而每一个员工只能属于一个部门,所以员工类Emp里面需要加入一个Depe类对象,表示所属部门。部门类和员工类的代码如下
public class Dept implements Serializable { private int deptId; private String deptName; private Set<Emp> emps = new HashSet<Emp>(); public int getDeptId() { return deptId; } public void setDeptId(int deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } }
public class Emp implements Serializable{ private int empNo; private String empName; private Date empBirthday; private Dept dept; public int getEmpNo() { return empNo; } public void setEmpNo(int empNo) { this.empNo = empNo; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public Date getEmpBirthday() { return empBirthday; } public void setEmpBirthday(Date empBirthday) { this.empBirthday = empBirthday; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } }
写完pojo类后就要配置这两个类和表之间的映射关系了,代码如下:
1.Dept.hbm.xml
<hibernate-mapping> <!-- 表和类之间的映射 --> <class name="com.pojo.Dept" table="dept"> <!-- 主键映射 --> <id name="deptId" column="deptId"> <generator class="native"></generator> </id> <!-- 属性映射 --> <property name="deptName" column="deptName" length="50"></property> <!-- 表之间关系映射 --> <set name="emps" cascade="save-update,delete"> <key column="deptId"></key> <one-to-many class="com.pojo.Emp"/> </set> </class> </hibernate-mapping>
这里面配置了一个set,里面的name="emps"表示在Dept类里的属性emps,它是一个集合,存放Emp对象的。cascade="save-update,delete"指明可以级联删除,级联插入数据。cascade有四个值:all、save-update、delete、none,默认就是none,表示不能级联操作。<one-to-many class="com.pojo.Emp"/>表示Dept与Emp是一对多的关系,他们是以deptId建立关系的,即deptId是Emp的外键。
2.Emp.hbm.xml
<hibernate-mapping> <!-- 表和类之间的映射 --> <class name="com.pojo.Emp" table="emp"> <!-- 主键映射 --> <id name="empNo" column="empNo"> <generator class="native"></generator> </id> <!-- 属性映射 --> <property name="empName" column="empName" length="50"></property> <property name="empBirthday" column="empBirthday"></property> <!-- 表之间关系映射 --> <many-to-one name="dept" column="deptId"></many-to-one> </class> </hibernate-mapping>
这里加了<many-to-one></many-to-one>表示Emp与Dept是多对一的关系,name="dept"表示在Emp类里面有一个属性是Dept对对象dept,column="deptId"表示 它们之间是用deptId建立联系的。
下面是级联插入数据的代码:
package com.test; import java.util.Date; import org.hibernate.Session; import org.hibernate.Transaction; import com.pojo.Dept; import com.pojo.Emp; import com.util.DBUtil; public class 级联插入数据 { /** * @param args */ public static void main(String[] args) { //获得session Session session = DBUtil.getSession(); //新建一个dept Dept dept = new Dept(); dept.setDeptName("吃饭部"); //新建emp Emp e1 = new Emp(); e1.setEmpName("李白"); e1.setEmpBirthday(new Date()); Emp e2 = new Emp(); e2.setEmpName("王维"); e2.setEmpBirthday(new Date()); dept.getEmps().add(e1); dept.getEmps().add(e2); Transaction tr = session.beginTransaction(); try { session.save(dept); tr.commit(); } catch (Exception e) { tr.rollback(); }finally{ session.close(); } } }
先建立一个dept对象,然后建立两个emp对象,然后把这两个emp对象加入到dept对象的集合里面,然后保存dept。级联插入只要操作父表,就可以操作子表。前提是要在前面那个cascade="save-update"必须写。
第25课和第26课 07-SSH网上商城:首页查询一级分类商品(分类显示商品信息二 ,这也是本章的难点和重点,学会了这个基本就没有问题
1、首先我们来分析下,首先一级分类和二级分类是一对多的关系,二级分类和商品是一对多的关系我们要进行配置
安装hibernate一对多的关系进行配置
一级分类的mysql语句如下所示:
CREATE TABLE `category` ( `cid` int(11) NOT NULL, `cname` varchar(255) DEFAULT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二级分类的mysql如下所示
CREATE TABLE `categorysecond` ( `csid` int(11) NOT NULL, `csname` varchar(255) DEFAULT NULL, `cid` int(11) DEFAULT NULL, PRIMARY KEY (`csid`), KEY `ww` (`cid`), KEY `FK936FCAF2E83BE920` (`cid`), CONSTRAINT `FK936FCAF2E83BE920` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`), CONSTRAINT `ww` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
商品的mysql如下所示
CREATE TABLE `product` ( `pid` int(11) NOT NULL, `pname` varchar(255) DEFAULT NULL, `market_price` double DEFAULT NULL, `shop_price` double DEFAULT NULL, `image` varchar(255) DEFAULT NULL, `pdesc` varchar(255) DEFAULT NULL, `is_hot` int(11) DEFAULT NULL, `pdate` datetime DEFAULT NULL, `csid` int(11) DEFAULT NULL, PRIMARY KEY (`pid`), KEY `ee` (`csid`), CONSTRAINT `ee` FOREIGN KEY (`csid`) REFERENCES `categorysecond` (`csid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
对应的实体bean如下
package cn.itcast.shop.category.beans; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import cn.itcast.shop.categorysecond.beans.CategorySecond; /** * 一级分类的实体类对象 * @author 传智.郭嘉 * 昨天初次接触hibernate,仅仅弄懂了一对一关系的映射。今天学习了一天又有了新的收获,弄懂了一对多之间关系的映射。 一、一对多的关系映射 建立一对多关系关系的表的原则是将一的一方的主键加入到多的一方的表作为外键。这里以员工和部门为例子来演示。以前不用hibernate时建立pojo类要在员工类Emp中加入一个属性,即部门编号deptid.使用hibernate则不同了,需要在“一”的一方类中加入一个set集合,里面存放“多”的一方的对象。而在“多”的一方的类中需要加入一个“一”方的对象。也就是说在Dept类中需要加入一个set集合,存放Emp对象,因为一个部门里面对应多个员工, 所以用一个集合来表示。而每一个员工只能属于一个部门, 所以员工类Emp里面需要加入一个Depe类对象,表示所属部门。 部门类和员工类的代码如下 * */ public class Category implements Serializable{ private Integer cid; private String cname; //现在当点击一级分类的时候,需要将二级分类全部查询出来,所以要在一级分类里面配置一个二级分类的集合 // 一级分类中存放二级分类的集合: private Set<CategorySecond> categorySeconds = new HashSet<CategorySecond>(); public Set<CategorySecond> getCategorySeconds() { return categorySeconds; } public void setCategorySeconds(Set<CategorySecond> categorySeconds) { this.categorySeconds = categorySeconds; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
对应的Category.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.itcast.shop.category.beans.Category" table="category"> <id name="cid"> <generator class="native"/> </id> <property name="cname"/> <!-- 配置二级分类的集合 II.一对多关联级别: <set>元素中的lazy属性的可选值为:true(延迟加载),extra(增强延迟加载)和false(立即加载);--> <set order-by="csid" name="categorySeconds" lazy="false" cascade="delete"> <key column="cid"/> <one-to-many class="cn.itcast.shop.categorysecond.beans.CategorySecond"/> </set> </class> </hibernate-mapping> <!-- 记得在hibernate的配置文件中引入该资源文件 -->
package cn.itcast.shop.categorysecond.beans; import java.util.HashSet; import java.util.Set; import cn.itcast.shop.category.beans.Category; import cn.itcast.shop.product.beans.Product; /** * 二级分类的实体 * @author 传智.郭嘉 * CREATE TABLE `categorysecond` ( `csid` int(11) NOT NULL, `csname` varchar(255) DEFAULT NULL, `cid` int(11) DEFAULT NULL, PRIMARY KEY (`csid`), KEY `ww` (`cid`), CONSTRAINT `ww` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; * */ public class CategorySecond { private Integer csid; private String csname; // 所属一级分类.存的是一级分类的对象. 外键cid对应的是类 private Category category; // 配置商品集合 private Set<Product> products = new HashSet<Product>(); public Set<Product> getProducts() { return products; } public void setProducts(Set<Product> products) { this.products = products; } public Integer getCsid() { return csid; } public void setCsid(Integer csid) { this.csid = csid; } public String getCsname() { return csname; } public void setCsname(String csname) { this.csname = csname; } public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } }
对应的CategorySecond.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.itcast.shop.categorysecond.beans.CategorySecond" table="categorysecond"> <id name="csid"> <generator class="native"/> </id> <property name="csname"/> <!-- 二级分类与一级分类的guanlian --> <many-to-one name="category" lazy="false" class="cn.itcast.shop.category.beans.Category" column="cid"></many-to-one> <!-- 二级分类与商品的关联 --> <set name="products"> <key column="csid"/> <one-to-many class="cn.itcast.shop.product.beans.Product"/> </set> </class> </hibernate-mapping>
package cn.itcast.shop.product.beans; import java.util.Date; import cn.itcast.shop.categorysecond.beans.CategorySecond; /** * 商品的实体对象 * @author 传智.郭嘉 * */ public class Product { private Integer pid; private String pname; private Double market_price; private Double shop_price; private String image; private String pdesc; private Integer is_hot; private Date pdate; // 二级分类的外键:使用二级分类的对象. private CategorySecond categorySecond; //设置 public CategorySecond getCategorySecond() { return categorySecond; } public void setCategorySecond(CategorySecond categorySecond) { this.categorySecond = categorySecond; } public Integer getPid() { return pid; } public void setPid(Integer pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public Double getMarket_price() { return market_price; } public void setMarket_price(Double market_price) { this.market_price = market_price; } public Double getShop_price() { return shop_price; } public void setShop_price(Double shop_price) { this.shop_price = shop_price; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getPdesc() { return pdesc; } public void setPdesc(String pdesc) { this.pdesc = pdesc; } public Integer getIs_hot() { return is_hot; } public void setIs_hot(Integer is_hot) { this.is_hot = is_hot; } public Date getPdate() { return pdate; } public void setPdate(Date pdate) { this.pdate = pdate; } }
Product.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.itcast.shop.product.beans.Product" table="product"> <id name="pid"> <generator class="native"/> </id> <property name="pname"/> <property name="market_price"/> <property name="shop_price"/> <property name="image"/> <property name="pdesc"/> <property name="is_hot"/> <property name="pdate"/> <many-to-one name="categorySecond" lazy="false" class="cn.itcast.shop.categorysecond.beans.CategorySecond" column="csid"/> </class> </hibernate-mapping>
注意上面的所有的配置中lazy都设置成false,禁止hibernate的延迟加载,当查询一级分类对象的时候,就将其关联的二级对象,以及二级对象下面的所有商品显示出来
上面把一级分类,二级分类 以及商品之间的关系配置成功之后,我们就可以实现下面的功能了
当用户登录成功之后,就在首页上显示出了所有的一级分类,当点击某个一级分类的菜单项的时候,在弹出的页面的左侧要显示出该对应的一级分类下所有的二级分类,并且在右侧显示出该一级分类下有多少商品,并且按照分页查询进行显示如何实现了
首先在左侧显示所有的二级分类
当用户登录成功之后,在首页就会显示所有的一级分类的名字
在menu.jsp中可以看到
<div class="span24"> <ul class="mainNav"> <li><a href="${ pageContext.request.contextPath }/index.action">首页</a> |</li> <s:iterator var="c" value="#session.cList"> <li><a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="#c.cid"/>&page=1"><s:property value="#c.cname"/></a> |</li> </s:iterator> </ul> </div>
其中:session.cList就是在indexAction中查询出来的一级分类的值,存储在session中,这里就是对一级分类进行遍历,<s:property value="#c.cname"/>就是对应的显示的一级分类的名称
当用户点击一级分类的某个菜单选项的时候跳转到${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="#c.cid"/>&page=1",跳转到product_findByCid.action这个action进行处理,并且携带当前的一级分类的cid的值,以及默认显示
当前一级分类下对应的商品,分页显示默认值为page=1传递过去
在实现分页查询之前,我们首先要定义两个实体类,该实体类能够帮助我们实现分页查询
PageBean
package cn.itcast.shop.user.utils; import java.util.List; /** * 分页类的封装 * @author 传智.郭嘉 * */ public class PageBean<T> { private int page; // 当前页数 private int totalCount; // 总记录数 private int totalPage; // 总页数 private int limit; // 每页显示的记录数 private List<T> list; // 每页显示数据的集合. public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } }
PageHibernateCallback
package cn.itcast.shop.user.utils; import java.sql.SQLException; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; public class PageHibernateCallback<T> implements HibernateCallback{ //分页查询的hql语句 private String hql; //对应的hql语句的执行参数 private Object[] params; //查询的begin的位置,例如每页显示8条数据,要显示第5的数据,这里startInde等于5*8等于40 private int startIndex; //当前页显示的条数,例如每页显示8条数据,这里就是8 private int pageSize; public PageHibernateCallback(String hql, Object[] params, int startIndex, int pageSize) { super(); this.hql = hql; this.params = params; this.startIndex = startIndex; this.pageSize = pageSize; } public List<T> doInHibernate(Session session) throws HibernateException, SQLException { //1 执行hql语句 Query query = session.createQuery(hql); //2 实际参数 if(params != null){ for(int i = 0 ; i < params.length ; i ++){ query.setParameter(i, params[i]); } } //3 分页 query.setFirstResult(startIndex); query.setMaxResults(pageSize); return query.list(); } }
该类是hibernate中进行分页查询的一个关键的实现类
有了这两个类我们来看看进行查询的action
package cn.itcast.shop.product.action; import java.util.List; import cn.itcast.shop.category.beans.Category; import cn.itcast.shop.category.service.CategoryService; import cn.itcast.shop.product.beans.Product; import cn.itcast.shop.product.service.ProductService; import cn.itcast.shop.user.utils.PageBean; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class ProductAction extends ActionSupport implements ModelDriven<Product>{ private ProductService productService; private CategoryService categoryService; // 注入商品的Service public ProductService getProductService() { return productService; } public CategoryService getCategoryService() { return categoryService; } public void setCategoryService(CategoryService categoryService) { this.categoryService = categoryService; } public void setProductService(ProductService productService) { this.productService = productService; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } private Product product = new Product(); // 接收一级分类cid private Integer cid; // 接收当前页数: private int page; // 接收二级分类id private Integer csid; public Integer getCsid() { return csid; } public void setCsid(Integer csid) { this.csid = csid; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } @Override public Product getModel() { // TODO Auto-generated method stub return product; } // 根据商品的ID进行查询商品:执行方法: public String findByPid() throws Exception{ // 调用Service的方法完成查询. product = productService.findByPid(product.getPid()); return "findByPid"; } // 根据一级分类的id查询商品: public String findByCid() { //查询出所有的一级分类 List<Category> cList = categoryService.findAll(); // 将cList存入到值栈中: ActionContext.getContext().getValueStack().set("cList", cList); // 根据二级分类查询商品,其中csid就是页面上传递过来的一级分类的cid,page就是页面上传递过来的第几页 PageBean<Product> pageBean = productService.findByPageCid(cid, page);// 根据一级分类查询商品,带分页查询 // 将PageBean存入到值栈中: ActionContext.getContext().getValueStack().set("pageBean", pageBean); return "findByCid"; } }
首先在首页点击一级菜单的选项的时候调用的是${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="#c.cid"/>&page=1"> ,调用的是findByCid这个方法,传递过来的参数是cid和page
所以:首先第一步在改action中需要定义两个成员变量
/ 接收一级分类cid
private Integer cid;
// 接收当前页数:
private int page;
来接受传递过来的参数提供对应的get和set方法
我们接下来看调用的是findByCid这个方法,在改方法中首先需要查询出所有的一级分类:调用 List<Category> cList = categoryService.findAll();这个方法,所以需要引入private CategoryService categoryService;
并且在applicationContext-action.xml中需要进行配置
<bean id="productAction" class = "cn.itcast.shop.product.action.ProductAction" scope="prototype"> <property name="productService" ref="productService"></property> <property name="categoryService" ref="categoryService"></property> </bean>
接下来把查询出来的一级分类存储在值栈中
接下来 PageBean<Product> pageBean = productService.findByPageCid(cid, page);// 根据一级分类查询商品,带分页查询
然后把查询出来的数据存储在值栈中
我们来看看具体的业务实现类是如何实现的
package cn.itcast.shop.product.service; import java.util.List; import cn.itcast.shop.product.beans.Product; import cn.itcast.shop.product.dao.ProductDao; import cn.itcast.shop.user.utils.PageBean; public class ProductService { private ProductDao productDao; public ProductDao getProductDao() { return productDao; } public void setProductDao(ProductDao productDao) { this.productDao = productDao; } public List<Product> findHot() { // TODO Auto-generated method stub return productDao.findHot(); } public List<Product> findNew(){ return productDao.findNew(); } public Product findByPid(Integer pid) { return productDao.findByPid(pid); } public PageBean<Product> findByPageCid(Integer cid, int page) { PageBean<Product> pageBean = new PageBean<Product>(); // 设置当前页数: pageBean.setPage(page); // 设置每页显示记录数: int limit = 8; pageBean.setLimit(limit); // 设置总记录数: int totalCount = 0; totalCount = productDao.findCountCid(cid); pageBean.setTotalCount(totalCount); // 设置总页数: int totalPage = 0; // Math.ceil(totalCount / limit); if (totalCount % limit == 0) { totalPage = totalCount / limit; } else { totalPage = totalCount / limit + 1; } pageBean.setTotalPage(totalPage); // 每页显示的数据集合: // 从哪开始: int begin = (page - 1) * limit; List<Product> list = productDao.findByPageCid(cid, begin, limit); pageBean.setList(list); return pageBean; } }
我们来看看具体的dao类
package cn.itcast.shop.product.dao; import java.util.List; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import cn.itcast.shop.product.beans.Product; import cn.itcast.shop.user.utils.PageHibernateCallback; import java.sql.SQLException; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class ProductDao extends HibernateDaoSupport { // 首页上热门商品查询 public List<Product> findHot() { // 使用离线条件查询. DetachedCriteria criteria = DetachedCriteria.forClass(Product.class); // 查询热门的商品,条件就是is_host = 1 criteria.add(Restrictions.eq("is_hot", 1)); // 倒序排序输出: criteria.addOrder(Order.desc("pdate")); // 执行查询: List<Product> list = this.getHibernateTemplate().findByCriteria( criteria, 0, 10); return list; } // 首页上最新商品的查询 public List<Product> findNew() { // 使用离线条件查询: DetachedCriteria criteria = DetachedCriteria.forClass(Product.class); // 按日期进行倒序排序: criteria.addOrder(Order.desc("pdate")); // 执行查询: List<Product> list = this.getHibernateTemplate().findByCriteria(criteria, 0, 10); return list; } // 根据商品ID查询商品 public Product findByPid(Integer pid) { return (Product) this.getHibernateTemplate().get(Product.class, pid); } // 根据一级分类cid查询商品的个数 public int findCountCid(Integer cid) { String hql = "select count(*) from Product p where p.categorySecond.category.cid = ?"; List<Long> list = this.getHibernateTemplate().find(hql,cid); if(list != null && list.size() > 0){ return list.get(0).intValue(); } return 0; } // 根据一级分类cid查询对应商品的集合,分页查询 public List<Product> findByPageCid(Integer cid, int begin, int limit) { // select p.* from category c,categorysecond cs,product p where c.cid = cs.cid and cs.csid = p.csid and c.cid = 2 // select p from Category c,CategorySecond cs,Product p where c.cid = cs.category.cid and cs.csid = p.categorySecond.csid and c.cid = ? String hql = "select p from Product p join p.categorySecond cs join cs.category c where c.cid = ?"; // 分页另一种写法: List<Product> list = (List<Product>) this.getHibernateTemplate().execute(new PageHibernateCallback<Product>(hql, new Object[]{cid}, begin, limit)); if(list != null && list.size() > 0){ return list; } return null; } }
对于dao这里要进行说明下:
要查询一级分类下所有的商品,因为涉及到三个表查询,一级分类表,一级分类下的二级分类类,二级分类下的商品表
使用的sql语句如下:
select p.* from category c,categorysecond cs,product p where c.cid = cs.cid and cs.csid = p.csid and c.cid = 2但是在hibernate中使用的hql语句转化成hql语句如下所示
select p from Category c,CategorySecond cs,Product p where c.cid = cs.category.cid and cs.csid = p.categorySecond.csid and c.cid = ?但是上面的hql语句比较复杂,hibernate提共了下面更加方便的语句如下所示
String hql = "select p from Product p join p.categorySecond cs join cs.category c where c.cid = ?";这个:
List<Product> list = (List<Product>) this.getHibernateTemplate().execute(new PageHibernateCallback<Product>(hql, new Object[]{cid}, begin, limit));这里主要是为了分页查询当查询到数据之后
<!-- 商品模块的Action --> <action name="product_*" class="productAction" method="{1}"> <result name="findByPid">/WEB-INF/jsp/product.jsp</result> <result name="findByCid">/WEB-INF/jsp/productList.jsp</result> </action>
这里跳转到了productList.jsp页面对查询出来的数据进行显示
<div class="hotProductCategory"> <s:iterator var="c" value="#session.cList"> <dl> <dt> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="#c.cid"/>&page=1"><s:property value="#c.cname"/></a> </dt> <s:iterator var="cs" value="#c.categorySeconds"> <dd> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="#cs.csid"/>&page=1"><s:property value="#cs.csname"/></a> </dd> </s:iterator> </dl> </s:iterator> </div>
上面就分别显示每个一级分类,以及该一级分类下有哪些二级分类
<div id="result" class="result table clearfix"> <ul> <s:iterator var="p" value="pageBean.list"> <li> <a href="${ pageContext.request.contextPath }/product_findByPid.action?pid=<s:property value="#p.pid"/>"> <img src="${pageContext.request.contextPath}/<s:property value="#p.image"/>" width="170" height="170" style="display: inline-block;"> <span style='color:green'> <s:property value="#p.pname"/> </span> <span class="price"> 商城价: ¥<s:property value="#p.shop_price"/> </span> </a> </li> </s:iterator> </ul>
这里就是显示一级分类下有哪些商品
上面的 1 2 3 4 5 6 数字按钮在下面显示
<div class="pagination"> <span>第 <s:property value="pageBean.page"/>/<s:property value="pageBean.totalPage"/> 页</span> <s:if test="cid != null"> <s:if test="pageBean.page != 1"> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=1" class="firstPage"> </a> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.page-1"/>" class="previousPage"> </a> </s:if> <s:iterator var="i" begin="1" end="pageBean.totalPage"> <s:if test="pageBean.page != #i"> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="#i"/>"><s:property value="#i"/></a> </s:if> <s:else> <span class="currentPage"><s:property value="#i"/></span> </s:else> </s:iterator> <s:if test="pageBean.page != pageBean.totalPage"> <a class="nextPage" href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.page+1"/>"> </a> <a class="lastPage" href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.totalPage"/>"> </a> </s:if> </s:if> <s:if test="csid != null"> <s:if test="pageBean.page != 1"> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=1" class="firstPage"> </a> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.page-1"/>" class="previousPage"> </a> </s:if> <s:iterator var="i" begin="1" end="pageBean.totalPage"> <s:if test="pageBean.page != #i"> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="#i"/>"><s:property value="#i"/></a> </s:if> <s:else> <span class="currentPage"><s:property value="#i"/></span> </s:else> </s:iterator> <s:if test="pageBean.page != pageBean.totalPage"> <a class="nextPage" href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.page+1"/>"> </a> <a class="lastPage" href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.totalPage"/>"> </a> </s:if> </s:if>
整个productList.jsp的代码如下所示:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- saved from url=(0048)http://localhost:8080/mango/product/list/1.jhtml --> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>传智网上商城</title> <link href="${pageContext.request.contextPath}/css/common.css" rel="stylesheet" type="text/css"/> <link href="${pageContext.request.contextPath}/css/product.css" rel="stylesheet" type="text/css"/> </head> <body> <div class="container header"> <div class="span5"> <div class="logo"> <a href="http://localhost:8080/mango/"> <img src="${pageContext.request.contextPath}/image/r___________renleipic_01/logo.gif" alt="传智播客"> </a> </div> </div> <div class="span9"> <div class="headerAd"> <img src="${pageContext.request.contextPath}/image/header.jpg" width="320" height="50" alt="正品保障" title="正品保障"> </div> </div> <%@ include file="menu.jsp" %> </div> <div class="container productList"> <div class="span6"> <div class="hotProductCategory"> <s:iterator var="c" value="#session.cList"> <dl> <dt> <a href="${pageContext.request.contextPath}/product_findByCid.action?cid=<s:property value="#c.cid"/>&page=1"><s:property value="#c.cname"/></a> </dt> <s:iterator var="cs" value="#c.categorySeconds"> <dd> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="#cs.csid"/>&page=1"><s:property value="#cs.csname"/></a> </dd> </s:iterator> </dl> </s:iterator> </div> </div> <div class="span18 last"> <form id="productForm" action="${pageContext.request.contextPath}/image/蔬菜 - Powered By Mango Team.htm" method="get"> <div id="result" class="result table clearfix"> <ul> <s:iterator var="p" value="pageBean.list"> <li> <a href="${ pageContext.request.contextPath }/product_findByPid.action?pid=<s:property value="#p.pid"/>"> <img src="${pageContext.request.contextPath}/<s:property value="#p.image"/>" width="170" height="170" style="display: inline-block;"> <span style='color:green'> <s:property value="#p.pname"/> </span> <span class="price"> 商城价: ¥<s:property value="#p.shop_price"/> </span> </a> </li> </s:iterator> </ul> </div> <div class="pagination"> <span>第 <s:property value="pageBean.page"/>/<s:property value="pageBean.totalPage"/> 页</span> <s:if test="cid != null"> <s:if test="pageBean.page != 1"> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=1" class="firstPage"> </a> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.page-1"/>" class="previousPage"> </a> </s:if> <s:iterator var="i" begin="1" end="pageBean.totalPage"> <s:if test="pageBean.page != #i"> <a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="#i"/>"><s:property value="#i"/></a> </s:if> <s:else> <span class="currentPage"><s:property value="#i"/></span> </s:else> </s:iterator> <s:if test="pageBean.page != pageBean.totalPage"> <a class="nextPage" href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.page+1"/>"> </a> <a class="lastPage" href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.totalPage"/>"> </a> </s:if> </s:if> <s:if test="csid != null"> <s:if test="pageBean.page != 1"> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=1" class="firstPage"> </a> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.page-1"/>" class="previousPage"> </a> </s:if> <s:iterator var="i" begin="1" end="pageBean.totalPage"> <s:if test="pageBean.page != #i"> <a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="#i"/>"><s:property value="#i"/></a> </s:if> <s:else> <span class="currentPage"><s:property value="#i"/></span> </s:else> </s:iterator> <s:if test="pageBean.page != pageBean.totalPage"> <a class="nextPage" href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.page+1"/>"> </a> <a class="lastPage" href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.totalPage"/>"> </a> </s:if> </s:if> </div> </form> </div> </div> <div class="container footer"> <div class="span24"> <div class="footerAd"> <img src="${pageContext.request.contextPath}/image/footer.jpg" width="950" height="52" alt="我们的优势" title="我们的优势"> </div> </div> <div class="span24"> <ul class="bottomNav"> <li> <a >关于我们</a> | </li> <li> <a>联系我们</a> | </li> <li> <a >诚聘英才</a> | </li> <li> <a >法律声明</a> | </li> <li> <a>友情链接</a> | </li> <li> <a target="_blank">支付方式</a> | </li> <li> <a target="_blank">配送方式</a> | </li> <li> <a >官网</a> | </li> <li> <a >论坛</a> </li> </ul> </div> <div class="span24"> <div class="copyright">Copyright©2005-2015 网上商城 版权所有</div> </div> </div> </body></html>
相当的经典
先建立一个dept对象,然后建立两个emp对象,然后把这两个emp对象加入到dept对象的集合里面,然后保存dept。级联插入只要操作父表,就可以操作子表。前提是要在前面那个cascade="save-update"必须写。
来源:https://www.cnblogs.com/kebibuluan/p/8330228.html