ZZJ_淘淘商城项目:day03(淘淘商城02

1.   今日大纲

1、  学习Nginx的使用

2、  实现商品的管理

a)       新增商品

b)       查询商品列表

c)       编辑商品

d)       删除商品

e)       上架和下架商品


SwitchHosts!_win_x64_3.5.0(5486)

https://oldj.github.io/SwitchHosts/

使用SwitchHosts!修改本地hosts文件,实现ip地址和域名的解析。

Win10系统的hosts目录为:

C:WindowsSystem32driversetc

Linux下的hosts文件所在路径: /etc/hosts

# taotao2016 开发环境
127.0.0.1 www.taotao.com
127.0.0.1 manage.taotao.com
127.0.0.1 image.taotao.com

修改配置conf/nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    
    sendfile        on;

    keepalive_timeout  65;

    gzip  on;

    server {
        listen       80;
        server_name  manage.taotao.com;

        #charset koi8-r;

        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
            proxy_pass http://127.0.0.1:8081;
            proxy_connect_timeout 600;
            proxy_read_timeout 600;
        }
    }
    server {
        listen       80;
        server_name  image.taotao.com;

        #charset koi8-r;

        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
            root  F:\javaweb\taotao-upload;
        }
    }
}
taotao2016.conf

使用nginx实现反向代理监听端口

Shift+鼠标右键启动Powershell
ls
F:javaweb
ginx-1.16.1

#powershell启动和关闭nginx.exe服务

.
ginx -c conf	aotao2016.conf

.
ginx -s stop

. ginx -s reload


Spring4.3.25版本集成使用通用Mapper,可以使用泛型注入的新特性。

package com.taotao.manage.service;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.manage.pojo.BasePojo;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

public abstract class BaseService<T extends BasePojo> {
/**
 * 方法:
1、      queryById
2、      queryAll
3、      queryOne
4、      queryListByWhere
5、      queryPageListByWhere
6、      save
7、      update
8、      deleteById
9、      deleteByIds
10、    deleteByWhere
 */
    
    // public abstract Mapper<T> getMapper();
    // spring4.3.25支持泛型注入新特性
    @Autowired
    private Mapper<T> mapper;
    
    /**
     * 根据id查询数据
     * @param id
     * @return
     */
    public T queryById(Long id) {
        return this.mapper.selectByPrimaryKey(id);
    }
    /**
     * 查询所有数据
     * @return
     */
    public List<T> queryAll(){
        return this.mapper.selectAll();
    }
    /**
     * 根据条件查询一条数据
     * 如果该条件所查询的数据为多条会抛出异常
     * @param record
     * @return
     */
    public T queryOne(T record) {
        return this.mapper.selectOne(record);
    }
    /**
     * 根据条件查询多条数据
     * @param record
     * @return
     */
    public List<T> queryListByWhere(T record){
        return this.mapper.select(record);
    }
    /**
     * 根据条件分页查询数据
     * @param record
     * @param pageNum
     * @param pageSize
     * @return
     */
    public PageInfo<T> queryPageListByWhere(T record,Integer pageNum,Integer pageSize){
        //设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        List<T> list = this.mapper.select(record);
        return new PageInfo<T>(list);
    }
    /**
     * 新增数据,未设置的值为null
     * @param t
     * @return
     */
    public Integer save(T t) {

        t.setCreated(new Date());
        t.setUpdated(t.getCreated());
        return this.mapper.insert(t);     
    }
    /**
     * 选择不为null的字段作为插入更新数据
     * @param t
     * @return
     */
    public Integer saveSelective(T t) {
        t.setCreated(new Date());
        t.setUpdated(t.getCreated());
        return this.mapper.insertSelective(t);     
    }
    
    /**
     * 更新数据,未设置的字段值为null
     * @param t
     * @return
     */
    public Integer update(T id) {
        id.setUpdated(new Date());
        return this.mapper.updateByPrimaryKey(id);   
    }
    /**
     * 更新不为null的字段作为更新的字段
     * @param t
     * @return
     */
    public Integer updateSelective(T id) {
        id.setUpdated(new Date());
        id.setCreated(null); //强制设置创建时间为null,永远不会被更新
        return this.mapper.updateByPrimaryKeySelective(id);
    }
    

    /**
     * 根据主键id删除数据(物理删除)
     * @param id
     * @return
     */
    public Integer deleteById(Long id) {
        return this.mapper.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);
        //设置条件,andIn(数据库字段,12345)
        example.createCriteria().andIn(property, ids);
        return this.mapper.deleteByExample(example);
    }
    /**
     * 根据条件删除数据
     * @param record
     * @return
     */
    public Integer  deleteByWhere(T record) {
        return this.mapper.delete(record);
    }
}
public abstract class BaseService

mysql数据库的bigint类型对应JAVA中的Long

item-add.jps的第115行修改restful风格的ajax请求:

        //提交到后台的RESTful
        $.ajax({
           type: "POST",
           url: "/rest/item",
           data: $("#itemAddForm").serialize(),
            statusCode: {
                  201: function() {
                  $.messager.alert('提示','新增商品成功!');            
                  },
                  400: function() {
                  $.messager.alert('提示','提交的参数不合法!');            
                  },
                  500: function() {
                  $.messager.alert('提示','新增商品失败!');        
                  }
           }   
        });

通过日志查看操作Item表和ItemDesc表,由于在Service层的:同一个类、同一个方法,并且已经配置好了spring的AOP管理事务。

信息: Starting ProtocolHandler ["http-bio-8081"]
2019-11-03 09:27:59,142 [http-bio-8081-exec-1] [com.alibaba.druid.pool.DruidDataSource]-[INFO] {dataSource-1} inited
2019-11-03 09:27:59,175 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
2019-11-03 09:27:59,184 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
2019-11-03 09:27:59,265 [http-bio-8081-exec-1] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [com.mysql.jdbc.JDBC4Connection@1e0b3b6e] will be managed by Spring
2019-11-03 09:27:59,269 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==>  Preparing: INSERT INTO tb_item ( created,updated,id,title,sell_point,price,num,barcode,image,cid,status ) VALUES( ?,?,?,?,?,?,?,?,?,?,? ) 
2019-11-03 09:27:59,295 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Parameters: 2019-11-03 09:27:59.17(Timestamp), 2019-11-03 09:27:59.17(Timestamp), null, Z7(String), 970M(String), 500000(Long), 1(Integer), 2(String), (String), 163(Long), 1(Integer)
2019-11-03 09:27:59,303 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] <==    Updates: 1
2019-11-03 09:27:59,307 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] ==>  Executing: SELECT LAST_INSERT_ID() 
2019-11-03 09:27:59,320 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] <==      Total: 1
2019-11-03 09:27:59,320 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
2019-11-03 09:27:59,332 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4] from current transaction
2019-11-03 09:27:59,334 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==>  Preparing: INSERT INTO tb_item_desc ( created,updated,item_id,item_desc ) VALUES( ?,?,?,? ) 
2019-11-03 09:27:59,335 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Parameters: 2019-11-03 09:27:59.332(Timestamp), 2019-11-03 09:27:59.332(Timestamp), 3(Long), qq(String)
2019-11-03 09:27:59,336 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] <==    Updates: 1
2019-11-03 09:27:59,336 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
2019-11-03 09:27:59,337 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
2019-11-03 09:27:59,337 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
2019-11-03 09:27:59,337 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]

5.2.  上传组件的JS实现的上传参数

 

5.3.实现springMVC图片上传

1.导入 commons-fileupload 的依赖坐标

        <!-- 文件上传组件 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>

2.配置文件上传解析器在springmvc.xml

    <!-- 定义文件上传解析器 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>

3.PicUploadController使用了配置文件中的路径,读取配置文件用Service层spring父容器的一个“读取配置文件的类” 的 public关键字修饰的成员属性

package com.taotao.manage.controller;

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.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
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.common.bean.PicUploadResult;
import com.taotao.manage.service.PropertieService;


/**
 * 图片上传
 */
@Controller
@RequestMapping("/pic")
public class PicUploadController {

    
    
        //创建日志对象
    private static final Logger LOGGER = LoggerFactory.getLogger(PicUploadController.class);

    @Autowired
    private PropertieService propertieService;
    
    private static final ObjectMapper mapper = new ObjectMapper();

    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[] { ".bmp", ".jpg", ".jpeg", ".gif", ".png" };

    @PostMapping(value = "/upload", 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, propertieService.REPOSITORY_PATH), "\", "/");
        fileUploadResult.setUrl(propertieService.IMAGE_BASE_URL + 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();
        }

        response.setContentType(MediaType.TEXT_HTML_VALUE);
        //将java对象序列化成json数据
        return mapper.writeValueAsString(fileUploadResult);
    }

    private String getFilePath(String sourceFileName) {
        String baseFolder = propertieService.REPOSITORY_PATH + 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;
    }

}
View Code

Spring容器  --  父容器

SpringMVC容器  -- 子容器

父子容器的关系:

1、  子容器能够访问父容器的资源(bean)

a)       示例:Controller可以注入Service

2、  父容器不能访问子容器的资源(bean)

package com.taotao.manage.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


@Service
public class PropertieService {
    // 加载spring父容器中配置文件内容
    @Value("${REPOSITORY_PATH}")
    public String REPOSITORY_PATH;

    @Value("${IMAGE_BASE_URL}")
    public String IMAGE_BASE_URL;
}

 对文件做校验:

1、 类型,通过文件的后缀名

2、 大小

3、 上传文件的内容做校验

 a)   通过获取文件的宽和高来判断是否是图片

7.   日志的书写

总结:

1、  方法的入参处需要将参数打印出

2、  业务执行的状态发生变化时,需要打印

3、  异常处需要打印


6.   查询商品列表

EasyUI的datagrid的格式化输出。

默认情况下,会直接显示返回的数据,但是有些情况下不能直接显示,如:价格、日期、性别,需要指定formatter函数。

@Service
public class ItemListService extends BaseService<Item> {
    
    @Autowired
    ItemMapper itemMapper;
    
    //根据商品更新时间降序排序
    public EasyUIResult queryItemList(Integer page, Integer rows) {
        //第三个参数:是否count查询
        PageHelper.startPage(page, rows, true);
        
        //设置查询条件
        Example example = new Example(Item.class);
        example.setOrderByClause("updated DESC");
        List<Item> list = itemMapper.selectByExample(example);
        
        PageInfo<Item> pageInfo = new PageInfo<>(list);
        // 返回给视图层一个包装好的EasyUIResult对象
        return new EasyUIResult(pageInfo.getTotal(), pageInfo.getList());
    }

}

=====================================

end

部分内容来自于学习编程期间收集于网络的免费分享资源和工作后购买的付费内容。
原文地址:https://www.cnblogs.com/MarlonKang/p/11781289.html