淘淘商城_day02_课堂笔记
今日大纲
- 学习Nginx的使用
- 实现商品的管理
- 新增商品
- 查询商品列表
- 编辑商品
- 删除商品
- 上架和下架商品
学习nginx
开发阶段中的环境
开发环境:自己的电脑
测试环境:提供给测试人员使用的环境
生产环境:项目最终发布上线的环境
预发布环境:数据是和生成环境的数据一致,运行最新的项目代码进去测试
每个环境的访问地址是不同的,可能因为访问地址不同导致一些问题的产生,所以,为了避免该类问题的产生,可以使不同的环境访问地址完全一致,通过域名访问即可实现。
需求:需要通过域名访问后台系统?
现在:http://127.0.0.1/rest/page/index
需要通过manage.taoao.com访问。
http://manage.taotao.com /rest/page/index
Hosts
用户访问淘宝:
用户 è www.taobao.com è 本机的hosts文件中查找域名映射,如果查找到就返回 è浏览器通过域名到DNS查找服务器ip地址 è 执行访问
Linux下的hosts文件所在路径: /etc/hosts
实现
- 修改本地的hosts,将manage.taotao.com映射到127.0.0.1
效果:
但是,如果后台系统占用80端口,其他系统就无法占用80,也就是无法通过域名直接访问,必须通过域名:端口访问http://www.taotao.com:8081/,
问题是:导致,生产环境和开发环境的访问路径是不同的。
如何解决以上问题? -- 通过nginx来解决。
修改后台管理系统的端口为8081
Nginx简介
目前电商和互联网系统都会采用nginx + 应用服务器(tomcat).
Web服务器分2类:
- web服务器
- Apache 服务器
- Nginx
- IIS
- web应用服务器
- tomcat
- resin
- jetty
区分:web服务器不能解析jsp等页面,只能处理js、css、html等静态资源。
并发:web服务器的并发能力远高于web应用服务器。
淘宝:
京东:(也是nginx,将服务名称改为JDWS)
简介
Nginx是使用C语言开发。
使用
解压得到:
三个命令:(在 CMD 中执行)
启动:start nginx.exe
停止:nginx.exe -s stop
重新加载:nginx.exe -s reload
只有2个进程nginx才算是真正的启动成功:
Nginx的配置
测试
现在的请求:
用户 è Nginx è tomcat
启动nginx的注意事项
- 其他服务占用80端口,会导致nginx启动失败,检查的方法是 cmd è nginx.exe
- Nginx的路径不能包含中文
代理
正向代理
用户 è 代理 è google
反向代理
用户 è nginx è tomcat
解释:
Tomcat根本不知道请求的来源,只知道所有的请求都是来源于Nginx,不知道真正的来源。
封装BaseService
方法:
- queryById
- queryAll
- queryOne
- queryListByWhere
- queryPageListByWhere
- save
- update
- deleteById
- deleteByIds
- deleteByWhere
实现
package com.taotao.manage.service;
import java.util.Date;
import java.util.List;
import com.github.abel533.entity.Example;
import com.github.abel533.mapper.Mapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.manage.pojo.BasePojo;
public abstract class BaseService<T extends BasePojo> {
public abstract Mapper<T> getMapper();
/**
* 根据id查询数据
*
* @param id
* @return
*/
public T queryById(Long id) {
return getMapper().selectByPrimaryKey(id);
}
/**
* 查询所有数据
*
* @return
*/
public List<T> queryAll() {
return this.getMapper().select(null);
}
/**
* 根据条件查询一条数据
*
* @param record
* @return
*/
public T queryOne(T record) {
return this.getMapper().selectOne(record);
}
/**
* 根据条件查询数据列表
*
* @param record
* @return
*/
public List<T> queryListByWhere(T record) {
return this.getMapper().select(record);
}
/**
* 根据条件分页查询数据列表
*
* @param record
* @param page
* @param rows
* @return
*/
public PageInfo<T> queryPageListByWhere(T record, Integer page, Integer rows) {
// 设置分页条件
PageHelper.startPage(page, rows);
List<T> list = this.getMapper().select(record);
// 获取分页数据
return new PageInfo<T>(list);
}
/**
* 保存数据
*
* @param record
* @return
*/
public Integer save(T record) {
record.setCreated(new Date());
record.setUpdated(record.getCreated());
return this.getMapper().insert(record);
}
/**
* 有选择性的保存数据(选择不为null的字段做保存)
*
* @param record
* @return
*/
public Integer saveSelective(T record) {
record.setCreated(new Date());
record.setUpdated(record.getCreated());
return this.getMapper().insertSelective(record);
}
/**
* 更新数据
*
* @param record
* @return
*/
public Integer update(T record) {
record.setUpdated(new Date());
return this.getMapper().updateByPrimaryKey(record);
}
/**
* 有选择性的更新数据(选择不为null的字段做更新)
*
* @param record
* @return
*/
public Integer updateSelective(T record) {
record.setCreated(null);
record.setUpdated(new Date());
return this.getMapper().updateByPrimaryKeySelective(record);
}
public Integer deleteById(Long id) {
return this.getMapper().deleteByPrimaryKey(id);
}
/**
* 根据ids批量删除数据
*
* @param ids
* @param clazz
* @param property
* @return
*/
public Integer deleteByIds(List<Object> ids, Class<T> clazz, String property) {
Example example = new Example(clazz);
example.createCriteria().andIn(property, ids);
return this.getMapper().deleteByExample(example);
}
/**
* 根据条件删除数据
*
* @param record
* @return
*/
public Integer deleteByWhere(T record){
return this.getMapper().delete(record);
}
}
使用BaseService改造ItemCatService
在Controller:
测试
测试结果:和原来的实现完全一致。
Spring4的泛型注入
BaseService的优化
测试:运行时注入具体的通用Mapper的子接口的实现类:
问题
ItemCatMapper在编码时没有使用到,是否将其删除? -- 不能。
原因:在Spring运行时会使用该对象,将其注入到BaseService中。
新增商品
商品数据结构
需求文档:
表结构:
问题1:为什么价格要以最小单位分存储? -- 为了避免小数计算带来的问题。
商品描述表:
问题2:为什么要将商品描述和商品的基本数据分离?
- 商品描述的数据量大,会导致数据文件变大,影响查询速度。
- 后期会对商品描述数据的存储做改造,所以需要将描述数据分离
点击商品类目的叶子节点的事件
在item-add.jsp中定义:
新增页面中价格
KindEditor的使用
效果:
- 导入js文件
- 定义多行文本
- 通过JS创建出富文本编辑器
Common.js:
提交事件
function submitForm(){
if(!$('#itemAddForm').form('validate')){
$.messager.alert('提示','表单还未填写完成!');
return ;
}
//处理商品的价格的单位,将元转化为分
$("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100);
//将编辑器中的内容同步到隐藏多行文本中
itemAddEditor.sync();
//输入的规格参数数据保存为json
var paramJson = [];
$("#itemAddForm .params li").each(function(i,e){
var trs = $(e).find("tr");
var group = trs.eq(0).text();
var ps = [];
for(var i = 1;i<trs.length;i++){
var tr = trs.eq(i);
ps.push({
"k" : $.trim(tr.find("td").eq(0).find("span").text()),
"v" : $.trim(tr.find("input").val())
});
}
paramJson.push({
"group" : group,
"params": ps
});
});
paramJson = JSON.stringify(paramJson);
$("#itemAddForm [name=itemParams]").val(paramJson);
/*
$.post("/rest/item/save",$("#itemAddForm").serialize(), function(data){
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}
});
*/
//提交到后台的RESTful
$.ajax({
type: "POST",
url: "/rest/item",
data: $("#itemAddForm").serialize(), //表单序列化,将所有的输入内容转化成K/V数据格式
statusCode : {
201 : function(){
$.messager.alert('提示','新增商品成功!');
},
400 : function(){
$.messager.alert('提示','提交的参数不合法!');
},
500 : function(){
$.messager.alert('提示','新增商品失败!');
}
}
});
}
商品描述表中业务id
实现
Controller
效果
数据:
描述数据:
事务问题
解决:
将2次保存放到同一个Service的同一个方法中即可:
Controller:
日志:
2016-12-02 15:26:39,723 [http-bio-8081-exec-1] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'taotao-manage' processing POST request for [/rest/item]
2016-12-02 15:26:39,725 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /item
2016-12-02 15:26:39,727 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public org.springframework.http.ResponseEntity<java.lang.Void> com.taotao.manage.controller.ItemController.saveItem(com.taotao.manage.pojo.Item,java.lang.String)]
2016-12-02 15:26:39,727 [http-bio-8081-exec-1] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'itemController'
2016-12-02 15:26:39,797 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Creating new transaction with name [com.taotao.manage.service.ItemService.saveItem]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2016-12-02 15:26:39,819 [http-bio-8081-exec-1] [com.jolbox.bonecp.BoneCPDataSource]-[DEBUG] JDBC URL = jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, Username = root, partitions = 1, max (per partition) = 100, min (per partition) = 5, idle max age = 30 min, idle test period = 60 min, strategy = DEFAULT
2016-12-02 15:26:40,113 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Acquired Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] for JDBC transaction
2016-12-02 15:26:40,117 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Switching JDBC Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] to manual commit
2016-12-02 15:26:40,154 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
2016-12-02 15:26:40,175 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]
2016-12-02 15:26:40,281 [http-bio-8081-exec-1] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] will be managed by Spring
2016-12-02 15:26:40,292 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_item (PRICE,UPDATED,STATUS,CREATED,SELL_POINT,ID,CID,IMAGE,TITLE,BARCODE,NUM) VALUES ( ?,?,?,?,?,?,?,?,?,?,? )
2016-12-02 15:26:40,325 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Parameters: 519900(Long), 2016-12-02 15:26:40.148(Timestamp), 1(Integer), 2016-12-02 15:26:40.148(Timestamp), 推荐选择下方的移动、联通、电信优惠购,套餐有优惠,还有话费返还。(String), null, 560(Long), (String), Apple iPhone 7 (A1660) 32G 银色移动联通电信4G手机(String), (String), 999999(Integer)
2016-12-02 15:26:40,326 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] <== Updates: 1
2016-12-02 15:26:40,332 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] ==> Executing: SELECT LAST_INSERT_ID()
2016-12-02 15:26:40,357 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] <== Total: 1
2016-12-02 15:26:40,358 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]
2016-12-02 15:26:40,358 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Participating in existing transaction
2016-12-02 15:26:40,388 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180] from current transaction
2016-12-02 15:26:40,397 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_item_desc (ITEM_DESC,UPDATED,CREATED,ITEM_ID) VALUES ( ?,?,?,? )
2016-12-02 15:26:40,398 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Parameters: <div id="activity_header" style="margin:0px;padding:0px;color:#666666;font-family:Arial, Verdana, 宋体;background-color:#FFFFFF;">
<div style="margin:0px;padding:0px;text-align:center;">
……
<br />
</div>
<div id="activity_footer" style="margin:0px;padding:0px;color:#666666;font-family:Arial, Verdana, 宋体;background-color:#FFFFFF;">
<div style="margin:0px;padding:0px;text-align:center;">
<img alt="" class="" src="https://img30.360buyimg.com/jgsq-productsoa/jfs/t3577/344/1077770157/80811/316f9e36/581c7263N82a0e9fc.jpg" />
</div>
</div>(String), 2016-12-02 15:26:40.388(Timestamp), 2016-12-02 15:26:40.388(Timestamp), 41(Long)
2016-12-02 15:26:40,399 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] <== Updates: 1
2016-12-02 15:26:40,400 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]
2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]
2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]
2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]
2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Initiating transaction commit
2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Committing JDBC transaction on Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}]
2016-12-02 15:26:40,403 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Releasing JDBC Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] after transaction
2016-12-02 15:26:40,404 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource
2016-12-02 15:26:40,422 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain]-[DEBUG] Invoking ResponseBodyAdvice chain for body=null
2016-12-02 15:26:40,422 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain]-[DEBUG] After ResponseBodyAdvice chain body=null
2016-12-02 15:26:40,422 [http-bio-8081-exec-1] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Null ModelAndView returned to DispatcherServlet with name 'taotao-manage': assuming HandlerAdapter completed request handling
2016-12-02 15:26:40,423 [http-bio-8081-exec-1] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request
2016-12-02 15:26:40,423 [http-bio-8081-exec-1] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.mybatis.spring.SqlSessionFactoryBean#0'
图片上传
上传组件
使用KindEditor的上传组件:
上传组件的JS实现
上传参数
官方示例代码
workspace/taotao-manage/taotao-manage-web/src/main/webapp/js/kindeditor-4.1.10/examples/multi-image-dialog.html
我们的实现
实现图片上传
在SpringMVC中实现图片上传:
- 导入依赖 commons-fileupload
- 配置文件上传解析器
- 编写具体的上传逻辑(Controller)
对文件做校验:
- 类型,通过文件的后缀名
- 大小
- 上传文件的内容做校验
- 通过获取文件的宽和高来判断是否是图片
上传组件
需求:上传文件返回的数据是:文本类型的json数据。
响应类型:
文本类型:
历史遗留问题。
解决:
安装taotao-common到本地仓库时出错:
测试:
完整的代码
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taotao.manage.bean.PicUploadResult;
/**
* 图片上传
*/
@Controller
@RequestMapping("/pic")
public
class PicUploadController {
private
static
final Logger LOGGER = LoggerFactory.getLogger(PicUploadController.class);
private
static
final ObjectMapper mapper = new ObjectMapper();
// 允许上传的格式
private
static
final String[] IMAGE_TYPE = new String[] { ".bmp", ".jpg", ".jpeg", ".gif", ".png" };
/**
*
* @param uploadFile
* @param response
* @return返回文本类型的json数据
* @throws Exception
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String upload(@RequestParam("uploadFile") MultipartFile uploadFile, HttpServletResponse response)
throws Exception {
// 校验图片格式
boolean
isLegal = false;
for (String type : IMAGE_TYPE) {
if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
isLegal = true;
break;
}
}
// 封装Result对象,并且将文件的byte数组放置到result对象中
PicUploadResult fileUploadResult = new PicUploadResult();
// 状态
fileUploadResult.setError(isLegal ? 0 : 1);
// 文件新路径
String filePath = getFilePath(uploadFile.getOriginalFilename());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Pic file upload .[{}] to [{}] .", uploadFile.getOriginalFilename(), filePath);
}
// 生成图片的绝对引用地址
String picUrl = StringUtils.replace(StringUtils.substringAfter(filePath, "E:\\0114\\taotao-upload"),
"\\", "/");
fileUploadResult.setUrl("http://image.taotao.com" + picUrl);
File newFile = new File(filePath);
// 写文件到磁盘
uploadFile.transferTo(newFile);
// 校验图片是否合法
isLegal = false;
try {
BufferedImage image = ImageIO.read(newFile);
if (image != null) {
fileUploadResult.setWidth(image.getWidth() + "");
fileUploadResult.setHeight(image.getHeight() + "");
isLegal = true;
}
} catch (IOException e) {
}
// 状态
fileUploadResult.setError(isLegal ? 0 : 1);
if (!isLegal) {
// 不合法,将磁盘上的文件删除
newFile.delete();
}
//将java对象序列化为json字符串
return
mapper.writeValueAsString(fileUploadResult);
}
//E:\\1110\\taotao-upload\\images\\2015\\11\\13\\20151113111111111.jpg
private String getFilePath(String sourceFileName) {
String baseFolder = "E:\\0114\\taotao-upload" + File.separator + "images";
Date nowDate = new Date();
// yyyy/MM/dd
String fileFolder = baseFolder + File.separator + new DateTime(nowDate).toString("yyyy")
+ File.separator + new DateTime(nowDate).toString("MM") + File.separator
+ new DateTime(nowDate).toString("dd");
File file = new File(fileFolder);
if (!file.isDirectory()) {
// 如果目录不存在,则创建目录
file.mkdirs();
}
// 生成新的文件名
String fileName = new DateTime(nowDate).toString("yyyyMMddhhmmssSSSS")
+ RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(sourceFileName, ".");
return
fileFolder + File.separator + fileName;
}
}
测试
解决显示图片的问题
之前的上传后,通过tomcat访问图片。
没有真实的项目是通过tomcat访问静态资源。 为什么?
Tomcat是应用服务器,作用:处理动态请求。
Nginx、Apache是web服务器,作用:处理静态资源、反向代理功能。
Web服务器的并发能力远高于应用服务器。
配置nginx访问图片
配置hosts
测试
图片存储路径硬编码到java代码中
解决方案:需要将路径配置到外部的配置文件中。
@value
@Value作用:获取配置文件的值。
注入值:在Spring容器初始化(所有的bean)之后,在当前的所在容器中获取值,然后注入。
Spring父子容器
Spring容器 -- 父容器
SpringMVC容器 -- 子容器
父子容器的关系:
- 子容器能够访问父容器的资源(bean)
- 示例:Controller可以注入Service
- 父容器不能访问子容器的资源(bean)
实现
- 定义ProperttiesService:
- 在Controller中注入Service:
- 测试
查询商品列表
JS
EasyUI的datagrid的格式化输出
默认情况下,会直接显示返回的数据,但是有些情况下不能直接显示,如:价格、日期、性别,需要指定formatter函数。
效果:
后台实现
Controller:
扩展BaseService中的排序查询方法:
日志的书写
总结:
- 方法的入参处需要将参数打印出
- 业务执行的状态发生变化时,需要打印
- 异常处需要打印
淘淘商城_day02_课堂笔记的更多相关文章
- 淘淘商城_day11_课堂笔记
今日大纲 发布前的准备 实施发布 一部分是由我来发布 一部分是由你们来发布 讲解分布式部署架构 测试 功能测试 压力测试 项目实战的准备以及分组 分组 抽取功能 讲解所需要开发的功能 项目部署上线流程 ...
- 淘淘商城_day01_课堂笔记
今日大纲 聊聊电商行业 电商行业发展 11.11 2015双11: 2016年: 预测:2017年的双11交易额将达到:1400亿 电商行业技术特点 淘淘商城简介 淘淘商城的前身 电商行业的概念 B2 ...
- 淘淘商城_day04_课堂笔记
今日大纲 实现首页的大广告位功能 实现内容管理系统 首页的大广告 什么是大广告 JS效果: 点击下面的序号选择查询哪个广告 自动切换 点击图片查询具体的页面 以上是由前端团队来开发. 数据结构 说明: ...
- 淘淘商城_day10_课堂笔记
今日大纲 Dubbo入门学习 使用dubbo优化单点登录系统 系统间服务调用方式 浏览器直接访问 浏览器发起请求,通过ajax或jsonp方式请求: Httpclient方式 系统与系统之间通过Htt ...
- 淘淘商城_day09_课堂笔记
今日大纲 实现购物车 基于Mysql实现读写分离 购物车 需求描述 用户可以在登录状态下将商品添加到购物车 用户可以在未登录状态下将商品添加到购物车 用户可以使用购物车一起结算下单 用户可以查询自己的 ...
- 淘淘商城_day08_课堂笔记
今日大纲 问题,如何实现商品数据的同步? 学习MQ(消息队列) 搭建RabbitMQ的环境 学习RabbitMQ的队列 学习Spring-Rabbit 使用RabbitMQ完成商品数据的同步 如何实现 ...
- 淘淘商城_day07_课堂笔记
今日大纲 讲解订单系统 基于订单系统完成下单功能的开发 使用Solr完成商品的搜索功能 订单系统 说明:订单系统只是做讲解,不做开发. 导入taotao-order 表结构 订单表: 订单商品表: 疑 ...
- 淘淘商城_day05_课堂笔记
今日大纲 学习Redis 使用Redis完成项目中缓存需求 实现商品详情页功能 缓存的需求 大广告位数据无需每次查询后台系统的接口,可以在前台系统添加缓存,提高访问首页的速度. 商品类目的数据也可以缓 ...
- 淘淘商城_day06_课堂笔记
今日大纲 实现单点登录系统 基于单点登录系统实现,用户的注册和登录 商品数据同步问题 问题 后台系统中将商品修改,前台系统没有进行数据的同步,导致前端系统不能够实时显示最新的数据. 解决 后台系统中商 ...
随机推荐
- NG2入门 - 根模块
根模块 app.module 建议大家先去学习angularjs官网的英雄教程后再进行后面的阅读,app.module.ts 就是ng2应用中的引导启动模块也称根模块 import { NgModul ...
- redis 学习笔记——数据同步、事务
redis主从同步 redis支持简单易用的主从复制(master-slave replication)功能,该功能也是redis高可用性实现的基础. redis复制原理 re ...
- <span>什么意思
<span> 在CSS定义中属于一个行内元素,在行内定义一个区域,也就是一行内可以被 <span> 划分成好几个区域,从而实现某种特定效果. <span> 本身没有 ...
- 数据持久层框架iBatis, Hibernate 与 JPA 比较
在本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persistence API(JPA).我们介绍每种解决方案并讨论其所规定的品质,以及在广泛 ...
- Linux CentOS7/RHEL7关闭ctrl+alt+delete功能键
这是本人测试的经过,纯粹记录来看看,最终解决方法在最后面,中间讲的是遇到的一些坑,可以略过不看!! 本人操作经验,转载请表明出处:http://www.cnblogs.c ...
- windows 下安装Python
一.下载 官网地址:https://www.python.org/,64位的版本 二.安装 32位和64位的版本安装起来没有区别,双击打开后,第一步要记得勾上add python to Path 选项 ...
- dev gridcontrol 绑定int型及日期型的列默认当值为0时显示空白及格式化日期显示方式
xmlns:sys="clr-namespace:System;assembly=mscorlib" 如只显示日期的时间部分 <dxg:GridColumn Header=& ...
- oracle_index的建立、修改、删除
索引索引是关系数据库中用于存放每一条记录的一种对象,主要目的是加快数据的读取速度和完整性检查.建立索引是一项技术性要求高的工作.一般在数据库设计阶段的与数据库结构一道考虑.应用系统的性能直接与索引的合 ...
- netty中级篇(2)
上一篇 netty入门篇(1) 一.编码解码技术 如何评价一个编解码技术: 是否支持跨语言,或者说支持的语言是否丰富 编码码流大小,影响传输速度 编码和解码的性能,即时间 类库是否精致,API是否方便 ...
- C# 操作IIS -App & AppPools
using System; using System.DirectoryServices; using System.Management; using Microsoft.Web.Administr ...