步骤 1 : 关于 idea 运行会失败 步骤 2 : 关于 idea 运行会失败 步骤 3 : 关于 idea 运行会失败 步骤 4 : 关于 idea 运行会失败 步骤 5 : 关于 idea 运行会失败 步骤 6 : 关于 idea 运行会失败 步骤 7 : 关于 idea 运行会失败 步骤 8 : 关于 idea 运行会失败 步骤 9 : 关于 idea 运行会失败 步骤 10 : 关于 idea 运行会失败 步骤 11 : 关于 idea 运行会失败 步骤 12 : 关于 idea 运行会失败 步骤 13 : 关于 idea 运行会失败 步骤 14 : 关于 idea 运行会失败 步骤 15 : 关于 idea 运行会失败 步骤 16 : 关于 idea 运行会失败 步骤 17 : 关于 idea 运行会失败 步骤 18 : 关于 idea 运行会失败 步骤 19 : 关于 idea 运行会失败 步骤 20 : 图床 步骤 21 : 关于JDK版本 步骤 22 : 图床 步骤 23 : 拓扑图点亮 步骤 24 : 拓扑图点亮 步骤 25 : 拓扑图点亮 步骤 26 : 专门用于回收的step 步骤 27 : 答案-综合练习2 步骤 28 : step1 步骤 29 : step2 步骤 30 : 先运行,看到效果,再学习 步骤 31 : Page.java 步骤 32 : 为空判断 步骤 33 : 编辑页面提交数据 步骤 34 : ProductServiceImpl 步骤 35 : 查询功能讲解 步骤 36 : 增加功能讲解 步骤 37 : 编辑功能讲解 步骤 38 : 修改功能讲解 步骤 39 : 删除功能讲解 步骤 40 : 其他-分页 步骤 41 : ReviewServiceImpl 步骤 42 : ProductDAO 步骤 43 : applicationContext.xml 步骤 44 : OrderService 步骤 45 : ForeRESTController.loginAjax() 步骤 46 : ProductServiceImpl 步骤 47 : searchPage.html 步骤 48 : 设计模式 步骤 49 : jars 步骤 50 : JAVA部分 步骤 51 : JAVA部分 步骤 52 : 前端部分 步骤 53 : 前端部分 步骤 54 : 框架 步骤 55 : 框架 步骤 56 : 实践项目 步骤 57 : 实践项目 步骤 58 : ForeController方法一览 步骤 59 : 确认项目名称 步骤 60 : Maven import 步骤 61 : 新建java源代码目录 步骤 62 : 创建包 步骤 63 : Category 步骤 64 : CategoryMapper 步骤 65 : CategoryService 步骤 66 : CategoryServiceImpl 步骤 67 : CategoryController 步骤 68 : CategoryMapper.xml 步骤 69 : log4j.properties 步骤 70 : jdbc.properties 步骤 71 : applicationContext.xml 步骤 72 : springMVC.xml 步骤 73 : 修改web.xml 步骤 74 : listCategory.html 步骤 75 : 配置Tomcat 步骤 76 : 启动Tomcat 步骤 77 : CategoryMapper.xml 步骤 78 : CategoryMapper 步骤 79 : CategoryService 步骤 80 : CategoryServiceImpl 步骤 81 : CategoryController 步骤 82 : listCategory.html 步骤 83 : 为了便于理解,先来一个简化了的adminPage.html 步骤 84 : 完整版的adminPage.html 步骤 85 : CategoryMapper.xml 步骤 86 : CategoryMapper 步骤 87 : CategoryService 步骤 88 : CategoryServiceImpl 步骤 89 : UploadedImageFile 步骤 90 : 用于删除的超链 步骤 91 : 删除前的确认操作 步骤 92 : CategoryMapper.xml 步骤 93 : CategoryMapper 步骤 94 : CategoryService 步骤 95 : CategoryServiceImpl 步骤 96 : CategoryController 步骤 97 : CategoryMapper.xml 步骤 98 : CategoryMapper 步骤 99 : CategoryService 步骤 100 : CategoryServiceImpl 步骤 101 : CategoryController 步骤 102 : CategoryMapper.xml 步骤 103 : CategoryMapper 步骤 104 : CategoryService 步骤 105 : CategoryServiceImpl 步骤 106 : CategoryController 步骤 107 : editCategory.html 步骤 108 : CategoryController 步骤 109 : 中文问题 步骤 110 : ProductService 步骤 111 : ProductServiceImpl 步骤 112 : 各个版本区别 步骤 113 : 各个版本区别 步骤 114 : 各个版本区别 步骤 115 : 各个版本区别 步骤 116 : 各个版本区别 步骤 117 : 各个版本区别 步骤 118 : 各个版本区别 步骤 119 : 各个版本区别 步骤 120 : 各个版本区别 步骤 121 : 各个版本区别 步骤 122 : 各个版本区别 步骤 123 : 各个版本区别 步骤 124 : 各个版本区别 步骤 125 : 各个版本区别 步骤 126 : 各个版本区别 步骤 127 : 各个版本区别 步骤 128 : 各个版本区别 步骤 129 : 各个版本区别 步骤 130 : 两个进程 步骤 131 : jquery.min.js 步骤 132 : CategoryController.getOneCategory() 步骤 133 : CategoryController.getManyCategory() 步骤 134 : idea 步骤 135 : 购买ECS服务器- 步骤 136 : 其他 步骤 137 : test 步骤 138 : 先看效果再学习 步骤 139 : sts 安装 步骤 140 : 确认 步骤 141 : 确认Licence 步骤 142 : 更多关于JPA 步骤 143 : 学习环境目标对象 步骤 144 : 期望薪资 步骤 145 : 可运行项目 步骤 146 : 先运行,看到效果,再学习 步骤 147 : 模仿和排错 步骤 148 : JobListener 步骤 149 : 可运行项目 步骤 150 : 一些概念 步骤 151 : 原理图 步骤 152 : 思路图 步骤 153 : 不要压缩睡眠时间 步骤 154 : 养成午睡的习惯 步骤 155 : 做事考虑性价比 步骤 156 : 11 步骤 157 : 1212 步骤 158 : fdsf 步骤 159 : MVVM 步骤 160 : 正在撸的教程 步骤 161 : 今年出的教程 步骤 162 : Category 步骤 163 : CategoryDAO 步骤 164 : 测试数据 步骤 165 : ceshi 步骤 166 : 先运行,看到效果,再学习 步骤 167 : 模仿和排错 步骤 168 : 先运行,看到效果,再学习 步骤 169 : 前端 步骤 170 : java 步骤 171 : 框架 步骤 172 : 中间件 步骤 173 : linux 步骤 174 : diy系列 步骤 175 : 其他 步骤 176 : 模仿和排错 步骤 177 : 创建新的虚拟机 步骤 178 : 比较区别 步骤 179 : 运行 Hello-World 步骤 180 : 消息中间件 步骤 181 : m2plugin 步骤 182 : 项目参数 步骤 183 : 创建父项目 步骤 184 : 新建项目 步骤 185 : 分布式和集群 步骤 186 : 出现位置-最近 步骤 187 : 概要 步骤 188 : 厦门 职位1 - Java后端开发,职位2 - 前端开发 步骤 189 : 删除 src 步骤 190 : 拓扑图点亮 步骤 191 : 改造 view 步骤 192 : 对服务链路追踪的影响 步骤 193 : 单体项目 步骤 194 : 修改 server.xml 步骤 195 : 肩颈操 步骤 196 : logback.xml 步骤 197 : 先运行,看到效果,再学习 步骤 198 : 模仿和排错 步骤 199 : Bootstrap 步骤 200 : 课程内容一览 步骤 201 : 怎么学这个项目 步骤 202 : 红色的日志 步骤 203 : 先运行,看到效果,再学习 步骤 204 : 模仿和排错 步骤 205 : 跟着做了,但是跑不起来,运行有问题,怎么办? 步骤 206 : MiniBrowser 步骤 207 : SetSessionServlet 步骤 208 : tomcat 教程进度 步骤 209 : 比较可运行项目,快速定位问题 步骤 210 : 运行演示 步骤 211 : 整个项目的结构体系图 步骤 212 : 12月 步骤 213 : 安装 akshare
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
右上角的可运行项目在 Eclipse 里运行是没有问题的,但是在 idea 中运行可能会失败. 原因是 idea 的 bug, 它不能在运行的时候使用 标记为 <scope>provided</scope> 的 jar 包。
解决办法是如果 idea 运行失败 (新版本 idea 也许就没有这个 bug了), 请删除掉 pom.xml 里面的所有 <scope>provided</scope>,然后再运行,谢谢
图床
至少使用JDK8版本,请下载JDK8或者更高版本: 下载以及配置JDK环境
图床
如图所示,点亮了新的节点,整个项目正在逐渐展开。 通过点亮的位置,就知道现在项目进展到哪里了,还剩下多少没做,这样学习思路越来越清晰
如图所示,点亮了新的节点,整个项目正在逐渐展开。 通过点亮的位置,就知道现在项目进展到哪里了,还剩下多少没做,这样学习思路越来越清晰
如图所示,点亮了新的节点,整个项目正在逐渐展开。 通过点亮的位置,就知道现在项目进展到哪里了,还剩下多少没做,这样学习思路越来越清晰
专门用于回收的step,id是3069,不可删除
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
</head>
@style@
<body>
<div class="topdiv">
<img style="margin-right:5px" src="https://how2j.cn/study/practise/3226/1.png">
<span class="bold">最新动态</span>
<span class="floatright" >设置</span>
<img style="margin-right:5px" class="floatright" src="https://how2j.cn/study/practise/3226/2.png">
</div>
<div id="left" class="floatleft" style="margin-right:15px">
<img src="https://how2j.cn/study/practise/3226/4.png"/> <br>
<br>
<span style="background-image:url(5.png); padding:5px">6551</span>
</div>
<div id="right" class="floatleft show1">
<div style="margin-bottom:5px">
<span>热门回答,来自 机械</span>
<a href="#">关注话题</a>
<img src="https://how2j.cn/study/practise/3226/3.png" class="floatright">
</div>
<a class="bold">人类史上令人叹为观止的极限精度制造成果有哪些?</a>
<p class="text"><strong>Vincent Fu</strong>, Materials Science, PhD</p>
<img class="floatleft" src="https://how2j.cn/study/practise/3226/6.png"/>
<div class="floatleft text" style="line-height:170%;margin-left:15px;width:367px"">
说到精度,就不得不提在材料学中最重要的一个方面:表征。要项研究一种材料性能,握在手里把玩时远远不够的,就算你拿出放大镜离近了看,也只能看到表面的一些坑坑洼洼,而为了知晓一种材料的纤维结构,科学家至少要下到纳米级(放大千倍),如果要获得更深...
<a href="">显示全部 </a>
<br>
</div>
<div id="thirdDiv">
<img src="https://how2j.cn/study/practise/3226/7.png">
<span>关注问题</span>
<img src="https://how2j.cn/study/practise/3226/8.png">
<span>867条评论</span>
<img src="https://how2j.cn/study/practise/3226/9.png">
<span>作者保留权利</span>
</div>
</div>
<div class="clearLeft" >
</div>
<div id="bottom" style="margin-top:20px;border-top-style:solid;border-top-width:1px;border-top-color:#ddd">
</div>
</body>
</html>
step2 step2 step2
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
新增Page这个类专门为分页提供必要信息
属性: int start; 开始位置 int count; 每页显示的数量 int total; 总共有多少条数据 String param; 参数(这个属性在后续有用到,但是分类的分页查询里并没有用到,请忽略) 方法: getTotalPage 根据 每页显示的数量count以及总共有多少条数据total,计算出总共有多少页 getLast 计算出最后一页的数值是多少 isHasPreviouse 判断是否有前一页 isHasNext 判断是否有后一页 package com.how2java.tmall.util;
public class Page {
private int start; //开始页数
private int count; //每页显示个数
private int total; //总个数
private String param; //参数
private static final int defaultCount = 5; //默认每页显示5条
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Page (){
count = defaultCount;
}
public Page(int start, int count) {
this();
this.start = start;
this.count = count;
}
public boolean isHasPreviouse(){
if(start==0)
return false;
return true;
}
public boolean isHasNext(){
if(start==getLast())
return false;
return true;
}
public int getTotalPage(){
int totalPage;
// 假设总数是50,是能够被5整除的,那么就有10页
if (0 == total % count)
totalPage = total /count;
// 假设总数是51,不能够被5整除的,那么就有11页
else
totalPage = total / count + 1;
if(0==totalPage)
totalPage = 1;
return totalPage;
}
public int getLast(){
int last;
// 假设总数是50,是能够被5整除的,那么最后一页的开始就是45
if (0 == total % count)
last = total - count;
// 假设总数是51,不能够被5整除的,那么最后一页的开始就是50
else
last = total - total % count;
last = last<0?0:last;
return last;
}
@Override
public String toString() {
return "Page [start=" + start + ", count=" + count + ", total=" + total + ", getStart()=" + getStart()
+ ", getCount()=" + getCount() + ", isHasPreviouse()=" + isHasPreviouse() + ", isHasNext()="
+ isHasNext() + ", getTotalPage()=" + getTotalPage() + ", getLast()=" + getLast() + "]";
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
<script>
$(function(){
$("#addForm").submit(function(){
if(!checkEmpty("name","分类名称"))
return false;
if(!checkEmpty("categoryPic","分类图片"))
return false;
return true;
});
});
</script>
<script> $(function(){ $("#addForm").submit(function(){ if(!checkEmpty("name","分类名称")) return false; if(!checkEmpty("categoryPic","分类图片")) return false; return true; }); }); </script>
编辑页面提交数据到admin_category_update
<form method="post" id="editForm" action="admin_category_update" enctype="multipart/form-data"> 1. method="post" 用于提交中文 2. enctype="multipart/form-data" 用于提交二进制文件
新增ProductServiceImpl ,提供CRUD一套。 值得一提的是, get和list方法都会把取出来的Product对象设置上对应的category
package com.how2java.tmall.service.impl;
import com.how2java.tmall.mapper.ProductMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.pojo.Product;
import com.how2java.tmall.pojo.ProductExample;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
ProductMapper productMapper;
@Autowired
CategoryService categoryService;
@Override
public void add(Product p) {
productMapper.insert(p);
}
@Override
public void delete(int id) {
productMapper.deleteByPrimaryKey(id);
}
@Override
public void update(Product p) {
productMapper.updateByPrimaryKeySelective(p);
}
@Override
public Product get(int id) {
Product p = productMapper.selectByPrimaryKey(id);
setCategory(p);
return p;
}
public void setCategory(List<Product> ps){
for (Product p : ps)
setCategory(p);
}
public void setCategory(Product p){
int cid = p.getCid();
Category c = categoryService.get(cid);
p.setCategory(c);
}
@Override
public List list(int cid) {
ProductExample example = new ProductExample();
example.createCriteria().andCidEqualTo(cid);
example.setOrderByClause("id desc");
List result = productMapper.selectByExample(example);
setCategory(result);
return result;
}
}
查询地址admin_product_list映射的是ProductController的list()方法
1. 获取分类 cid,和分页对象page 2. 通过PageHelper设置分页参数 3. 基于cid,获取当前分类下的产品集合 4. 通过PageInfo获取产品总数 5. 把总数设置给分页page对象 6. 拼接字符串"&cid="+c.getId(),设置给page对象的Param值。 因为产品分页都是基于当前分类下的分页,所以分页的时候需要传递这个cid 7. 把产品集合设置到 request的 "ps" 产品上 8. 把分类对象设置到 request的 "c" 产品上。 ( 这个c有什么用呢? 在 其他-面包屑导航 中会用于显示分类名称) 9. 把分页对象设置到 request的 "page" 对象上 10. 服务端跳转到admin/listProduct.html页面 11. 在listProduct.html页面上使用c:forEach 遍历ps集合,并显示
@RequestMapping("admin_product_list")
public String list(int cid, Model model, Page page) {
Category c = categoryService.get(cid);
PageHelper.offsetPage(page.getStart(),page.getCount());
List<Product> ps = productService.list(cid);
int total = (int) new PageInfo<>(ps).getTotal();
page.setTotal(total);
page.setParam("&cid="+c.getId());
model.addAttribute("ps", ps);
model.addAttribute("c", c);
model.addAttribute("page", page);
return "admin/listProduct";
}
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id}</td>
<td>
</td>
<td>${p.name}</td>
<td>${p.subTitle}</td>
<td>${p.originalPrice}</td>
<td>${p.promotePrice}</td>
<td>${p.stock}</td>
<td><a href="admin_productImage_list?pid=${p.id}"><span
class="glyphicon glyphicon-picture"></span></a></td>
<td><a href="admin_product_editPropertyValue?id=${p.id}"><span
class="glyphicon glyphicon-th-list"></span></a></td>
<td><a href="admin_product_edit?id=${p.id}"><span
class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true"
href="admin_product_delete?id=${p.id}"><span
class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
1. 在listProduct.html提交数据的时候,除了提交产品名称,小标题,原价格,优惠价格,库存外还会提交cid
2. 在ProductController中获取Product对象,并插入到数据库 3. 客户端跳转到admin_product_list,并带上参数cid
<form method="post" id="addForm" action="admin_product_add">
<table class="addTable">
<tr>
<td>产品名称</td>
<td><input id="name" name="name" type="text"
class="form-control"></td>
</tr>
<tr>
<td>产品小标题</td>
<td><input id="subTitle" name="subTitle" type="text"
class="form-control"></td>
</tr>
<tr>
<td>原价格</td>
<td><input id="originalPrice" value="99.98" name="originalPrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>优惠价格</td>
<td><input id="promotePrice" value="19.98" name="promotePrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>库存</td>
<td><input id="stock" value="99" name="stock" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="cid" value="${c.id}">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
@RequestMapping("admin_product_add")
public String add(Model model, Product p) {
p.setCreateDate(new Date());
productService.add(p);
return "redirect:admin_product_list?cid="+p.getCid();
}
1. 在ProductController的edit方法中,根据id获取product对象
2. 根据product对象的cid产品获取Category对象,并把其设置在product对象的category产品上 3. 把product对象放在request的 "p" 产品中 3. 服务端跳转到admin/editProduct.html 4. 在editProduct.html中显示产品名称 5. 在editProduct.html中隐式提供id和cid( cid 通过 p.category.id 获取)
@RequestMapping("admin_product_edit")
public String edit(Model model, int id) {
Product p = productService.get(id);
Category c = categoryService.get(p.getCid());
p.setCategory(c);
model.addAttribute("p", p);
return "admin/editProduct";
}
@RequestMapping("admin_product_edit") public String edit(Model model, int id) { Product p = productService.get(id); Category c = categoryService.get(p.getCid()); p.setCategory(c); model.addAttribute("p", p); return "admin/editProduct"; }
<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
<input type="hidden" name="id" value="${p.id}"> <input type="hidden" name="cid" value="${p.category.id}">
1. 在ProductController的update方法中获取Product对象
2. 借助productService更新这个对象到数据库 3. 客户端跳转到admin_product_list,并带上参数cid @RequestMapping("admin_product_update")
public String update(Product p) {
productService.update(p);
return "redirect:admin_product_list?cid="+p.getCid();
}
@RequestMapping("admin_product_update") public String update(Product p) { productService.update(p); return "redirect:admin_product_list?cid="+p.getCid(); }
1. 在ProductController的delete方法中获取id
2. 根据id获取Product对象 3. 借助productService删除这个对象对应的数据 4. 客户端跳转到admin_product_list,并带上参数cid @RequestMapping("admin_product_delete")
public String delete(int id) {
Product p = productService.get(id);
productService.delete(id);
return "redirect:admin_product_list?cid="+p.getCid();
}
@RequestMapping("admin_product_delete") public String delete(int id) { Product p = productService.get(id); productService.delete(id); return "redirect:admin_product_list?cid="+p.getCid(); }
这里的分页比起分类管理中的分页多了一个参数cid
1. 在PropertyController.list() 方法中,把&cid= 参数设置到在page对象的param属性上 page.setParam("&cid="+c.getId()); 2. 在adminPage.html页面中通过${page.param}取出这个参数 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<script>
$(function(){
$("ul.pagination li.disabled a").click(function(){
return false;
});
});
</script>
<nav>
<ul class="pagination">
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=0${page.param}" aria-label="Previous" >
<span aria-hidden="true">«</span>
</a>
</li>
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=${page.start-page.count}${page.param}" aria-label="Previous" >
<span aria-hidden="true">‹</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
<a
href="?page.start=${status.index*page.count}${page.param}"
<c:if test="${status.index*page.count==page.start}">class="current"</c:if>
>${status.count}</a>
</li>
</c:forEach>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.start+page.count}${page.param}" aria-label="Next">
<span aria-hidden="true">›</span>
</a>
</li>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.last}${page.param}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
增加ReviewServiceImpl,实现对应方法
package com.how2java.tmall.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.how2java.tmall.mapper.ReviewMapper;
import com.how2java.tmall.pojo.Review;
import com.how2java.tmall.pojo.ReviewExample;
import com.how2java.tmall.pojo.User;
import com.how2java.tmall.service.ReviewService;
import com.how2java.tmall.service.UserService;
@Service
public class ReviewServiceImpl implements ReviewService {
@Autowired
ReviewMapper reviewMapper;
@Autowired
UserService userService;
@Override
public void add(Review c) {
reviewMapper.insert(c);
}
@Override
public void delete(int id) {
reviewMapper.deleteByPrimaryKey(id);
}
@Override
public void update(Review c) {
reviewMapper.updateByPrimaryKeySelective(c);
}
@Override
public Review get(int id) {
return reviewMapper.selectByPrimaryKey(id);
}
public List<Review> list(int pid){
ReviewExample example =new ReviewExample();
example.createCriteria().andPidEqualTo(pid);
example.setOrderByClause("id desc");
List<Review> result =reviewMapper.selectByExample(example);
setUser(result);
return result;
}
public void setUser(List<Review> reviews){
for (Review review : reviews) {
setUser(review);
}
}
private void setUser(Review review) {
int uid = review.getUid();
User user =userService.get(uid);
review.setUser(user);
}
@Override
public int getCount(int pid) {
return list(pid).size();
}
}
修改ProductService,增加为产品设置销量和评价数量的方法:
void setSaleAndReviewNumber(Product p); void setSaleAndReviewNumber(List<Product> ps); package com.how2java.tmall.service;
import java.util.List;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.pojo.Product;
public interface ProductService {
void add(Product p);
void delete(int id);
void update(Product p);
Product get(int id);
List list(int cid);
void setFirstProductImage(Product p);
void fill(List<Category> cs);
void fill(Category c);
void fillByRow(List<Category> cs);
void setSaleAndReviewNumber(Product p);
void setSaleAndReviewNumber(List<Product> ps);
}
在最后增加事务管理配置:
<!--事务管理--> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> 因为增加订单行为需要同时修改两个表 1. 为Order表新增数据 2. 修改OrderItem表 所以需要进行事务管理,否则当新增了Order表的数据,还没有来得及修改OrderItem的时候出问题,比如突然断电,那么OrderItem的数据就会是脏数据了(没有指向正确的Order表数据)。 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.how2java.tmall.service" />
<!-- 导入数据库配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />
</bean>
<!--Mybatis的SessionFactory配置-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="com.how2java.tmall.pojo" />
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
</value>
</property>
</bean>
</array>
</property>
</bean>
<!--Mybatis的Mapper文件识别-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.how2java.tmall.mapper"/>
</bean>
<!--事务管理-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
实现add(Order o, List<OrderItem> ois)方法,该方法通过注解进行事务管理
@Transactional(propagation= Propagation.REQUIRED,rollbackForClassName="Exception") 41-42行代码用来模拟当增加订单后出现异常,观察事务管理是否预期发生。(需要把false修改为true才能观察到) if(false) throw new RuntimeException(); package com.how2java.tmall.service.impl;
import java.util.List;
import com.how2java.tmall.pojo.OrderItem;
import com.how2java.tmall.service.OrderItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.how2java.tmall.mapper.OrderMapper;
import com.how2java.tmall.pojo.Order;
import com.how2java.tmall.pojo.OrderExample;
import com.how2java.tmall.pojo.User;
import com.how2java.tmall.service.OrderService;
import com.how2java.tmall.service.UserService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderService implements OrderService {
@Autowired
OrderMapper orderMapper;
@Autowired
UserService userService;
@Autowired
OrderItemService orderItemService;
@Override
public void add(Order c) {
orderMapper.insert(c);
}
@Override
@Transactional(propagation= Propagation.REQUIRED,rollbackForClassName="Exception")
public float add(Order o, List<OrderItem> ois) {
float total = 0;
add(o);
if(false)
throw new RuntimeException();
for (OrderItem oi: ois) {
oi.setOid(o.getId());
orderItemService.update(oi);
total+=oi.getProduct().getPromotePrice()*oi.getNumber();
}
return total;
}
@Override
public void delete(int id) {
orderMapper.deleteByPrimaryKey(id);
}
@Override
public void update(Order c) {
orderMapper.updateByPrimaryKeySelective(c);
}
@Override
public Order get(int id) {
return orderMapper.selectByPrimaryKey(id);
}
public List<Order> list(){
OrderExample example =new OrderExample();
example.setOrderByClause("id desc");
return orderMapper.selectByExample(example);
}
}
在上一步modal.html中,点击了登录按钮之后,访问路径/foreloginAjax,导致ForeRESTController.loginAjax()方法被调用
1. 获取账号密码 2. 通过账号密码获取User对象 2.1 如果User对象为空,那么就返回"fail"字符串。 2.2 如果User对象不为空,那么就把User对象放在session中,并返回"success" 字符串
@RequestMapping("foreloginAjax")
@ResponseBody
public String loginAjax(@RequestParam("name") String name, @RequestParam("password") String password,HttpSession session) {
name = HtmlUtils.htmlEscape(name);
User user = userService.get(name,password);
if(null==user){
return "fail";
}
session.setAttribute("user", user);
return "success";
}
}
package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.*;
import com.how2java.tmall.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.util.HtmlUtils;
import javax.servlet.http.HttpSession;
import java.util.List;
@Controller
@RequestMapping("")
public class ForeRESTController {
@Autowired
CategoryService categoryService;
@Autowired
ProductService productService;
@Autowired
UserService userService;
@Autowired
ProductImageService productImageService;
@Autowired
PropertyValueService propertyValueService;
@Autowired
OrderService orderService;
@Autowired
OrderItemService orderItemService;
@Autowired
ReviewService reviewService;
@RequestMapping("home")
public String home(Model model) {
List<Category> cs= categoryService.list();
productService.fill(cs);
productService.fillByRow(cs);
model.addAttribute("cs", cs);
return "fore/home";
}
@RequestMapping("foreregister")
public String register(Model model,User user) {
String name = user.getName();
name = HtmlUtils.htmlEscape(name);
user.setName(name);
boolean exist = userService.isExist(name);
if(exist){
String m ="用户名已经被使用,不能使用";
model.addAttribute("msg", m);
return "fore/register";
}
userService.add(user);
return "redirect:registerSuccessPage";
}
@RequestMapping("forelogin")
public String login(@RequestParam("name") String name, @RequestParam("password") String password, Model model, HttpSession session) {
name = HtmlUtils.htmlEscape(name);
User user = userService.get(name,password);
if(null==user){
model.addAttribute("msg", "账号密码错误");
return "fore/login";
}
session.setAttribute("user", user);
return "redirect:home";
}
@RequestMapping("forelogout")
public String logout( HttpSession session) {
session.removeAttribute("user");
return "redirect:home";
}
@RequestMapping("foreproduct")
public String product( int pid, Model model) {
Product p = productService.get(pid);
List<ProductImage> productSingleImages = productImageService.list(p.getId(), ProductImageService.type_single);
List<ProductImage> productDetailImages = productImageService.list(p.getId(), ProductImageService.type_detail);
p.setProductSingleImages(productSingleImages);
p.setProductDetailImages(productDetailImages);
List<PropertyValue> pvs = propertyValueService.list(p.getId());
List<Review> reviews = reviewService.list(p.getId());
productService.setSaleAndReviewNumber(p);
model.addAttribute("reviews", reviews);
model.addAttribute("p", p);
model.addAttribute("pvs", pvs);
return "fore/product";
}
@RequestMapping("forecheckLogin")
@ResponseBody
public String checkLogin( HttpSession session) {
User user =(User) session.getAttribute("user");
if(null!=user)
return "success";
return "fail";
}
@RequestMapping("foreloginAjax")
@ResponseBody
public String loginAjax(@RequestParam("name") String name, @RequestParam("password") String password,HttpSession session) {
name = HtmlUtils.htmlEscape(name);
User user = userService.get(name,password);
if(null==user){
return "fail";
}
session.setAttribute("user", user);
return "success";
}
}
修改ProductServiceImpl实现search方法,通过关键字进行模糊查询
package com.how2java.tmall.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.how2java.tmall.mapper.ProductMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.pojo.Product;
import com.how2java.tmall.pojo.ProductExample;
import com.how2java.tmall.pojo.ProductImage;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.service.OrderItemService;
import com.how2java.tmall.service.ProductImageService;
import com.how2java.tmall.service.ProductService;
import com.how2java.tmall.service.ReviewService;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
ProductMapper productMapper;
@Autowired
CategoryService categoryService;
@Autowired
ProductImageService productImageService;
@Autowired
OrderItemService orderItemService;
@Autowired
ReviewService reviewService;
@Override
public void add(Product p) {
productMapper.insert(p);
}
@Override
public void delete(int id) {
productMapper.deleteByPrimaryKey(id);
}
@Override
public void update(Product p) {
productMapper.updateByPrimaryKeySelective(p);
}
@Override
public Product get(int id) {
Product p = productMapper.selectByPrimaryKey(id);
setFirstProductImage(p);
setCategory(p);
return p;
}
public void setCategory(List<Product> ps){
for (Product p : ps)
setCategory(p);
}
public void setCategory(Product p){
int cid = p.getCid();
Category c = categoryService.get(cid);
p.setCategory(c);
}
@Override
public List list(int cid) {
ProductExample example = new ProductExample();
example.createCriteria().andCidEqualTo(cid);
example.setOrderByClause("id desc");
List result = productMapper.selectByExample(example);
setFirstProductImage(result);
setCategory(result);
return result;
}
@Override
public void setFirstProductImage(Product p) {
List<ProductImage> pis = productImageService.list(p.getId(), ProductImageService.type_single);
if (!pis.isEmpty()) {
ProductImage pi = pis.get(0);
p.setFirstProductImage(pi);
}
}
@Override
public void fill(List<Category> cs) {
for (Category c : cs) {
fill(c);
}
}
@Override
public void fillByRow(List<Category> cs) {
int productNumberEachRow = 8;
for (Category c : cs) {
List<Product> products = c.getProducts();
List<List<Product>> productsByRow = new ArrayList<>();
for (int i = 0; i < products.size(); i+=productNumberEachRow) {
int size = i+productNumberEachRow;
size= size>products.size()?products.size():size;
List<Product> productsOfEachRow =products.subList(i, size);
productsByRow.add(productsOfEachRow);
}
c.setProductsByRow(productsByRow);
}
}
@Override
public void setSaleAndReviewNumber(Product p) {
int saleCount = orderItemService.getSaleCount(p.getId());
p.setSaleCount(saleCount);
int reviewCount = reviewService.getCount(p.getId());
p.setReviewCount(reviewCount);
}
@Override
public void setSaleAndReviewNumber(List<Product> ps) {
for (Product p : ps) {
setSaleAndReviewNumber(p);
}
}
@Override
public List<Product> search(String keyword) {
ProductExample example = new ProductExample();
example.createCriteria().andNameLike("%" + keyword + "%");
example.setOrderByClause("id desc");
List result = productMapper.selectByExample(example);
setFirstProductImage(result);
setCategory(result);
return result;
}
@Override
public void fill(Category c) {
List<Product> ps = list(c.getId());
c.setProducts(ps);
}
public void setFirstProductImage(List<Product> ps) {
for (Product p : ps) {
setFirstProductImage(p);
}
}
}
searchResultPage.html 本身没做什么。。。。 直接包含了 productsBySearch.html
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<div id="searchResult">
<div class="searchResultDiv">
<%@include file="productsBySearch.html"%>
</div>
</div>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <div id="searchResult"> <div class="searchResultDiv"> <%@include file="productsBySearch.html"%> </div> </div>
除了图片资源外,还用到了各种第三方的jar包
响应式布局系统讲解
css3 vue.js anulgar.js react.js 前端部分更全面的练习和答案
ForeController的内容比较多,而且还需要对现存的各种Service类进行改进才可以使用,这里就暂时不列出代码,而是在所有前台功能开发完毕之后,对其所有方法做了一个截图,供大家一览
无需改动,点击Finish即可
每次新建Maven项目,或者pom.xml有改动,都会有这个提示,这次点击Enable Auto-Import,自动导入,省掉麻烦。
maven web项目默认是没有java源代码目录的,所以需要手动创建,并设置其为源代码目录
右键main目录-> New->Directory->输入java->右键java->Mark Directory as-> Sources Root 这样就创建了存放java源文件的目录了
首先点中源目录:java 然后菜单->File->New->Package 输入 com.how2java.tmall.pojo 创建包
包创建好之后如图所示 package com.how2java.tmall.pojo;
public class Category {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
}
首先点中源目录:java 然后菜单->File->New->Package 输入 com.how2java.tmall.mapper 创建包
接着创建类CategoryMapper,因为本知识点只做查询,所以只声明了一个list方法。 package com.how2java.tmall.mapper;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryMapper {
List<Category> list();
}
package com.how2java.tmall.mapper; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryMapper { List<Category> list(); }
首先点中源目录:java 然后菜单->File->New->Package 输入 com.how2java.tmall.service 创建包
接着创建接口CategoryService,因为本知识点只做查询,所以只声明了一个list方法。 package com.how2java.tmall.service;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryService{
List<Category> list();
}
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryService{ List<Category> list(); }
首先点中源目录:java 然后菜单->File->New->Package 输入 com.how2java.tmall.service.impl 创建包
新建CategoryService接口的实现类CategoryServiceImpl 注解@Service声明当前类是一个Service类 通过自动装配@Autowired引入CategoryMapper ,在list方法中调用CategoryMapper 的list方法. 有时候 categoryMapper 会出现红色的下划线,原因不是代码出错了,而是idea的bug. 解决办法请看: idea 无法正确识别autowired package com.how2java.tmall.service.impl;
import com.how2java.tmall.mapper.CategoryMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
public List<Category> list(){
return categoryMapper.list();
};
}
package com.how2java.tmall.service.impl; import com.how2java.tmall.mapper.CategoryMapper; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.service.CategoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class CategoryServiceImpl implements CategoryService { @Autowired CategoryMapper categoryMapper; public List<Category> list(){ return categoryMapper.list(); }; }
首先点中源目录:java 然后菜单->File->New->Package 输入 com.how2java.tmall.controller 创建包
新建CategoryController, 注解@Controller声明当前类是一个控制器 注解@RequestMapping("")表示访问的时候无需额外的地址 注解@Autowired把CategoryServiceImpl自动装配进了CategoryService 接口 注解@RequestMapping("admin_category_list") 映射admin_category_list路径的访问 在list方法中,通过categoryService.list()获取所有的Category对象,然后放在"cs"中,并服务端跳转到 “admin/listCategory” 视图。 “admin/listCategory” 会根据后续的springMVC.xml 配置文件,跳转到 WEB-INF/jsp/admin/listCategory.html 文件 package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model){
List<Category> cs= categoryService.list();
model.addAttribute("cs", cs);
return "admin/listCategory";
}
}
1. 在resources目录下,新建mapper目录
2. 右键mapper目录->New->File 新建文件CategoryMapper.xml CategoryMapper.xml的namespace必须是com.how2java.tmall.mapper.CategoryMapper,以和CategoryMapper保持一致。 CategoryMapper.xml声明了唯一的一条sql语句: select * from category order by id desc <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.how2java.tmall.mapper.CategoryMapper"> <select id="list" resultType="Category"> select * from category order by id desc </select> </mapper>
在resources目录下新建log4j.properties。如图所示这个配置文件的作用是开启日志,当访问页面的时候,查看mybatis运行的情况,执行了什么SQL语句,以及sql语句的返回情况等信息。
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.how2java.tmall=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... log4j.logger.com.how2java.tmall=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
在resources目录下新建jdbc.properties,此配置文件给出了访问数据库需要的必须信息:
1. 驱动 2. url 3. 账号 4. 密码 #数据库配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tmall_springboot?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=admin
#数据库配置文件 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/tmall_springboot?useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=admin
在resources目录下新建applicationContext.xml
此配置文件做了如下工作 1. 启动对注解的识别 <context:annotation-config /> <context:component-scan base-package="com.how2java.tmall.service" /> 2. 指定对jdbc.properties的引用 <context:property-placeholder location="classpath:jdbc.properties"/> 3. 配置数据源 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 4. 配置Mybatis的SessionFactory,其中声明了别名,并且使用前面配置的数据源,扫描CategoryMapper.xml配置文件 <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> 5. 扫描Mapper类: CategoryMapper <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.how2java.tmall.service" />
<!-- 导入数据库配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />
</bean>
<!--Mybatis的SessionFactory配置-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="com.how2java.tmall.pojo" />
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<!--分页插件,目前先注释,后面重构的时候才会使用
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
</value>
</property>
</bean>
</array>
</property>
-->
</bean>
<!--Mybatis的Mapper文件识别-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.how2java.tmall.mapper"/>
</bean>
</beans>
在resources目录下新建springMVC.xml
1. 开启注解的识别 <context:annotation-config/> <context:component-scan base-package="com.how2java.tmall.controller"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <mvc:annotation-driven /> 2.开通静态资源的访问,否则访问图片,css,js等文件可能出错 <mvc:default-servlet-handler /> 3. 视图定位 视图定位到/WEB-INF/HTML/*.html这里 4. 对上传文件的解析 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!--启动注解识别-->
<context:annotation-config/>
<context:component-scan base-package="com.how2java.tmall.controller">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<mvc:annotation-driven />
<!--开通静态资源的访问-->
<mvc:default-servlet-handler />
<!-- 视图定位 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".html" />
</bean>
<!-- 对上传文件的解析-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
</beans>
修改web.xml,主要提供如下功能
1. 指定spring的配置文件为classpath下的applicationContext.xml 2. 设置中文过滤器 3. 指定spring mvc配置文件为classpath下的springMVC.xml <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- spring的配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--中文过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- spring mvc核心:分发servlet -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- spring mvc的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
通过静态资源步骤,就会在WEB-INF下创建jsp目录。 然后在jsp目录中创建admin目录,接着创建listCategory.html文件
listCategory.html主要作用是通过43行的forEach标签遍历"cs"里的内容,然后挨个显示出来 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.html"%>
<%@include file="../include/admin/adminNavigator.html"%>
<script>
$(function(){
$("#addForm").submit(function(){
if(!checkEmpty("name","分类名称"))
return false;
if(!checkEmpty("categoryPic","分类图片"))
return false;
return true;
});
});
</script>
<title>分类管理</title>
<div class="workingArea">
<h1 class="label label-info" >分类管理</h1>
<br>
<br>
<div class="listDataTableDiv">
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr class="success">
<th>ID</th>
<th>图片</th>
<th>分类名称</th>
<th>属性管理</th>
<th>产品管理</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
<c:forEach items="${cs}" var="c">
<tr>
<td>${c.id}</td>
<td><img height="40px" src="img/category/${c.id}.jpg"></td>
<td>${c.name}</td>
<td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td>
<td><a href="admin_product_list?cid=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td>
<td><a href="admin_category_edit?id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="pageDiv">
<%//@include file="../include/admin/adminPage.html" %>
</div>
<div class="panel panel-warning addDiv">
<div class="panel-heading">新增分类</div>
<div class="panel-body">
<form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data">
<table class="addTable">
<tr>
<td>分类名称</td>
<td><input id="name" name="name" type="text" class="form-control"></td>
</tr>
<tr>
<td>分类圖片</td>
<td>
<input id="categoryPic" accept="image/*" type="file" name="image" />
</td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<%@include file="../include/admin/adminFooter.html"%>
点击绿色按钮,启动Tomcat
修改CategoryMapper.xml,以提供带分页的查询语句和获取总数的sql语句
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<select id="total" resultType="int">
select count(*) from category
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.how2java.tmall.mapper.CategoryMapper"> <select id="list" resultType="Category"> select * from category order by id desc <if test="start!=null and count!=null"> limit #{start},#{count} </if> </select> <select id="total" resultType="int"> select count(*) from category </select> </mapper>
修改CategoryMapper,提供一个支持分页的查询方法list(Page page)和获取总数的方法total
package com.how2java.tmall.mapper;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryMapper {
public List<Category> list(Page page);
public int total();
}
package com.how2java.tmall.mapper; import com.how2java.tmall.util.Page; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryMapper { public List<Category> list(Page page); public int total(); }
修改CategoryService,提供一个支持分页的查询方法list(Page page)和获取总数的方法total
package com.how2java.tmall.service;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.util.Page;
import java.util.List;
public interface CategoryService{
int total();
List<Category> list(Page page);
}
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.util.Page; import java.util.List; public interface CategoryService{ int total(); List<Category> list(Page page); }
修改CategoryServiceImpl,提供一个支持分页的查询方法list(Page page)和获取总数的方法total。
package com.how2java.tmall.service.impl;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.mapper.CategoryMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list(Page page) {
return categoryMapper.list(page);
}
@Override
public int total() {
return categoryMapper.total();
}
}
修改CategoryController
1. 为方法list增加参数Page用于获取浏览器传递过来的分页信息 2. categoryService.list(page); 获取当前页的分类集合 3. 通过categoryService.total(); 获取分类总数 4. 通过page.setTotal(total); 为分页对象设置总数 5. 把分类集合放在"cs"中 6. 把分页对象放在 "page“ 中 7. 跳转到listCategory.html页面 package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.util.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page){
List<Category> cs= categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
}
本来注释掉的62行,去掉注释
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.html"%>
<%@include file="../include/admin/adminNavigator.html"%>
<script>
$(function(){
$("#addForm").submit(function(){
if(!checkEmpty("name","分类名称"))
return false;
if(!checkEmpty("categoryPic","分类图片"))
return false;
return true;
});
});
</script>
<title>分类管理</title>
<div class="workingArea">
<h1 class="label label-info" >分类管理</h1>
<br>
<br>
<div class="listDataTableDiv">
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr class="success">
<th>ID</th>
<th>图片</th>
<th>分类名称</th>
<th>属性管理</th>
<th>产品管理</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
<c:forEach items="${cs}" var="c">
<tr>
<td>${c.id}</td>
<td><img height="40px" src="img/category/${c.id}.jpg"></td>
<td>${c.name}</td>
<td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td>
<td><a href="admin_product_list?cid=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td>
<td><a href="admin_category_edit?id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="pageDiv">
<%@include file="../include/admin/adminPage.html" %>
</div>
<div class="panel panel-warning addDiv">
<div class="panel-heading">新增分类</div>
<div class="panel-body">
<form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data">
<table class="addTable">
<tr>
<td>分类名称</td>
<td><input id="name" name="name" type="text" class="form-control"></td>
</tr>
<tr>
<td>分类圖片</td>
<td>
<input id="categoryPic" accept="image/*" type="file" name="image" />
</td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<%@include file="../include/admin/adminFooter.html"%>
在listCategory.html页面包含了分页专用jsp:adminPage.html
在其中,依据page对象,进行分页超链元素的显示 完整版的adminPage.html 比较复杂,为了便于大家理解,我先把完整版的adminPage.html简化一下 首先,分页超链的效果,用的Bootstrap的分页效果来制作 首页超链: <li> <a href="?start=0" aria-label="Previous" > <span aria-hidden="true">«</span> </a> </li> 上一页超链: <li > <a href="?start=${page.start-page.count}" aria-label="Previous" > <span aria-hidden="true">‹</span> </a> </li> 下一页超链: <li > <a href="?start=${page.start+page.count}" aria-label="Next"> <span aria-hidden="true">›</span> </a> </li> 最后一页 <li > <a href="?start=${page.last}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> 中间页 <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status"> <li> <a href="?start=${status.index*page.count}" class="current">${status.count}</a> </li> </c:forEach> <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<script>
$(function(){
$("ul.pagination li.disabled a").click(function(){
return false;
});
});
</script>
<nav>
<ul class="pagination">
<li>
<a href="?start=0" aria-label="Previous" >
<span aria-hidden="true">«</span>
</a>
</li>
<li >
<a href="?start=${page.start-page.count}" aria-label="Previous" >
<span aria-hidden="true">‹</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<li>
<a href="?start=${status.index*page.count}" class="current">${status.count}</a>
</li>
</c:forEach>
<li >
<a href="?start=${page.start+page.count}" aria-label="Next">
<span aria-hidden="true">›</span>
</a>
</li>
<li >
<a href="?start=${page.last}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
简化的adminPage.html 用于帮助大家理解,其存在的问题是,即便是没有下一页的数据了,下一页超链也可以点击,点出来的页面是空白的。(首页,上一页,下一页和最后一页都存在这个问题)
那么所谓的完整版的adminPage.html,就是对这些边界进行了处理。当没有下一页的时候,对应超链处于不可点击状态。 比如首页: 当page.hasPreviouse为false的时候,为首页连接套用Bootstrap样式 disabled <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>> <a href="?page.start=0${page.param}" aria-label="Previous" > <span aria-hidden="true">«</span> </a> </li> 注: hasPreviouse会的导致isHasPreviouse()方法被调用,请参考EL表达式获取JavaBean的属性 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<script>
$(function(){
$("ul.pagination li.disabled a").click(function(){
return false;
});
});
</script>
<nav>
<ul class="pagination">
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?start=0${page.param}" aria-label="Previous" >
<span aria-hidden="true">«</span>
</a>
</li>
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?start=${page.start-page.count}${page.param}" aria-label="Previous" >
<span aria-hidden="true">‹</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
<a
href="?start=${status.index*page.count}${page.param}"
<c:if test="${status.index*page.count==page.start}">class="current"</c:if>
>${status.count}</a>
</li>
</c:forEach>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?start=${page.start+page.count}${page.param}" aria-label="Next">
<span aria-hidden="true">›</span>
</a>
</li>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?start=${page.last}${page.param}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
在CategoryMapper.xml中新增加 插入分类的SQL语句
注: 需要加上2个属性:keyProperty="id" useGeneratedKeys="true" 以确保Category对象通过mybatis增加到数据库之后得到的id增长值会被设置在Category对象上。 因为在保存分类图片的时候需要用到这个id值,所以这一步是必须的。 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<select id="total" resultType="int">
select count(*) from category
</select>
<insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" >
insert into category ( name ) values (#{name})
</insert>
</mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.how2java.tmall.mapper.CategoryMapper"> <select id="list" resultType="Category"> select * from category order by id desc <if test="start!=null and count!=null"> limit #{start},#{count} </if> </select> <select id="total" resultType="int"> select count(*) from category </select> <insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" > insert into category ( name ) values (#{name}) </insert> </mapper>
新增add方法
package com.how2java.tmall.mapper;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryMapper {
List<Category> list(Page page);
int total();
void add(Category category);
}
package com.how2java.tmall.mapper; import com.how2java.tmall.util.Page; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryMapper { List<Category> list(Page page); int total(); void add(Category category); }
新增add方法
package com.how2java.tmall.service;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.util.Page;
import java.util.List;
public interface CategoryService{
int total();
List<Category> list(Page page);
void add(Category category);
}
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.util.Page; import java.util.List; public interface CategoryService{ int total(); List<Category> list(Page page); void add(Category category); }
新增add方法的实现
package com.how2java.tmall.service.impl;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.mapper.CategoryMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list(Page page) {
return categoryMapper.list(page);
}
@Override
public int total() {
return categoryMapper.total();
}
@Override
public void add(Category category) {
categoryMapper.add(category);
}
}
新增UploadedImageFile ,其中有一个MultipartFile 类型的属性,用于接受上传文件的注入。
注: 这里的属性名称image必须和页面中的增加分类部分中的type="file"的name值保持一致。 <input id="categoryPic" accept="image/*" type="file" name="image" /> package com.how2java.tmall.util;
import org.springframework.web.multipart.MultipartFile;
public class UploadedImageFile {
MultipartFile image;
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
package com.how2java.tmall.util; import org.springframework.web.multipart.MultipartFile; public class UploadedImageFile { MultipartFile image; public MultipartFile getImage() { return image; } public void setImage(MultipartFile image) { this.image = image; } }
用于删除的超链,指向地址admin_category_delete,并且会传递当前分类对象的id过去。
<a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a>
在adminHeader.html 中对所有的删除连接都进行了监听:
$(function(){
$("a").click(function(){
var deleteLink = $(this).attr("deleteLink");
console.log(deleteLink);
if("true"==deleteLink){
var confirmDelete = confirm("确认要删除");
if(confirmDelete)
return true;
return false;
}
});
})
$(function(){ $("a").click(function(){ var deleteLink = $(this).attr("deleteLink"); console.log(deleteLink); if("true"==deleteLink){ var confirmDelete = confirm("确认要删除"); if(confirmDelete) return true; return false; } }); })
增加删除sql语句
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<select id="total" resultType="int">
select count(*) from category
</select>
<insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" >
insert into category ( name ) values (#{name})
</insert>
<delete id="delete">
delete from category where id= #{id}
</delete>
</mapper>
增加删除方法
package com.how2java.tmall.mapper;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryMapper {
List<Category> list(Page page);
int total();
void add(Category category);
void delete(int id);
}
package com.how2java.tmall.mapper; import com.how2java.tmall.util.Page; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryMapper { List<Category> list(Page page); int total(); void add(Category category); void delete(int id); }
增加删除方法
package com.how2java.tmall.service;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.util.Page;
import java.util.List;
public interface CategoryService{
int total();
List<Category> list(Page page);
void add(Category category);
void delete(int id);
}
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.util.Page; import java.util.List; public interface CategoryService{ int total(); List<Category> list(Page page); void add(Category category); void delete(int id); }
增加删除方法
package com.how2java.tmall.service.impl;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.mapper.CategoryMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list(Page page) {
return categoryMapper.list(page);
}
@Override
public int total() {
return categoryMapper.total();
}
@Override
public void add(Category category) {
categoryMapper.add(category);
}
@Override
public void delete(int id) {
categoryMapper.delete(id);
}
}
增加删除方法
1. 映射路径admin_category_delete 2. 提供参数接受id注入 3. 提供session参数,用于后续定位文件位置 3. 通过categoryService删除数据 4. 通过session获取ControllerContext然后获取分类图片位置,接着删除分类图片 5. 客户端跳转到 admin_category_list
@RequestMapping("admin_category_delete")
public String delete(int id,HttpSession session) throws IOException {
categoryService.delete(id);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,id+".jpg");
file.delete();
return "redirect:/admin_category_list";
}
package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.util.ImageUtil;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.util.UploadedImageFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page){
List<Category> cs= categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
categoryService.add(c);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
uploadedImageFile.getImage().transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
return "redirect:/admin_category_list";
}
@RequestMapping("admin_category_delete")
public String delete(int id,HttpSession session) throws IOException {
categoryService.delete(id);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,id+".jpg");
file.delete();
return "redirect:/admin_category_list";
}
}
增加通过id获取Category对象的sql语句
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<select id="total" resultType="int">
select count(*) from category
</select>
<insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" >
insert into category ( name ) values (#{name})
</insert>
<delete id="delete">
delete from category where id= #{id}
</delete>
<select id="get" resultType="Category">
select * from category where id= #{id}
</select>
</mapper>
增加get方法
package com.how2java.tmall.mapper;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryMapper {
List<Category> list(Page page);
int total();
void add(Category category);
void delete(int id);
Category get(int id);
}
package com.how2java.tmall.mapper; import com.how2java.tmall.util.Page; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryMapper { List<Category> list(Page page); int total(); void add(Category category); void delete(int id); Category get(int id); }
增加get方法
package com.how2java.tmall.service;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.util.Page;
import java.util.List;
public interface CategoryService{
int total();
List<Category> list(Page page);
void add(Category category);
void delete(int id);
Category get(int id);
}
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.util.Page; import java.util.List; public interface CategoryService{ int total(); List<Category> list(Page page); void add(Category category); void delete(int id); Category get(int id); }
增加get方法
package com.how2java.tmall.service.impl;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.mapper.CategoryMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list(Page page) {
return categoryMapper.list(page);
}
@Override
public int total() {
return categoryMapper.total();
}
@Override
public void add(Category category) {
categoryMapper.add(category);
}
@Override
public void delete(int id) {
categoryMapper.delete(id);
}
@Override
public Category get(int id) {
return categoryMapper.get(id);
}
}
增加edit方法
1. 映射admin_category_edit路径的访问 2. 参数id用来接受注入 3. 通过categoryService.get获取Category对象 4. 把对象放在“c"上 5. 返回editCategory.html
@RequestMapping("admin_category_edit")
public String edit(int id,Model model) throws IOException {
Category c= categoryService.get(id);
model.addAttribute("c", c);
return "admin/editCategory";
}
package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.util.ImageUtil;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.util.UploadedImageFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page){
List<Category> cs= categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
categoryService.add(c);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
uploadedImageFile.getImage().transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
return "redirect:/admin_category_list";
}
@RequestMapping("admin_category_delete")
public String delete(int id,HttpSession session) throws IOException {
categoryService.delete(id);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,id+".jpg");
file.delete();
return "redirect:/admin_category_list";
}
@RequestMapping("admin_category_edit")
public String edit(int id,Model model) throws IOException {
Category c= categoryService.get(id);
model.addAttribute("c", c);
return "admin/editCategory";
}
}
增加修改的sql语句
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<select id="total" resultType="int">
select count(*) from category
</select>
<insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category" >
insert into category ( name ) values (#{name})
</insert>
<delete id="delete">
delete from category where id= #{id}
</delete>
<select id="get" resultType="Category">
select * from category where id= #{id}
</select>
<update id="update" parameterType="Category" >
update category set name=#{name} where id=#{id}
</update>
</mapper>
增加update方法
package com.how2java.tmall.mapper;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.pojo.Category;
import java.util.List;
public interface CategoryMapper {
List<Category> list(Page page);
int total();
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}
package com.how2java.tmall.mapper; import com.how2java.tmall.util.Page; import com.how2java.tmall.pojo.Category; import java.util.List; public interface CategoryMapper { List<Category> list(Page page); int total(); void add(Category category); void delete(int id); Category get(int id); void update(Category category); }
增加update方法
package com.how2java.tmall.service;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.util.Page;
import java.util.List;
public interface CategoryService{
int total();
List<Category> list(Page page);
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.util.Page; import java.util.List; public interface CategoryService{ int total(); List<Category> list(Page page); void add(Category category); void delete(int id); Category get(int id); void update(Category category); }
增加update方法
package com.how2java.tmall.service.impl;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.mapper.CategoryMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list(Page page) {
return categoryMapper.list(page);
}
@Override
public int total() {
return categoryMapper.total();
}
@Override
public void add(Category category) {
categoryMapper.add(category);
}
@Override
public void delete(int id) {
categoryMapper.delete(id);
}
@Override
public Category get(int id) {
return categoryMapper.get(id);
}
@Override
public void update(Category category) {
categoryMapper.update(category);
}
}
新增update方法
1. update 方法映射路径admin_category_update的访问 1.1 参数 Category c接受页面提交的分类名称 1.2 参数 session 用于在后续获取当前应用的路径 1.3 UploadedImageFile 用于接受上传的图片 2. 通过categoryService更新c对象 3. 首先判断是否有上传图片,如果有上传,那么通过session获取ControllerContext,再通过getRealPath定位存放分类图片的路径。 如果严格按照本教程的做法,使用idea中的tomcat部署的话,那么图片就会存放在:E:\project\tmall_springboot\target\tmall_springboot\img\category 这里 4. 根据分类id创建文件名 5. 通过UploadedImageFile 把浏览器传递过来的图片保存在上述指定的位置 6. 通过ImageUtil.change2jpg(file); 确保图片格式一定是jpg,而不仅仅是后缀名是jpg. 7. 客户端跳转到admin_category_list
@RequestMapping("admin_category_update")
public String update(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
categoryService.update(c);
MultipartFile image = uploadedImageFile.getImage();
if(null!=image &&!image.isEmpty()){
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
image.transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
}
return "redirect:/admin_category_list";
}
package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.util.ImageUtil;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.util.UploadedImageFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page){
List<Category> cs= categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
categoryService.add(c);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
uploadedImageFile.getImage().transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
return "redirect:/admin_category_list";
}
@RequestMapping("admin_category_delete")
public String delete(int id,HttpSession session) throws IOException {
categoryService.delete(id);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,id+".jpg");
file.delete();
return "redirect:/admin_category_list";
}
@RequestMapping("admin_category_edit")
public String edit(int id,Model model) throws IOException {
Category c= categoryService.get(id);
model.addAttribute("c", c);
return "admin/editCategory";
}
@RequestMapping("admin_category_update")
public String update(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
categoryService.update(c);
MultipartFile image = uploadedImageFile.getImage();
if(null!=image &&!image.isEmpty()){
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
image.transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
}
return "redirect:/admin_category_list";
}
}
提供editCategory.html
在第40行显示分类名称 在第50行提供id <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.html"%>
<%@include file="../include/admin/adminNavigator.html"%>
<title>编辑分类</title>
<script>
$(function(){
$("#editForm").submit(function(){
if(!checkEmpty("name","分类名称"))
return false;
return true;
});
});
</script>
<div class="workingArea">
<ol class="breadcrumb">
<li><a href="admin_category_list">所有分类</a></li>
<li class="active">编辑分类</li>
</ol>
<div class="panel panel-warning editDiv">
<div class="panel-heading">编辑分类</div>
<div class="panel-body">
<form method="post" id="editForm" action="admin_category_update" enctype="multipart/form-data">
<table class="editTable">
<tr>
<td>分类名称</td>
<td><input id="name" name="name" value="${c.name}" type="text" class="form-control"></td>
</tr>
<tr>
<td>分类圖片</td>
<td>
<input id="categoryPic" accept="image/*" type="file" name="image" />
</td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="id" value="${c.id}">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
CategoryController新增add方法
1. add方法映射路径admin_category_add的访问 1.1 参数 Category c接受页面提交的分类名称 1.2 参数 session 用于在后续获取当前应用的路径 1.3 UploadedImageFile 用于接受上传的图片 2. 通过categoryService保存c对象 3. 通过session获取ControllerContext,再通过getRealPath定位存放分类图片的路径。 如果严格按照本教程的做法,使用idea中的tomcat部署的话,那么图片就会存放在:E:\project\tmall_springboot\target\tmall_springboot\img\category 这里 4. 根据分类id创建文件名 5. 如果/img/category目录不存在,则创建该目录,否则后续保存浏览器传过来图片,会提示无法保存 6. 通过UploadedImageFile 把浏览器传递过来的图片保存在上述指定的位置 7. 通过ImageUtil.change2jpg(file); 确保图片格式一定是jpg,而不仅仅是后缀名是jpg. 8. 客户端跳转到admin_category_list
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
categoryService.add(c);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
uploadedImageFile.getImage().transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
return "redirect:/admin_category_list";
}
package com.how2java.tmall.controller;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.util.ImageUtil;
import com.how2java.tmall.util.Page;
import com.how2java.tmall.util.UploadedImageFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
@Controller
@RequestMapping("")
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page){
List<Category> cs= categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
System.out.println(c.getId());
categoryService.add(c);
System.out.println(c.getId());
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,c.getId()+".jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
System.out.println(uploadedImageFile);
System.out.println(uploadedImageFile.getImage());
System.out.println(file);
uploadedImageFile.getImage().transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
return "redirect:/admin_category_list";
}
}
中文问题,统一交由web.xml 中定义的org.springframework.web.filter.CharacterEncodingFilter来进行处理
其他的配合动作 1. 在jsp中要加上 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> 其中contentType="text/html; charset=UTF-8"的作用是告诉浏览器提交数据的时候,使用UTF-8编码 2. 在form里method="post" 才能正确提交中文 参考: 使用Filter处理中文问题
新增方法:
void setFirstProductImage(Product p); package com.how2java.tmall.service;
import java.util.List;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.pojo.Product;
public interface ProductService {
void add(Product p);
void delete(int id);
void update(Product p);
Product get(int id);
List list(int cid);
void setFirstProductImage(Product p);
}
package com.how2java.tmall.service; import java.util.List; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.pojo.Product; public interface ProductService { void add(Product p); void delete(int id); void update(Product p); Product get(int id); List list(int cid); void setFirstProductImage(Product p); }
ProductServiceImpl为ProductService中新增加的三个方法提供实现。
1. 为分类填充产品集合 public void fill(Category category); 2. 为多个分类填充产品集合 public void fill(List<Category> categorys); 3.为多个分类填充推荐产品集合,即把分类下的产品集合,按照8个为一行,拆成多行,以利于后续页面上进行显示 public void fillByRow(List<Category> categorys); package com.how2java.tmall.service.impl;
import com.how2java.tmall.mapper.ProductMapper;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.pojo.Product;
import com.how2java.tmall.pojo.ProductExample;
import com.how2java.tmall.pojo.ProductImage;
import com.how2java.tmall.service.CategoryService;
import com.how2java.tmall.service.ProductImageService;
import com.how2java.tmall.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
ProductMapper productMapper;
@Autowired
CategoryService categoryService;
@Autowired
ProductImageService productImageService;
@Override
public void add(Product p) {
productMapper.insert(p);
}
@Override
public void delete(int id) {
productMapper.deleteByPrimaryKey(id);
}
@Override
public void update(Product p) {
productMapper.updateByPrimaryKeySelective(p);
}
@Override
public Product get(int id) {
Product p = productMapper.selectByPrimaryKey(id);
setFirstProductImage(p);
setCategory(p);
return p;
}
public void setCategory(List<Product> ps){
for (Product p : ps)
setCategory(p);
}
public void setCategory(Product p){
int cid = p.getCid();
Category c = categoryService.get(cid);
p.setCategory(c);
}
@Override
public List list(int cid) {
ProductExample example = new ProductExample();
example.createCriteria().andCidEqualTo(cid);
example.setOrderByClause("id desc");
List result = productMapper.selectByExample(example);
setCategory(result);
setFirstProductImage(result);
return result;
}
@Override
public void setFirstProductImage(Product p) {
List<ProductImage> pis = productImageService.list(p.getId(), ProductImageService.type_single);
if (!pis.isEmpty()) {
ProductImage pi = pis.get(0);
p.setFirstProductImage(pi);
}
}
@Override
public void fill(List<Category> cs) {
for (Category c : cs) {
fill(c);
}
}
@Override
public void fill(Category c) {
List<Product> ps = list(c.getId());
c.setProducts(ps);
}
@Override
public void fillByRow(List<Category> cs) {
int productNumberEachRow = 8;
for (Category c : cs) {
List<Product> products = c.getProducts();
List<List<Product>> productsByRow = new ArrayList<>();
for (int i = 0; i < products.size(); i+=productNumberEachRow) {
int size = i+productNumberEachRow;
size= size>products.size()?products.size():size;
List<Product> productsOfEachRow =products.subList(i, size);
productsByRow.add(productsOfEachRow);
}
c.setProductsByRow(productsByRow);
}
}
public void setFirstProductImage(List<Product> ps) {
for (Product p : ps) {
setFirstProductImage(p);
}
}
}
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>异步处理技术</td>
<td>JQuery</td>
<td>JQuery</td>
<td>JQuery</td>
<td>Axios.js</td>
</tr>
<tr>
<td>RESTFUL</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 标准 RESTFUL 风格</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>异步处理技术</td>
<td>JQuery</td>
<td>JQuery</td>
<td>JQuery</td>
<td>Axios.js</td>
</tr>
<tr>
<td>RESTFUL</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 标准 RESTFUL 风格</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>异步处理技术</td>
<td>JQuery</td>
<td>JQuery</td>
<td>JQuery</td>
<td>Axios.js</td>
</tr>
<tr>
<td>RESTFUL</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 标准 RESTFUL 风格</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
模仿天猫整站实践项目教程目前有 4 个版本,分别是 J2EE版, SSH版、SSM版, Springboot版 以下列出了各个版本之间的区别。
同一个项目,特意采用了不同的技术实现,大体上涵盖了目前JAVA用到的各类主流技术。采用不同的开发环境,启动部署方式,项目风格,以各种不同的方式实现了同一个项目里的各类业务功能。 掌握了这些内容之后,能够比较明显地提高参加工作时的适应能力。 <script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="5" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>异步处理技术</td>
<td>JQuery</td>
<td>JQuery</td>
<td>JQuery</td>
<td>Axios.js</td>
</tr>
<tr>
<td>RESTFUL</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 标准 RESTFUL 风格</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
模仿天猫整站实践项目教程目前有 4 个版本,分别是 J2EE版, SSH版、SSM版, Springboot版 以下列出了各个版本之间的区别。
同一个项目,特意采用了不同的技术实现,大体上涵盖了目前JAVA用到的各类主流技术。采用不同的开发环境,启动部署方式,项目风格,以各种不同的方式实现了同一个项目里的各类业务功能。 掌握了这些内容之后,能够比较明显地提高参加工作时的适应能力。 <script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="5" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>异步处理技术</td>
<td>JQuery</td>
<td>JQuery</td>
<td>JQuery</td>
<td>Axios.js</td>
</tr>
<tr>
<td>RESTFUL</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 标准 RESTFUL 风格</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
模仿天猫整站实践项目教程目前有 4 个版本,分别是 J2EE版, SSH版、SSM版, Springboot版 以下列出了各个版本之间的区别。
同一个项目,特意采用了不同的技术实现,大体上涵盖了目前JAVA用到的各类主流技术。采用不同的开发环境,启动部署方式,项目风格,以各种不同的方式实现了同一个项目里的各类业务功能。 掌握了这些内容之后,能够比较明显地提高参加工作时的适应能力。 <script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="5" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
<th>SPRINGBOOT 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
<td>JPA</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
<td>Maven 项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
<td>Springboot 自带Tomcat</td>
</tr>
<tr>
<td>模板技术</td>
<td>JSP</td>
<td>JSP</td>
<td>JSP</td>
<td>Thymeleaf</td>
</tr>
<tr>
<td>前端框架</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap</td>
<td>Bootstrap, Vue.js</td>
</tr>
<tr>
<td>前后端分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>异步处理技术</td>
<td>JQuery</td>
<td>JQuery</td>
<td>JQuery</td>
<td>Axios.js</td>
</tr>
<tr>
<td>RESTFUL</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 标准 RESTFUL 风格</td>
</tr>
<tr>
<td>动静分离</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 nginx 实现</td>
</tr>
<tr>
<td>安全框架</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 shiro 实现</td>
</tr>
<tr>
<td>缓存</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 redis 实现</td>
</tr>
<tr>
<td>搜索引擎</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 通过 elastic search 实现</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="4" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="3" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="3" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts2</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr>
<td>部署到Linux</td>
<td colspan="3" align="center"><a target="_blank" href="https://how2j.cn/k/1591">提供独立免费教程-如何把J2EE应用部署到Linux系列教程</a></td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr>
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr>
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<style>
</style>
<script>
$(function(){
})
</script>
<div align="center">
<table style="width:90%" class="table table-striped table-bordered1 table-hover table-condensed">
<!-- <caption style="text-align:center">模仿天猫整站不同版本区别</caption> -->
<thead>
<th colspan="4" style="text-align:center">模仿天猫整站个版本区别</th>
</thead>
<thead>
<th style="width:120px"></th>
<th>J2EE版</th>
<th>SSH 版</th>
<th>SSM 版</th>
</thead>
<tr>
<td>前台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>后台功能</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 齐备</td>
</tr>
<tr>
<td>存储层技术</td>
<td>JDBC</td>
<td>Hibernate</td>
<td>Mybatis</td>
</tr>
<tr>
<td>控制层技术</td>
<td>Servlet+反射</td>
<td>Struts</td>
<td>Spring MVC</td>
</tr>
<tr>
<td>教程使用的IDE</td>
<td>Eclipse</td>
<td>Eclipse</td>
<td>IntelliJ IDEA(无缝兼容Eclipse)</td>
</tr>
<tr>
<td>是否Maven项目</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-remove text-danger"></span> 否</td>
<td><span class="glyphicon glyphicon-ok text-success"></span> 是</td>
</tr>
<tr>
<td>项目格式</td>
<td>标准 Java 项目</td>
<td>动态Web项目</td>
<td>Maven Web项目</td>
</tr>
<tr>
<td>启动方式</td>
<td>Tomcat独立配置启动</td>
<td>Eclipse内置Tomcat启动</td>
<td>IntelliJ IDEA内置Tomcat启动</td>
</tr>
<tr style="display:none">
<td>企业要求</td>
<td>极少企业会使用Servlet+JDBC这种方式进行开发新项目了。 但是这种“原始” 方式是框架模式开发的基础,掌握这些基础,有助于在框架模式下遭遇疑难问题的时候,更从容地解决相关问题。</td>
<td>SSH这种模式是以前的主流,现在的趋势是逐渐被SSM所替代。 但是正因为是曾经的主流,所以存在大量的以前项目需要SSH技术去维护,所以在各大招聘网站可以观察到大量的这方面的人员需求。所以掌握SSH依然对拿到Offer非常有帮助</td>
<td>大部分企业在开展新项目的时候都会选择SSM框架,所以这个技术的人才需求会持续旺盛相当长一段时间,犹如当年的SSH一般</td>
</tr>
</table>
</div>
有部分同学更倾向于使用idea来启动web项目,但是在idea导入eclipse的Dynamic Web Project风格项目的时候由常常走不通,为此专门制作了:1576,协助学习曲线更平滑些。
后面有一个JPA的CRUD和分页,可以学习到更多的关于JPA的知识
有一定的逻辑能力,自学能力,但是自律能力有限的同学
在右上角有本知识点对应的可运行项目下载 ,实在自己搞不出来,就下载解压出来比较一下。
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
在右上角有本知识点对应的可运行项目下载 ,实在自己搞不出来,就下载解压出来比较一下。
其他概念。。。后面学到再讲~
22
22
22
dsfa
fdsaf
fdsaf
刚把 diytomcat 74个视频录制完毕,休息一下。。。
让 Cate
package com.how2java.springboot.pojo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "category_")
public class Category implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
首先点中源目录:java 然后菜单->File->New->Package 输入 com.how2java.tmall.test 创建包
接着创建测试TestTmall, 其作用是借助JDBC, 运行代码,创建10条分类测试数据。 注: 既然是SSM教程,为什么不用mybatis创建测试数据,而要用JDBC创建? 因为增加功能要到下个知识点才讲啊。。。 package com.how2java.tmall.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestTmall {
public static void main(String args[]){
//准备分类测试数据:
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try (
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/tmall_springboot?useUnicode=true&characterEncoding=utf8",
"root", "admin");
Statement s = c.createStatement();
)
{
for (int i = 1; i <=10 ; i++) {
String sqlFormat = "insert into category values (null, '测试分类%d')";
String sql = String.format(sqlFormat, i);
s.execute(sql);
}
System.out.println("已经成功创建10条分类测试数据");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
content-1
content-1
content-2
content-2
content-3
content-3
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
好,假装已经下好了
什么是消息中间件呢?
以站长的公众号为例,如果某学员订阅(关注)了这个公众号,每当站长发布新教程的时候,都可以在这个公众号得到通知,这就是一种广播订阅模式。 而公众号如何实现这一点呢? 就可以通过 消息中间件 来轻松实现。 站长把最新的教程信息 发给 消息中间件服务器, 学员手机上的微信里的消息中间件客户端,就会自动去把消息获取出来显示,这样站长就达到了教程广播的效果了。
http://repo1.maven.org/maven2/.m2e/connectors/m2eclipse-mavenarchiver/0.17.2/N/LATEST/
Version: Oxygen Release (4.7.0) idea7
公司C基础信息:
职位地点:厦门 公司所属领域:教育互联网 公司规模:50人。 工作时间:双休。 薪资范围:基薪(13薪)+项目奖(优秀者可谈) 融资情况:未融资 年龄要求:倾向于35岁以下 学历要求:本科以上。 招聘人数:1人/职位 职位编号20190621-C-02:Java后端开发 工作内容 1.3年以上后端开发经验,有独立完成项目架构的能力。(Node.js 优先) 2.熟悉网站构架和性能优化,熟悉各种WEB缓存技术。 3.能很好的分析、总结、归纳需求,并能提供合适的技术解决方案。 4.有出色的沟通和理解他人(特别是孩子)的能力。 5.善于思考、乐于思考,对解决具有挑战性的问题充满激情。 6.熟悉JavaScript和前端开发框架。 7.开源贡献者优先,github源码者优先,技术博客者优先。 职位要求 1. 负责开发双语阅读个性化教育平台。 2. 负责开发儿童教育类教学管理系统。 3. 参与技术攻关,组织技术积累等工作。 4. 撰写项目架构设计文档,定期做技术分享和项目总结。 职位编号20190621-C-01:前端开发 工作内容 1.负责开发儿童教育类线上产品。 2.建立公司前端开发标准库。 职位要求 1.3年以上前端开发经验,有独立完成项目的能力。 2.精通HTML5、CSS3等前端开发语言。 3.精通Vue 或 ReactJS。 4.熟悉微信小程序开发框架。 5.能处理主流浏览器兼容性问题。 6.至少熟悉一种后端语言是加分项。 7.开源贡献者优先,github源码者优先,技术博客者优先。
删除掉这4个,其实删不删都无所谓,只是删除了看到清爽点~
注: 不要删除下面 src 目录了,否则会报异常。
只需要改造 trend-trading-backtest-view 使其联通 rabbitmq,并且能够接受更新配置服务的信号就行了,index-config-server 不用修改。
肩颈操10分钟视频,缓解肩部神经,减缓疼痛预防颈椎病
把 logback.xml 放在 src 或者 src/main/resources 目录下就可以了。
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT" /> </root> </configuration>
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
运行 Bootstrap, 然后访问测试地址: http://127.0.0.1:18080/ 将看到如图所示的效果。
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程 package cn.how2.how2tomcat;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import cn.hutool.core.util.NetUtil;
public class Bootstrap {
public static void main(String[] args) {
try {
int port = 18080;
if(!NetUtil.isUsableLocalPort(port)) {
System.out.println(port +" 端口已经被占用了,排查并关闭本端口的办法请用:\r\nhttps://how2j.cn/k/tomcat/tomcat-portfix/545.html");
return;
}
ServerSocket ss = new ServerSocket(port);
int i = 1;
while(true) {
Socket s = ss.accept();
System.out.println(i++);
OutputStream os = s.getOutputStream();
String response_head = "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n\r\n";
String text = "<div style='color:blue' >Hello DIY Tomcat!</div>";
text = response_head + text;
os.write(text.getBytes());
s.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1. 学完之后,能够 "自己写个Tomcat", 能做到这一点本身就说明技术不错了
2. 在制作 DiyTomcat 的过程中,需要解决各种各样稀奇古怪的问题,最后能够做出来,功力就会有大大的提升 3. 在简历里会成为亮点, 对面试官很有吸引力, 为争取高薪岗位提供了重要的砝码
本项目有75个章节, 站长会带着大家从0开始, 从建立项目开始,一点点地把这个项目构建起来。
在运行过程中会提示如图所示的红色提醒,有的同学会误以为测试失败,其实不是。 这个Hutool的警告信息,表示检查到了 log4j 的 jar包,但是却没有找到 log4j 的配置文件,在后续的教程就会讲解 日志相关的内容,就不会出现这个警告信息了。
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
会有同学反应,明明跟着做了,但是项目就是跑不起来,运行有问题,怎么办?
1. 部分同学自己以为的跟着做,其实并不是,中途自己爱在这里改一下,那里改一下,正是因为对项目不熟悉,所以这些 “小改动” 恰恰就是项目不能运行起来的原因。 所以应该严格按照站长教程的步骤,一五一十地照着做,等把这个项目全部都做通了,然后再根据自己的意愿这里改改,哪里改改,既满足了手痒的瘾,又能够在出了问题的时候不那么慌张,沉着冷静地分析解决问题。 2. 虽然部分同学“照着做了” 但是依然没有跑起来,这是因为项目本身比较复杂,伴随着学习进度的推进,会越来越复杂。 很有可能都意识不到自己哪里不一样导致的。 所以,站长专门在右上角提供了当前这个阶段对应的可运行项目。 这样通过对整个项目的比较,就很容易定位自己的代码哪一行的哪个细节没有做对,这样学习起来,就会很有效率。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
readBytes 有bug,修正一下。。。
package cn.how2j.diytomcat.util;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.http.HttpUtil;
public class MiniBrowser {
public static void main(String[] args) throws Exception {
String url = "http://static.how2j.cn/diytomcat.html";
String contentString= getContentString(url,false);
System.out.println(contentString);
String httpString= getHttpString(url,false);
System.out.println(httpString);
}
public static byte[] getContentBytes(String url) {
return getContentBytes(url, false);
}
public static String getContentString(String url) {
return getContentString(url,false);
}
public static String getContentString(String url, boolean gzip) {
byte[] result = getContentBytes(url, gzip);
if(null==result)
return null;
try {
return new String(result,"utf-8").trim();
} catch (UnsupportedEncodingException e) {
return null;
}
}
public static byte[] getContentBytes(String url, boolean gzip) {
byte[] response = getHttpBytes(url,gzip);
byte[] doubleReturn = "\r\n\r\n".getBytes();
int pos = -1;
for (int i = 0; i < response.length-doubleReturn.length; i++) {
byte[] temp = Arrays.copyOfRange(response, i, i + doubleReturn.length);
if(Arrays.equals(temp, doubleReturn)) {
pos = i;
break;
}
}
if(-1==pos)
return null;
pos += doubleReturn.length;
byte[] result = Arrays.copyOfRange(response, pos, response.length);
return result;
}
public static String getHttpString(String url,boolean gzip) {
byte[] bytes=getHttpBytes(url,gzip);
return new String(bytes).trim();
}
public static String getHttpString(String url) {
return getHttpString(url,false);
}
public static byte[] getHttpBytes(String url,boolean gzip) {
byte[] result = null;
try {
URL u = new URL(url);
Socket client = new Socket();
int port = u.getPort();
if(-1==port)
port = 80;
InetSocketAddress inetSocketAddress = new InetSocketAddress(u.getHost(), port);
client.connect(inetSocketAddress, 1000);
Map<String,String> requestHeaders = new HashMap<>();
requestHeaders.put("Host", u.getHost()+":"+port);
requestHeaders.put("Accept", "text/html");
requestHeaders.put("Connection", "close");
requestHeaders.put("User-Agent", "how2j mini brower / java1.8");
if(gzip)
requestHeaders.put("Accept-Encoding", "gzip");
String path = u.getPath();
if(path.length()==0)
path = "/";
String firstLine = "GET " + path + " HTTP/1.1\r\n";
StringBuffer httpRequestString = new StringBuffer();
httpRequestString.append(firstLine);
Set<String> headers = requestHeaders.keySet();
for (String header : headers) {
String headerLine = header + ":" + requestHeaders.get(header)+"\r\n";
httpRequestString.append(headerLine);
}
PrintWriter pWriter = new PrintWriter(client.getOutputStream(), true);
pWriter.println(httpRequestString);
InputStream is = client.getInputStream();
result = readBytes(is);
client.close();
} catch (Exception e) {
e.printStackTrace();
try {
result = e.toString().getBytes("utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
}
return result;
}
public static byte[] readBytes(InputStream is) throws IOException {
int buffer_size = 1024;
byte buffer[] = new byte[buffer_size];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while(true) {
int length = is.read(buffer);
if(-1==length)
break;
baos.write(buffer, 0, length);
}
byte[] result =baos.toByteArray();
return result;
}
}
tomcat 教程跳票以及解释。
经过相当长的时间之后,手写 tomcat 本身已经与3月份开发完毕。 然后在此基础之上,进行教程的开发,原计划于4月份完成教程,但是在制作教程过程中,发现需要耗费的精力与时间远超计划,所以截至 2020-4-25 ,教程目前完成的进度是 67%,如图所示,点亮部分即已经完成的。 接下来还剩下的只能在5月份完成了。 完成之后会上线,然后6月份会陆续录制视频,直到所有视频录制完成。
跟着做了,但是还是有问题,跑不起来。
原有主要有二: 1. 自己做了改动,因为对项目还不熟悉,这些改动导致项目跑不起来。 2. 以为自己没做改动,其实还是做了改动,这个时常发生。 为了解决这个问题,站长特意把当前的可运行项目放在了右上角下载, 这样通过比较,就可以快速定位问题所在,大大地提高学习效率。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
耳听为虚,眼见为实,这个项目到底都做了什么呢? 点击 运行演示
项目的内容很多,为了便于大家理解与跟踪学习,专门制作了项目体系结构图。
这个体系结构图很复杂,这里不展开讲,在后面每个章节学习,都会点亮这个体系结构图的对应节点,全部章节都学习完,对项目体系自然也就明白了。
什么是akshare? AKShare 是基于Python的财经数据接口库, 方便大家从各个公开的网站如 新浪,腾讯,东财等地方获取各类金融数据。
HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
|