通用mapper、图片上传、nginx

通用Mapper介绍

1.1 通用Mapper入门案例

1.1.1 通用的findCount()

  1. 编辑接口

 

/**
     * 需求:自己实现一个通用Mapper的方法
     * 要求:查询任意表的记录总数???
     * sql: select count(*) from 表名
     */
    @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int findCount();

2.编辑测试方法

/**
     * 目的:获取表的名称
     * 1.获取方法的执行的路径
     * 2.获取Mapper的接口路径
     * 3.通过反射的机制获取Mapper的类型
     * 4.通过Mapper的类型获取父级接口类型
     *      1.判断父级接口是否为泛型
     * 5.获取泛型中的类型 Item
     * 6.获取item类型的注解
     * 7.获取表的名称
     * @param ms
     * @return
     */
    public SqlNode findCount(MappedStatement ms){
        
        //1.获取当前正在执行的Mapper的方法路径
        //com.jt.manage.mapper.itemMapper.findCount()
        try {
            //1.获取客户端调用的方法 
            //com.jt.manage.mapper.ItemMapper.findCount()
            String methodPath = ms.getId();
            
            //2.获取ItemMapper的字符串  com.jt.manage.mapper.ItemMapper
            String targetPath = methodPath.substring(0, methodPath.lastIndexOf("."));
            
            //3.获取ItemMapper对象   ItemMapper.Class
            Class<?> targetClass = Class.forName(targetPath);
            
            //4.获取ItemMapper的父级接口 由于接口是可以多继承的
            Type[] types = targetClass.getGenericInterfaces();
            
            //5.获取SysMapper
            Type targetType = types[0];
            
            //判断该类型是否为泛型     SysMapper<Item> 
            if(targetType instanceof ParameterizedType){
                //表示当前接口是一个泛型,并且获取泛型参数  SysMapper<Item>
                ParameterizedType parameterizedType = (ParameterizedType) targetType;
                
                //SysMapper<T,V,K>   获取泛型的全部参数  Item Type
                Type[] supers =  parameterizedType.getActualTypeArguments();
                
                //表示成功获取第一个参数   Item.class
                Class<?> targetMethodClass = (Class<?>) supers[0];
                
                //判断Class不能为空
                if(targetMethodClass !=null){
                    
                    //判断该类中是否含有注解
                    if(targetMethodClass.isAnnotationPresent(Table.class)){
                        //获取目标对象的注解
                        Table table = targetMethodClass.getAnnotation(Table.class);
                        
                        //获取表名
                        String tableName = table.name();
                        
                        //定义查询sql语句
                        String sql = "select count(*) from "+tableName;
                        
                        //定义sqlNode对象
                        SqlNode sqlNode = new StaticTextSqlNode(sql);
                        
                        return sqlNode;
                    }    
                }
            }
            
            } catch (ClassNotFoundException e) {
                
                e.printStackTrace();
            }
            
            return null;
            
        }

 

 

富文本编辑器

2.1 入门案例

2.1.1 引入js

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>

 

 

2.1.2 初始化文本编辑器

<script type="text/javascript">
    $(function(){
        KindEditor.ready(function(){
            KindEditor.create("#editor")
        })
    })
    
</script>

 

2.2 商品描述新增

2.2.1 表设计

 

2.2.2 编辑pojo对象

  

2.2.3 页面分析

说明:根据页面中的name属性进行数据传输

<td>商品描述:</td>
  <td>
      <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea>
  </td>

 

 

2.2.4 编辑Controller

 

2.2.5 编辑Service

 

/**
     * 说明:
     *     Item对象的主键是自增的,所以item中的id现在为null
     *  ItemDesc对象入库操作时,必须含有主键Id信息.
     * 困难:如果获取已经入库的id??
     * 解决:
     * 利用通用Mapper的机制.当执行插入操作时,会先查询当前最大的id.
     * 之后回显.
     *   SELECT LAST_INSERT_ID() 
     * @param item
     * @param desc
     */
    @Override
    public void saveItem(Item item,String desc) {
        //补齐Item数据
        item.setStatus(1); //启用
        item.setCreated(new Date());
        item.setUpdated(item.getCreated());
        
        //利用通用Mapper实现入库操作
        itemMapper.insert(item);
        //为ItemDesc补齐数据
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemDesc(desc);
        itemDesc.setItemId(item.getId());
        itemDesc.setCreated(item.getCreated());
        itemDesc.setUpdated(item.getCreated());
        itemDescMapper.insert(itemDesc);    
    }

2.3 商品描述的回显

2.3.1 页面分析

 

2.3.2 编辑Controller

 

2.3.3 编辑Service

说明:通过通用Mapper的根据主键查询ItemDesc信息

 

 

2.4 商品描述信息修改

2.4.1 页面分析

说明:根据修改页面的语句.接收name=desc提交的数据

<tr>
                <td>商品描述:</td>
                <td>
                    <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea>
                </td>
            </tr>

 

2.4.2 编辑Controller

说明:接收Desc数据

 

2.4.3 编辑Service

 

 

2.4.4 效果展现

说明:数据已经修改

 

2.5 商品关联删除

2.5.1 商品描述删除

 

2.6 图片的上传

2.6.1 页面分析

说明:如果测试图片上传,需要使用谷歌浏览器.

 

 

2.6.2 添加文件上传解析器

<!--配置文件上传解析器
        要求:
            1.id的名称必须固定  multipartResolver
            2.规范文件上传的参数
    -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--最大的上传量10M  -->
        <property name="maxUploadSize" value="10485760"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

 

2.7 Spring属性赋值

说明:将本地的磁盘路径和url直接写死在代码中,不是特别的好,最好使用配置文件的方式进行动态的注入.

2.7.1 编辑配置文件

 

2.7.2 Spring容器管理配置文件

 

2.7.3 动态的取值

 

2.8 文件上传

2.8.1 编辑Controller

 

 

2.8.2 编辑Service

/**
     * 文件上传的步骤
     * 1.判断是否为图片  png|jpg|gif
     * 2.判断是否非法程序 通过BufferedImage对象
     * 3.为了让图片检索快速,使用分文件夹存储
     * 4.应该尽可能让图片名称不一致
     * 5.将文件进行写盘操作
     * 6.url和本地的文件路径的关系?
     *   url的作用:
     *       通过用户访问虚拟路径,获取图片的资源
     *   https://img11.360buyimg.com/n1/s150x150_jfs/t4918/211/45049371/104197/15abee23/58d9d1deN542b664b.jpg
     *   
     * 结论:
     *     1.本地的磁盘路径是保存图片的物理地址
     *  2.url是用户访问图片的虚拟地址
     *  
     *  物理地址: E:\jt-upload/2018/10/1/10/abc.jpg
     *  虚拟地址: http://image.jt.com/2018/10/1/10/abc.jpg
     *  
     *  
     */
    @Override
    public PicUploadResult uploadFile(MultipartFile uploadFile) {
        
        PicUploadResult result = new PicUploadResult();
        
        //1.获取文件的名称     abc.jpg
        String fileName = uploadFile.getOriginalFilename();
        
        //2.判断是否为图片类型  .代表任意一个不为空格的字符
        if(!fileName.matches("^.*(jpg|png|gif)$")){
            result.setError(1); //表示不是一个图片
            return result;
        }
        
        try {
            //3.判断是否为恶意程序
            BufferedImage bufferedImage = 
                    ImageIO.read(uploadFile.getInputStream());
            
            //4.获取图片的高度和宽度
            int height = bufferedImage.getHeight();//获取高度
            int width = bufferedImage.getWidth();  //获取宽度
            
            if(height == 0 || width == 0){
                //表示不是图片
                result.setError(1);
                return result;
            }
            
            //如果程序执行到这里表示图片正常
            //5.定义本地磁盘的路径
            //String LPath = "E:/jt-upload/";
            
            //6.采用时间格式分文件存储 yyyy/MM/dd/HH
            String datePath = 
                    new SimpleDateFormat("yyyy/MM/dd/HH")
                    .format(new Date());
            
            //7.拼接存储文件夹   E:/jt-upload/yyyy/MM/dd/HH
            String filePath = LPath + datePath;
            
            //8.判断文件夹是否存在
            File file = new File(filePath);
            
            if(!file.exists()){
                //表示文件不存在
                file.mkdirs();    //创建文件夹
            }
            
            //9.重构文件名,让文件名称尽可能不一致
            
            //获取文件的类型    abc.jpg===>.jpg
            String fileType = 
                    fileName.substring(fileName.lastIndexOf("."));
            
            //使用UUID生成文件名称  sdfsdfsdf-sdfsdfa-sadfasdf-asdfasd
            String uuid = UUID.randomUUID().toString()
                    .replace("-", "");
            
            /**
             * 形成文件的完成路径  E:/jt-upload/yyyy/MM/dd/HH/asdfasdfasdf.jpg
             */
            String realPath = filePath + "/" + uuid + fileType;
            
            //10.写盘操作
            uploadFile.transferTo(new File(realPath));
            
            //11.封装虚拟路径,用户图片的展现
            //String uPath = "http://image.jt.com/";
            
            //拼接虚拟路径 
            //http://image.jt.com/2018/03/02/16/
            String realUrlPath = uPath +  datePath + "/"
                    + uuid + fileType;
            
            result.setUrl(realUrlPath);    //赋值url路径
            result.setHeight(height+"");
            result.setWidth(width+"");
            return result;    
        } catch (Exception e) {
            result.setError(1); //表示非法图片
            return result;
        }
    }

 

文件上传的图片回显

3.1 url分析

3.1.1 文件回显的url

说明:文件上传后.根据自定义的虚拟路径获取图片的信息

 

 

问题:

文件在本地磁盘下存储

E:\jt-upload\2018\03\02\16\1.jpg

URL的路径

http://image.jt.com/2018/03/02/17/54d2410e4d6646a4882377d0aa0510f3.jpg

 

问题:本地的磁盘路径与url的路径是不匹配的

解决方法:nginx反向代理技术

3.1.2 反向代理

说明:用户根据虚拟路径请求静态资源,经过Nginx,将请求转发真实的磁盘路径下.获取静态资源文件.再次由Nginx将结果回传给客户端.这样的方式叫做反向代理

 

3.2 Nginx介绍

3.2.1 Nginx说明

 

3.2.2 Nginx下载

 

3.3 Nginx本地磁盘部署

3.3.1 导入本地

说明:路径不要安装到C/不要有空格和中文

 

3.3.2 Nginx命令

  1. 以管理员身份运行

 

2.命令

1.start nginx

2.nginx -s stop

3.nginx -s reload  

重启(该命令会提示报错信息)

 

3.3.3 Nginx配置

#定义图片服务器  root表示转向文件夹
    server {
        listen       80;
        server_name  image.jt.com;

        location / {
            root   E:\jt-upload;
        }
    }

 

3.3.4 修改hosts文件

说明:修改了host文件后,可以将指定的路径发往本机.

路径:

C:\Windows\System32\drivers\etc/hosts

 

编辑HOST文件

 

3.3.5 图片回显调用过程

 

 

说明:

  1. 当根据虚拟路径请求图片时,首先经过Hosts中的配置转向到本地的服务器.否则会去外网中查询image.jt.com的服务器.
  2. 通过Hosts文件转向本地后,请求会被Nginx拦截实现反向代理.将请求转发到指定的文件夹下 E:/jt-upload.请求图片信息
  3. 当获取到图片信息后,返回结果给Nginx.之后再由Nginx回传给客户端.

3.3.6 效果:

 

posted @ 2018-03-15 21:10  项羽齐  阅读(329)  评论(0编辑  收藏  举报