分布式思维

分布式计算
阐明: 一项工作由多个服务器共同完成的.
例子: 假如一项工作独自实现须要10天,如果有10集体同时执行则一天实现. 大数据处理技术.

分布式系统
阐明: 将我的项目依照特定的功能模块及层级进行拆分.从而升高整个零碎架构的耦合性问题.

分布式我的项目拆分

外围:无论未来我的项目怎么拆分,都是同一个零碎. 口诀: 对外对立,对内互相独立

依照模块拆分

因为单体架构中耦合性太高,所以采纳了分布式思维,将我的项目依照模块进行拆分,使得各个模块之间相互不影响.进步了整体的扩展性.

依照层级拆分

阐明:因为某些我的项目性能实现起来比较复杂,须要多人协同单干,则须要将我的项目依照层级再次拆分.

分布式系统引发的问题

1.分布式系统中jar包文件如何对立治理?
2.分布式系统中工具API如何对立治理?

京淘我的项目后端搭建

创立父级工程jt

新建我的项目

打包形式: pom 示意:该我的项目是一个聚合工程,里边蕴含了很多的小我的项目,并且该我的项目能够对立治理公共的jar包文件.

编辑POM.xml文件

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.jt</groupId>    <artifactId>jt2007</artifactId>    <version>1.0-SNAPSHOT</version>    <!--1.设定打包形式 为聚合工程-->    <packaging>pom</packaging>    <!--2.对立治理jar包-->    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>2.3.4.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <properties>        <java.version>1.8</java.version>        <skipTests>true</skipTests>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-jdbc</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-devtools</artifactId>            <scope>runtime</scope>            <optional>true</optional>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <scope>runtime</scope>        </dependency>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <optional>true</optional>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>            <exclusions>                <exclusion>                    <groupId>org.junit.vintage</groupId>                    <artifactId>junit-vintage-engine</artifactId>                </exclusion>            </exclusions>        </dependency>        <!--spring整合mybatis-plus -->        <dependency>            <groupId>com.baomidou</groupId>            <artifactId>mybatis-plus-boot-starter</artifactId>            <version>3.2.0</version>        </dependency>        <!--springBoot整合JSP增加依赖  -->        <!--servlet依赖 -->        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>javax.servlet-api</artifactId>        </dependency>        <!--jstl依赖 -->        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>jstl</artifactId>        </dependency>        <!--使jsp页面失效 -->        <dependency>            <groupId>org.apache.tomcat.embed</groupId>            <artifactId>tomcat-embed-jasper</artifactId>        </dependency>        <!--增加httpClient jar包 -->        <dependency>            <groupId>org.apache.httpcomponents</groupId>            <artifactId>httpclient</artifactId>        </dependency>        <!--引入dubbo配置 -->        <!--<dependency>            <groupId>com.alibaba.boot</groupId>            <artifactId>dubbo-spring-boot-starter</artifactId>            <version>0.2.0</version>        </dependency>-->        <!--增加Quartz的反对 -->        <!--<dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-quartz</artifactId>        </dependency>-->        <!-- 引入aop反对 -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-aop</artifactId>        </dependency>        <!--spring整合redis -->        <dependency>            <groupId>redis.clients</groupId>            <artifactId>jedis</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.data</groupId>            <artifactId>spring-data-redis</artifactId>        </dependency>    </dependencies>    <!--        注意事项: 聚合工程自身不须要公布,所以不要增加 build标签    --></project>

编辑工具API jt-common

打包类型: jar

创立我的项目

查看是否有父子级关系

导入课前材料

创立jt-manage我的项目

打包形式: war包 留神IDEA的工作目录的配置

创立我的项目

编辑POM.xml文件

`<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>jt-manage</artifactId>    <!--1.web我的项目打成war包-->    <packaging>war</packaging>    <!--2.继承父级我的项目-->    <parent>        <artifactId>jt2007</artifactId>        <groupId>com.jt</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <!--3.依赖工具API-->    <dependencies>        <dependency>            <groupId>com.jt</groupId>            <artifactId>jt-common</artifactId>            <version>1.0-SNAPSHOT</version>        </dependency>    </dependencies>    <!--4.增加maven插件-->    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>` 

导入动态资源文件

阐明:将课前材料中jt-manage中的src文件导入.

批改启动项

对于SpringBoot默认页面拜访阐明

阐明: SpringBoot我的项目中如果用户采纳缺省值拜访时,则SpringBoot会采纳模板工具API进行页面跳转. 如果应用模板工具API则会动静的拼接视图解析器的前缀和后缀
eg:
前缀: /WEB-INF/views/
后缀 .jsp
默认零碎欢送页面的全门路: /WEB-INF/views/index.jsp

京淘后盾页面构造阐明

京淘后端页面布局阐明

`<link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" /><link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/icon.css" /><link rel="stylesheet" type="text/css" href="/css/jt.css" /><script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script><script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script><script type="text/javascript" src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script></head><body class="easyui-layout">   <div data-options="region:'north',title:'North Title',split:true" style="height:100px;"></div>      <div data-options="region:'south',title:'South Title',split:true" style="height:100px;"></div>      <div data-options="region:'east',iconCls:'icon-reload',title:'East',split:true" style="width:100px;"></div>      <div data-options="region:'west',title:'West',split:true" style="width:100px;"></div>      <div data-options="region:'center',title:'center title'" style="padding:5px;background:#eee;"></div></body>` 

树形构造

 `<ul class="easyui-tree">              <li>            <span>商品治理</span>            <ul>                <li>商品查问</li>                <li>商品新增</li>                <li>                    <span>今日价格</span>                    <ul>                        <li>猪肉: 10块/斤</li>                        <li>牛肉: 30块/斤</li>                        <li>羊肉: 24块/斤</li>                    </ul>                </li>            </ul>        </li>      </ul>` 

京淘后盾实现

通用页面跳转实现

package com.jt.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;@Controllerpublic class IndexController {    /*@RequestMapping("/index")    public String index(){        return "index";    }*/    /**     * 需要:实现通用页面跳转     *  url: /page/item-add    页面:item-add.jsp     *  url: /page/item-list   页面:item-list.jsp     * 论断: url中的地址就是跳转的页面信息.     *     * restFul格调实现1:     *     作用: 能够动静的接管url中的参数     *     语法:     *          1.url中的地址如果是参数,则须要应用/宰割     *          2.controller办法接管参数时,须要应用{}号形式获取     *          3.如果须要获取参数信息,则应用特定的注解标识     *     * restFul格调实现2: 须要指定拜访的申请类型,并且依据特定的类型执行业务     *      申请类型:     *          1.get    执行查问操作     *          2.post   执行入库操作     *          3.put    执行更新操作     *          4.delete 执行删除操作     */   //@RequestMapping(value = "/page/{moduleName}",method = RequestMethod.GET)    @GetMapping("/page/{moduleName}")    public String module(@PathVariable String moduleName){        return moduleName;    }}

UI框架-表格数据展示阐明

外围: JS中须要什么数据,则后端程序员就封装什么数据!!

常见缩写介绍

  1. POJO 与数据库映射的实体类对象
  2. VO : 数据展示层的对象 次要与页面JS进行数据交互的媒介

EasyUI表格定义

<div>            定义表格,并且通过url拜访json数据, fitColumns:true示意主动适应,singleSelect:true 示意选中单个            <table class="easyui-datagrid" style="width:500px;height:300px"                   data-options="url:'datagrid_data.json',method:'get',                   fitColumns:true,singleSelect:false,pagination:true">                <thead>                     <tr>                         <th data-options="field:'code',width:100">Code</th>                         <th data-options="field:'name',width:100">Name</th>                         <th data-options="field:'price',width:100,align:'right'">Price</th>                    </tr>                 </thead>             </table>         </div>

表格数据返回格局阐明

{    "total":2000,    "rows":[        {"code":"A","name":"果汁","price":"20"},        {"code":"B","name":"汉堡","price":"30"},        {"code":"C","name":"鸡柳","price":"40"},        {"code":"D","name":"可乐","price":"50"},        {"code":"E","name":"薯条","price":"10"},        {"code":"F","name":"麦旋风","price":"20"},        {"code":"G","name":"套餐","price":"100"}    ]}

依据返回值 定义VO对象

JSON构造阐明

什么是JSON

答:JSON(JavaScript Object Notation) 是一种轻量级的数据交换格局。

JSON格局之对象格局

对象(object) 是一个无序的“‘名称/值’对”汇合。一个对象以“{”(左括号)开始,“}”(右括号)完结。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间应用“,”(逗号)分隔。

eg: {“id”:“100”,“name”:“tomcat猫”}

JSON格局之数组格局


eg: [“1”,“玩”,“学习”]

JSON格局之嵌套格局

京淘商品后盾治理实现商品POJO对象

@TableId(type=IdTyple.AUTO) 加了这个注解的属性标识为自增主键
package com.jt.pojo;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;import lombok.Data;import lombok.experimental.Accessors;@JsonIgnoreProperties(ignoreUnknown=true) //示意JSON转化时疏忽未知属性@TableName("tb_item")@Data@Accessors(chain=true)public class Item extends BasePojo{    @TableId(type=IdType.AUTO)        //主键自增    private Long id;                //商品id    private String title;            //商品题目    private String sellPoint;        //商品卖点信息    private Long price;            //商品价格 double精度问题 num *100 /100 long    private Integer num;            //商品数量    private String barcode;            //条形码    private String image;            //商品图片信息 1.jpg,2.jpg,3.jpg    private Long cid;                //示意商品的分类id    private Integer status;            //1失常,2下架        //为了满足页面调用需要,增加get办法    public String[] getImages(){                return image.split(",");    }}

分页查问实现类(findItemByPage)

  • 须要定义sql语句@Select("SELECT * FROM tb_item ORDER BY updated DESC LIMIT #{startNum}, #{rows}")
  • 前端向服务器传两个参数,当前页和一页的数据量(page,rows)
  • 依据两个参数能够计算出开始的下标 (page-1)*rows
  • 应用开始下标和查问数量,即可失去后果,返回的后果封装成对象(总记录数(total)本次查问到的数据(itemList))
package com.jt.service;import com.jt.pojo.Item;import com.jt.vo.EasyUITable;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.jt.mapper.ItemMapper;import java.util.List;@Servicepublic class ItemServiceImpl implements ItemService {        @Autowired    private ItemMapper itemMapper;    /*    SELECT * FROM tb_item LIMIT 0, 20 /*第一页 0-19    SELECT * FROM tb_item LIMIT 20,20 /*第二页 20-39    SELECT * FROM tb_item LIMIT 40,20 /*第三页 40-59    SELECT * FROM tb_item LIMIT (page-1)*ROWS,ROWS 40-59*/    /**     * 1.后端查询数据库记录     * 2.将后端数据通过业务调用转化为VO对象     * 3.前端通过VO对象的JSON进行数据的解析     *     *执行的sql:     *     select * from tb_item order by updated desc LIMIT 0, 20     * @param page     * @param rows     * @return     */    @Override    public EasyUITable findItemByPage(int page, int rows) {        //1.total 获取数据库总记录数        long total = itemMapper.selectCount(null);        //2.rows 商品分页查问的后果        int startNum = (page-1)*rows;        List<Item> itemList = itemMapper.findItemByPage(startNum,rows);        //3.将返回值后果封装        return new EasyUITable(total,itemList);    }}

分页查问实现类(selectPage)

  • MP自带的分页查询方法,应用简略,然而须要加配置类
  • Page对象封装了查问一页的条件信息(起始位,查问个数。。。)
  • QueryWrapper封装查问条件
@Servicepublic class ItemServiceImpl implements ItemService {        @Autowired    private ItemMapper itemMapper;    @Override    public EasyUITable findItemByPage(int page, int rows) {        //1.须要应用MP的形式进行分页        IPage<Item> iPage = new Page<>(page,rows);        QueryWrapper<Item> queryWrapper = new QueryWrapper<>();        queryWrapper.orderByDesc("updated");        //MP通过分页操作将分页的相干数据对立封装到IPage对象中        iPage = itemMapper.selectPage(iPage,queryWrapper);        return new EasyUITable(iPage.getTotal(),iPage.getRecords());    }}

MybatisPlus配置类官网默认配置,目标是拦挡一个响应,否则会就会阻塞期待齐全的查一遍库中所有的数据

阐明:在jt-common中增加MP的配置文件

package com.jt.config;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration //标识配置类public class MybatisPlusConfig {    @Bean    public PaginationInterceptor paginationInterceptor() {        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();        // 设置申请的页面大于最大页后操作, true调回到首页,false 持续申请 默认false        // paginationInterceptor.setOverflow(false);        // 设置最大单页限度数量,默认 500 条,-1 不受限制        // paginationInterceptor.setLimit(500);        // 开启 count 的 join 优化,只针对局部 left join        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));        return paginationInterceptor;    }}

商品分类目录实现

封装POJO对象

@TableName("tb_item_cat")@Data@Accessors(chain = true)public class ItemCat extends BasePojo{    @TableId(type = IdType.AUTO)    private Long id;         //主键ID    private Long parentId;   //父级ID    private String name;     //分类名称    private Integer status;  //状态    private Integer sortOrder;  //排序号    private Boolean isParent;   //是否为父级}

页面JS引入过程

引入JS/CSS款式

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" /><link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/icon.css" /><link rel="stylesheet" type="text/css" href="/css/jt.css" /><script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script><script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script><script type="text/javascript" src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script><!-- 本人实现业务逻辑 --><script type="text/javascript" src="/js/common.js"></script>

引入common.jsp

数据格式化

格式化价格

`1.页面标签<th data-options="field:'price',width:70,align:'right',formatter:KindEditorUtil.formatPrice">价格</th>2.页面JSformatPrice : function(val,row){        return (val/100).toFixed(2);    },` 

格式化状态

<th data-options="field:'status',width:60,align:'center',formatter:KindEditorUtil.formatItemStatus">状态</th>// 格式化商品的状态    formatItemStatus : function formatStatus(val,row){        if (val == 1){            return '<span >失常</span>';        } else if(val == 2){            return '<span >下架</span>';        } else {            return '未知';        }    },

格式化商品分类目录

页面构造剖析

<th data-options="field:'cid',width:100,align:'center',formatter:KindEditorUtil.findItemCatName">叶子类目</th>//格式化名称    findItemCatName : function(val,row){        var name;        $.ajax({            type:"get",            url:"/item/cat/queryItemName",            data:{itemCatId:val},            cache:true,    //缓存            async:false,    //示意同步   默认的是异步的true            dataType:"text",//示意返回值参数类型            success:function(data){                name = data;            }        });        return name;    },

编辑ItemCatController

@RestController //要求返回JSON数据@RequestMapping("/item/cat")public class ItemCatController {    @Autowired    private ItemCatService itemCatService;    /**     * 业务: 依据商品分类的ID,查问商品分类的名称     * url:  /item/cat/queryItemName     * 参数: itemCatId  商品分类id     * 返回值: 商品分类名称     */    @RequestMapping("queryItemName")    public String findItemCatName(Long itemCatId){        return itemCatService.findItemCatName(itemCatId);    }}

编辑ItemCatService

package com.jt.service;import com.jt.mapper.ItemCatMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class ItemCatServiceImpl implements ItemCatService{    @Autowired    private ItemCatMapper itemCatMapper;    @Override    public String findItemCatName(Long itemCatId) {        return itemCatMapper.selectById(itemCatId).getName();    }}

页面成果展示

ajax嵌套问题

阐明: 如果在ajax外部再次嵌套ajax申请,则须要将外部的ajax申请设置为同步状态.俗语: 连忙走吧 赶不上二路公交车了…,示意后面发申请响应时,服务器还没解决完外围起因: 页面须要刷新2次都是只刷新一次.

jQuery根本用法

1.选择器 在整个html页面 依据某些特定的标识 精确的定位元素的地位.

  1. Id选择器 $("#元素的Id")
  2. 元素(标签)选择器 $(“tr”)
  3. 类选择器 $(".class的名称") [{},{},{}]

3级表数据的剖析

阐明:通过parentId 依据父级的ID查问所有的子级信息.
当查问一级菜单时parentId=0; 查问别的菜单的子菜单时 条件为父级ID=该菜单id的分类

/*查问一级分类信息 父级ID=0*/SELECT * FROM tb_item_cat WHERE parent_id=0;/*查问二级分类信息 父级ID=id*/SELECT * FROM tb_item_cat WHERE parent_id=495;/*查问三级分类信息 父级ID=id*/SELECT * FROM tb_item_cat WHERE parent_id=529;

EasyUI中树形构造阐明

$("#tree").tree({            url:"tree.json",        //加载近程JSON数据            method:"get",            //申请形式 POST            animate:false,            //示意显示折叠端口动画成果            checkbox:true,            //表述复选框            lines:false,                //示意显示连接线            dnd:true,                //是否拖拽            onClick:function(node){    //增加点击事件                          //控制台                console.info(node);            }        });

返回值阐明,
前端的EasyUI树,须要靠这三个属性来构建树结构,所以在后端须要封装这三条属性

[    {        "id":"1",        "text":"吃鸡游戏",        "state":"closed"    },    {        "id":"1",        "text":"吃鸡游戏",        "state":"closed"    }]

封装树形构造VO对象

@Data@Accessors(chain = true)@NoArgsConstructor@AllArgsConstructorpublic class EasyUITree implements Serializable {private Long id; //节点IDprivate String text; //节点名称private String state; //节点状态}

异步树加载阐明

树控件读取URL。子节点的加载依赖于父节点的状态。当开展一个关闭的节点,如果节点没有加载子节点,它将会把节点id的值作为http申请参数并命名为’id’,通过URL发送到服务器下面检索子节点。