移动商城第九篇【属性选项卡、最小存储单元、数据进库】
属性选项卡
第三个选项卡涉及到了我们的手机属性,因此,还是需要用到我们其他的数据库表:EB_FEATURE
继续做逆向工程:
查询出普通属性和特殊属性:
<select id="selectCommFeature" resultMap="BaseResultMap">
select * from eb_feature t where t.is_spec = 0
</select>
<select id="selectSpecFeature" resultMap="BaseResultMap">
select * from eb_feature t where t.is_spec = 1
</select>
dao和service和controller
dao实现
/**
* 继承SqlSessionDaoSupport能够得到sessionFactory的引用,非常方便!
*/
@Repository
public class EbFeatureDaoImpl extends SqlSessionDaoSupport implements EbFeatureDao {
String nameSpace = "com.rl.ecps.sqlMap.EbFeatureMapper.";
public List<EbFeature> selectCommFeature() {
return this.getSqlSession().selectList(nameSpace + "selectCommFeature");
}
public List<EbFeature> selectSpecFeature() {
return this.getSqlSession().selectList(nameSpace + "selectSpecFeature");
}
}
service实现
@Service
public class EbFeatureServiceImpl implements EbFeatureService {
@Autowired
private EbFeatureDao featureDao;
public List<EbFeature> selectCommFeature() {
return featureDao.selectCommFeature();
}
public List<EbFeature> selectSpecFeature() {
return featureDao.selectSpecFeature();
}
}
controller调用service拿到对应的普通属性和特殊属性。
/**
* 跳转到添加商品页面
*
* @return
*/
@RequestMapping("/toAddItem.do")
public String toAddItem(Model model) {
List<EbBrand> ebBrands = ebBrandService.selectBrand();
List<EbFeature> commFeature = featureService.selectCommFeature();
List<EbFeature> specFeature = featureService.selectSpecFeature();
model.addAttribute("ebBrands", ebBrands);
model.addAttribute("commFeature", commFeature);
model.addAttribute("specFeature", specFeature);
return "item/addItem";
}
JSP显示普通属性:
- forEach标签默认支持遍历以“,”逗号分割的数据!
<div id="tab_3" class="edit set" style="display: none">
<c:if test="${fn:length(commFeature) == 0}">
<p><label></label>无属性</p>
</c:if>
<%--判断每个属性的录入方式并显示--%>
<c:forEach items="${commFeature}" var="feature">
<p>
<label>${feature.featureName }:</label>
<%--如果输入类型为1,那么就是下拉框方式--%>
<c:if test="${feature.inputType==1}">
<select name="${feature.featureId}">
<%--这里需要设置一个空值,否则后台是可以获取到数据“请选择”--%>
<option value="">请选择</option>
<c:forEach items="${feature.selectValues}" var="value">
<option value="${value}">${value}</option>
</c:forEach>
</select>
</c:if>
<%--如果输入类型为2,那么就是单选框方式--%>
<c:if test="${feature.inputType==2}">
<c:forEach items="${feature.selectValues}" var="value">
<input type="radio" name="${feature.featureId}" value="${value}">${value}
</c:forEach>
</c:if>
<%--如果输入类型为3,那么就是多选框方式--%>
<c:if test="${feature.inputType==3}">
<c:forEach items="${feature.selectValues}" var="value">
<input type="checkbox" name="${feature.featureId}" value="${value}">${value}
</c:forEach>
</c:if>
</p>
</c:forEach>
</div>
属性存放
想要把我们在页面上选定的基本属性进行保存的话,我们是使用另一张表来进行保存的。Featrue表仅仅保存了相对应的属性,是不做保存功能的!
因此,我们需要对EB_PARA_VALUE做逆向工程!
我们参数表的主键是不需要被其他的表用的, 因此我们直接使用序列来管理进行的。并不需要主键返回
<insert id="insert" parameterType="com.rl.ecps.model.EbParaValue" >
insert into EB_PARA_VALUE (PARA_ID, ITEM_ID, FEATURE_ID,
PARA_VALUE)
values (seqparavalueid.nextval, #{itemId,jdbcType=DECIMAL}, #{featureId,jdbcType=DECIMAL},
#{paraValue,jdbcType=VARCHAR})
</insert>
编写参数表的dao
public interface EbParaValueDao {
/**
*由于我们的参数数据是多个的,不想在service做循环而浪费我们的数据库连接
* 因此就使用了List集合作为参数
* @param ebParaValues
* @param itemId
*/
void saveParaValue(List<EbParaValue> ebParaValues, Long itemId);
}
@Repository
public class EbParaValueDaoImpl extends SqlSessionDaoSupport implements EbParaValueDao {
private String nameSpace = "com.rl.ecps.sqlMap.EbParaValueMapper.";
public void saveParaValue(List<EbParaValue> ebParaValues, Long itemId) {
//获取数据库连接,通过一个连接把数据存到数据库里边去
SqlSession sqlSession = this.getSqlSession();
for (EbParaValue ebParaValue : ebParaValues) {
ebParaValue.setItemId(itemId);
sqlSession.insert(nameSpace + "insert", ebParaValue);
}
}
}
controller
回到我们的网页上,我们发现属性是非常多的,那么我们在controller是怎么接收的呢???
我们将JSP页面的name属性都设置为我们的featureId
由于我们该页面上的数据都是从数据库中查询出来的,数据库中的记录有多少,在页面上显示的就有多少
因此,我们可以这么干:
- 我们使用request对象来获取页面上所有的勾选出来的数据属性
- 再次从数据库中查询数据,遍历这些数据,如果发现有勾选出来的数据,那么我们就保存在EbParaValue对象中!
代码:
//查询出所有的属性数据
List<EbFeature> commFeature = featureService.selectCommFeature();
//创建一个集合来装载我们所有的参数数据
List<EbParaValue> ebParaValues = new ArrayList<EbParaValue>();
for (EbFeature feature : commFeature) {
//得到录入方式
Short inputType = feature.getInputType();
//复选,复选的值是有多个的
if (inputType == 3) {
String[] parameterValues = request.getParameterValues(feature.getFeatureId() + "");
//装载参数数据
String value = "";
//如果得到的数据不为null,那么就使用一个字符串来对其进行拼接
if (parameterValues != null && parameterValues.length > 0) {
for (String parameterValue : parameterValues) {
value = value + parameterValue + ",";
}
//去除最后一个逗号
value = value.substring(0, value.length() - 1);
//把数据封装到参数对象上
EbParaValue ebParaValue = new EbParaValue();
ebParaValue.setFeatureId(feature.getFeatureId());
ebParaValue.setParaValue(value);
//装载到集合中
ebParaValues.add(ebParaValue);
}
}else{
//非复选的值都只有一个
String parameter = request.getParameter(feature.getFeatureId() + "");
//如果拿到的数据不为null
if (StringUtils.isNotBlank(parameter)) {
//把数据封装到参数对象上
EbParaValue ebParaValue = new EbParaValue();
ebParaValue.setFeatureId(feature.getFeatureId());
ebParaValue.setParaValue(parameter);
//装载到集合中
ebParaValues.add(ebParaValue);
}
}
}
测试:
最小库存单元选项卡
来到我们的最小库存单元选项卡,我们是需要把我们的特殊属性查询出来的,供用户选择。
查询出特殊属性:
<c:forEach items="${specFeature }" var="spec">
<tr>
<td>${spec.featureName }:</td>
<td>
<c:forEach items="${spec.selectValues}" var="para">
<input type="radio" name="${spec.featureId}" value="${para}">${para}
</c:forEach>
</td>
</tr>
</c:forEach>
当我们想点击增加规格的时候,就应该多那么一个div在页面上显示!那为什么我们需要多个规格呢??如下所示:
对该按钮添加单击事件
//实现页面规格的自动增加和删除
$("#button2").click(function () {
//得到想要控件div所有的内容,不包含自己的标签
var htmlDiv = $("#sp_0").html();
//把自己的标签包含进去
htmlDiv = "<div class='sp_0'>"+htmlDiv+"</div>";
//在下一个div之前插入
$(".page_c").before(htmlDiv);
});
当我们添加了对应的内容时,问题就随之而来了:我们的按钮选项互斥了!
- 当我们点击第一行的颜色时,想要点击第二行的颜色就不行了!【第一行的颜色选择没有了】
- 提交表单中的name属性多个重复了。
原因就是出在:
- name属性是一样的,radio只让选一个!
- 我们是直接把html内容复制过来的。
那么我们使用一个变量值,让每次的name属性都不一样即可!
//得到divNum的值
var divNum = $("#divNum").val();
//实现页面规格的自动增加和删除
$("#button2").click(function () {
divNum++;
//得到想要控件div所有的内容,不包含自己的标签
var htmlDiv = $("#sp_0").html();
//把自己的标签包含进去
htmlDiv = "<div class='sp_0' id='sp_"+divNum+"'>"+htmlDiv+"</div>";
//修改各个name的值,使用正则表达式就可以修改一部份的了
htmlDiv = htmlDiv.replace(/specradio1/g, "specradio"+divNum);
htmlDiv = htmlDiv.replace(/#sp_0/g, "#sp_"+divNum);
//skuType1 showStatus1 sort1 skuPrice1 marketPrice1 stockInventory1 skuUpperLimit1 sku1 location1
htmlDiv = htmlDiv.replace(/skuType1/g, "skuType"+divNum);
htmlDiv = htmlDiv.replace(/showStatus1/g, "showStatus"+divNum);
htmlDiv = htmlDiv.replace(/sort1/g, "sort"+divNum);
htmlDiv = htmlDiv.replace(/skuPrice1/g, "skuPrice"+divNum);
htmlDiv = htmlDiv.replace(/marketPrice1/g, "marketPrice"+divNum);
htmlDiv = htmlDiv.replace(/stockInventory1/g, "stockInventory"+divNum);
htmlDiv = htmlDiv.replace(/skuUpperLimit1/g, "skuUpperLimit"+divNum);
htmlDiv = htmlDiv.replace(/sku1/g, "sku"+divNum);
htmlDiv = htmlDiv.replace(/location1/g, "location"+divNum);
//重新设置div的值
$("#divNum").val(divNum);
//在下一个div之前插入
$(".page_c").before(htmlDiv);
});
还是就是我们不能删除第一个销售单元规格:
function clickRemove(id) {
var a = $(".sp_0").length;
if (a == 1) {
alert("默认规格不可删除");
return;
}
}
最小库存单元属性存放
我们的最小库存单元涉及到了两张数据库表:
首先我们来做逆向工程:
设置SKU有一个集合来保存所有的特殊属性值:
private List<EbSpecValue> specList;
public List<EbSpecValue> getSpecList() {
return specList;
}
public void setSpecList(List<EbSpecValue> specList) {
this.specList = specList;
}
sku的主键需要被SpecValue用到,因此需要返回主键
<selectKey keyProperty="skuId" order="BEFORE" resultType="long">
select seqskuid.nextval from dual
</selectKey>
specValue主键自动增长:
<insert id="insert" parameterType="com.rl.ecps.model.EbSpecValue" >
insert into EB_SPEC_VALUE (SPEC_ID, SKU_ID, FEATURE_ID,
SPEC_VALUE)
values (seqspecvalueid.nextval, #{skuId,jdbcType=DECIMAL}, #{featureId,jdbcType=DECIMAL},
#{specValue,jdbcType=VARCHAR})
</insert>
编写Dao
public interface EbSkuDao {
void saveEbSku(List<EbSku> ebSkus, Long itemId);
}
/**
* 继承SqlSessionDaoSupport能够得到sessionFactory的引用,非常方便!
*/
@Repository
public class EbSkuDaoImpl extends SqlSessionDaoSupport implements EbSkuDao {
String nameSpace = "com.rl.ecps.sqlMap.EbSkuMapper.";
String nameSpace1 = "com.rl.ecps.sqlMap.EbSpecValueMapper.";
public void saveEbSku(List<EbSku> ebSkus, Long itemId) {
SqlSession sqlSession = this.getSqlSession();
for (EbSku ebSku : ebSkus) {
//设置商品属性
ebSku.setItemId(itemId);
sqlSession.insert(nameSpace+"insert", ebSku);
List<EbSpecValue> specList = ebSku.getSpecList();
for (EbSpecValue ebSpecValue : specList) {
ebSpecValue.setSkuId(ebSku.getSkuId());
sqlSession.insert(nameSpace1 + "insert", ebSpecValue);
}
}
}
}
Controller获取页面数据
//使用集合来进行装sku的对象
List<EbSku> skuList = new ArrayList<EbSku>();
//遍历出特殊属性的值
List<EbFeature> specList = featureService.selectSpecFeature();
//获取页面有多少个单元格,对其进行遍历,取出对应的值
for (int i = 1; i <= divNum; i++) {
//获得商城价和库存,他们是必填的字段
String skuPrice = request.getParameter("skuPrice" + i);
String stock = request.getParameter("stockInventory" + i);
//如果上面的必填字段不是空说明数据有效
if (StringUtils.isNotBlank(skuPrice) && StringUtils.isNotBlank(stock)) {
String skuType = request.getParameter("skuType" + i);
String showStatus = request.getParameter("showStatus" + i);
String sort = request.getParameter("sort" + i);
String marketPrice = request.getParameter("marketPrice" + i);
String skuUpperLimit = request.getParameter("skuUpperLimit" + i);
String sku = request.getParameter("sku" + i);
String location = request.getParameter("location" + i);
//创建最小销售单元的对象,并且赋值
EbSku skuObj = new EbSku();
skuObj.setSkuPrice(new BigDecimal(skuPrice));
skuObj.setStockInventory(new Integer(stock));
if (StringUtils.isNotBlank(skuType) && !StringUtils.equals(skuType, "")) {
skuObj.setSkuType(new Short(skuType));
}
if (StringUtils.isNotBlank(showStatus) && !StringUtils.equals(showStatus, "")) {
skuObj.setShowStatus(new Short(showStatus));
}
if (StringUtils.isNotBlank(sort) && !StringUtils.equals(sort, "")) {
skuObj.setSkuSort(new Integer(sort));
}
if (StringUtils.isNotBlank(marketPrice) && !StringUtils.equals(marketPrice, "")) {
skuObj.setMarketPrice(new BigDecimal(marketPrice));
}
if (StringUtils.isNotBlank(skuUpperLimit) && !StringUtils.equals(skuUpperLimit, "")) {
skuObj.setSkuUpperLimit(new Integer(skuUpperLimit));
}
skuObj.setSku(sku);
skuObj.setLocation(location);
//装取特殊属性的集合
List<EbSpecValue> specValList = new ArrayList<EbSpecValue>();
for (EbFeature feature : specList) {
Long featureId = feature.getFeatureId();
//获得所选规格属性的值
String specVal = request.getParameter(featureId + "specradio" + i);
if (StringUtils.isNotBlank(specVal)) {
//创建规格对象
EbSpecValue spec = new EbSpecValue();
spec.setFeatureId(featureId);
spec.setSpecValue(specVal);
specValList.add(spec);
}
}
skuObj.setSpecList(specValList);
skuList.add(skuObj);
}
}
获取得到值:
将Item数据存进数据库
到目前为止,我们4个选项卡的数据都可以拿到了。因此,我们可以把Item所需要的对象存入数据库了..
dao层编写
public void saveItem(EbItem ebItem) {
this.getSqlSession().insert(nameSpace + "insert", ebItem);
}
service层编写:
public void saveItem(EbItem ebItem, EbItemClob clob, List<EbSku> skus, List<EbParaValue> ebParaValues) {
itemDao.saveItem(ebItem);
clobDao.saveItemClob(clob, ebItem.getItemId());
skuDao.saveEbSku(skus, ebItem.getItemId());
paraValueDao.saveParaValue(ebParaValues, ebItem.getItemId());
}
controller编写:
@RequestMapping("/addItem.do")
public void addItem(EbItem ebItem, EbItemClob ebItemClob, HttpServletRequest request, Integer divNum) {
//为商品设置编号
ebItem.setItemNo(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
//查询出所有的属性数据
List<EbFeature> commFeature = featureService.selectCommFeature();
//创建一个集合来装载我们所有的参数数据
List<EbParaValue> ebParaValues = new ArrayList<EbParaValue>();
for (EbFeature feature : commFeature) {
//得到录入方式
Short inputType = feature.getInputType();
//复选,复选的值是有多个的
if (inputType == 3) {
String[] parameterValues = request.getParameterValues(feature.getFeatureId() + "");
//装载参数数据
String value = "";
//如果得到的数据不为null,那么就使用一个字符串来对其进行拼接
if (parameterValues != null && parameterValues.length > 0) {
for (String parameterValue : parameterValues) {
value = value + parameterValue + ",";
}
//去除最后一个逗号
value = value.substring(0, value.length() - 1);
//把数据封装到参数对象上
EbParaValue ebParaValue = new EbParaValue();
ebParaValue.setFeatureId(feature.getFeatureId());
ebParaValue.setParaValue(value);
//装载到集合中
ebParaValues.add(ebParaValue);
}
} else {
//非复选的值都只有一个
String parameter = request.getParameter(feature.getFeatureId() + "");
//如果拿到的数据不为null
if (StringUtils.isNotBlank(parameter)) {
//把数据封装到参数对象上
EbParaValue ebParaValue = new EbParaValue();
ebParaValue.setFeatureId(feature.getFeatureId());
ebParaValue.setParaValue(parameter);
//装载到集合中
ebParaValues.add(ebParaValue);
}
}
}
//使用集合来进行装sku的对象
List<EbSku> skuList = new ArrayList<EbSku>();
//遍历出特殊属性的值
List<EbFeature> specList = featureService.selectSpecFeature();
//获取页面有多少个单元格,对其进行遍历,取出对应的值
for (int i = 1; i <= divNum; i++) {
//获得商城价和库存,他们是必填的字段
String skuPrice = request.getParameter("skuPrice" + i);
String stock = request.getParameter("stockInventory" + i);
//如果上面的必填字段不是空说明数据有效
if (StringUtils.isNotBlank(skuPrice) && StringUtils.isNotBlank(stock)) {
String skuType = request.getParameter("skuType" + i);
String showStatus = request.getParameter("showStatus" + i);
String sort = request.getParameter("sort" + i);
String marketPrice = request.getParameter("marketPrice" + i);
String skuUpperLimit = request.getParameter("skuUpperLimit" + i);
String sku = request.getParameter("sku" + i);
String location = request.getParameter("location" + i);
//创建最小销售单元的对象,并且赋值
EbSku skuObj = new EbSku();
skuObj.setSkuPrice(new BigDecimal(skuPrice));
skuObj.setStockInventory(new Integer(stock));
if (StringUtils.isNotBlank(skuType) && !StringUtils.equals(skuType, "")) {
skuObj.setSkuType(new Short(skuType));
}
if (StringUtils.isNotBlank(showStatus) && !StringUtils.equals(showStatus, "")) {
skuObj.setShowStatus(new Short(showStatus));
}
if (StringUtils.isNotBlank(sort) && !StringUtils.equals(sort, "")) {
skuObj.setSkuSort(new Integer(sort));
}
if (StringUtils.isNotBlank(marketPrice) && !StringUtils.equals(marketPrice, "")) {
skuObj.setMarketPrice(new BigDecimal(marketPrice));
}
if (StringUtils.isNotBlank(skuUpperLimit) && !StringUtils.equals(skuUpperLimit, "")) {
skuObj.setSkuUpperLimit(new Integer(skuUpperLimit));
}
skuObj.setSku(sku);
skuObj.setLocation(location);
//装取特殊属性的集合
List<EbSpecValue> specValList = new ArrayList<EbSpecValue>();
for (EbFeature feature : specList) {
Long featureId = feature.getFeatureId();
//获得所选规格属性的值
String specVal = request.getParameter(featureId + "specradio" + i);
if (StringUtils.isNotBlank(specVal)) {
//创建规格对象
EbSpecValue spec = new EbSpecValue();
spec.setFeatureId(featureId);
spec.setSpecValue(specVal);
specValList.add(spec);
}
}
skuObj.setSpecList(specValList);
skuList.add(skuObj);
}
}
itemService.saveItem(ebItem, ebItemClob, skuList, ebParaValues);
return "redirect:listItem.do";
}
检查数据是否进去了
- 项目的id是自己查询出来的。
SELECT * from EB_ITEM WHERE ITEM_ID = 3073
SELECT * from EB_SKU where ITEM_ID = 3073
SELECT * from EB_PARA_VALUE WHERE ITEM_ID = 3073
SELECT * from EB_SPEC_VALUE WHERE SKU_ID = 3060