分布式思维
分布式计算
阐明: 一项工作由多个服务器共同完成的.
例子: 假如一项工作独自实现须要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中须要什么数据,则后端程序员就封装什么数据!!
常见缩写介绍
- POJO 与数据库映射的实体类对象
- 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页面 依据某些特定的标识 精确的定位元素的地位.
- Id选择器 $("#元素的Id")
- 元素(标签)选择器 $(“tr”)
- 类选择器 $(".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发送到服务器下面检索子节点。