springmvc和mybatis——京淘电商项目
一.技术路线
开发工具:IDEA、HBuilder
技术框架:springmvc、mybatis
数据库:mysql8
前端框架:vue
二.项目分析
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/275c4074384c527c881424e585a491e7.png)
1.主站用户注册
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/845a8d8541f4355afb1a17b11299523d.png)
2.前端主站
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/74e40a61818a325089b7ddbd02d85c19.png)
3.后台管理
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1511d4f060e40f2a3fb8f7599d7df4d4.jpeg)
三.创建项目
1.创建项目com.tedu.project_jingtao
创建spingboot项目
选择module->spring Initializr->选择Java版本和设置项目名称->添加依赖(web,mybatis,mysql)->finish
2.逆向工程生成xml和pojo类
eclipse中import项目generator,
修改根目录下的GeneratorConfig.xml中的 2,3,4的包名为com.tedu.project_jingtao,
修改5为对应的数据库表名
3.创建controller,mapper,service,pojo包
4.拷贝mapper.xml和接口
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5d653a38889ad8138e87576823babc4c.png)
5.创建application.yml(resources文件夹下)
server:
port: 12345
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
# 有的mysql如5.0 下面必须改成com.mysql.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
username: root
password: 123456
mybatis:
mapperLocations: classpath:com.tedu.project_jingtao.mapper/*.xml
logging:
path: ./logs
level:
com.tedu.project_jingtao.mapper: debug
6.添加扫描
@SpringBootApplication
@MapperScan("com.tedu.project_jingtao.mapper")
public class ProjectJingtaoApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectJingtaoApplication.class, args);
}
}
四.后台服务
1.用户模块UserController
package com.tedu.project_jingtao.controller;
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {
@Autowired
private UserMapper userMapper;
@RequestMapping("/register")
public String register(User user){
UserExample userExample = new UserExample();
UserExample.Criteria criteria = userExample.or();
criteria.andPasswordEqualTo(user.getPassword());
criteria.andUsernameEqualTo(user.getUsername());
List<User> users = userMapper.selectByExample(userExample);
if(users!=null&&users.size()==0){
int rows = userMapper.insert(user);
if(rows>=1){
return "注册成功";
}else {
return "注册失败";
}
}
return "用户名太受欢迎了,换一个吧";
}
@RequestMapping("/login")
public User login(User user){
UserExample userExample = new UserExample();
UserExample.Criteria criteria = userExample.or();
criteria.andUsernameEqualTo(user.getUsername());
criteria.andPasswordEqualTo(user.getPassword());
List<User> users = userMapper.selectByExample(userExample);
if(users!=null&&users.size()>0){
User u = users.get(0);
u.setPassword("");
return u;
}
return null;
}
}
2.管理员模块AdminController
package com.tedu.project_jingtao.controller;
@RestController
@RequestMapping("/admin")
public class AdminController {
@Autowired
private TbAdminMapper tbAdminMapper;
@RequestMapping("/login")
@CrossOrigin
public TbAdmin login(TbAdmin tbAdmin){
TbAdminExample tbAdminExample = new TbAdminExample();
TbAdminExample.Criteria criteria = tbAdminExample.or();
criteria.andAdminNameEqualTo(tbAdmin.getAdminName());
criteria.andAdminPasswordEqualTo(tbAdmin.getAdminPassword());
List<TbAdmin> tbAdmins = tbAdminMapper.selectByExample(tbAdminExample);
if(tbAdmins!=null&&tbAdmins.size()>=1){
TbAdmin admin = tbAdmins.get(0);
admin.setAdminPassword("");
return admin;
}
return null;
}
}
3.商品模块ItemController
package com.tedu.project_jingtao.controller;
@RestMapping("/item")
@RestController
@CrossOrigin
public class ItemController {
@Autowired
private ItemMapper itemMapper;
@RequestMapping("/findByCategoryId")
public List<Item> findByCategoryId(Integer categoryId){
ItemExample itemExample = new ItemExample();
ItemExample.Criteria criteria = itemExample.or();
criteria.andCategoryIdEqualTo(categoryId);
List<Item> items = itemMapper.selectByExample(itemExample);
return items;
}
@RequestMapping("/findByItemId")
public Item findById(Integer itemId){
return itemMapper.selectByPrimaryKey(itemId);
}
@RequestMapping("/insertItem")
public String insertItem(Item item){
int rows = itemMapper.insert(item);
if(rows>=1){
return "添加成功";
}
return "添加失败";
}
@RequestMapping("/findAllItems")
public List<Item> findAllItems(){
return itemMapper.selectByExample(null);
}
@RequestMapping("/deleteByItemId")
public String deleteById(Integer itemId){
int rows = itemMapper.deleteByPrimaryKey(itemId);
if(rows>=1){
return "删除成功";
}
return "删除失败";
}
@RequestMapping("update")
public String update(Item item){
int rows = itemMapper.updateByPrimaryKey(item);
if(rows>=1){
return "修改成功";
}
return "修改失败";
}
4.分类模块CategoryController
package com.tedu.project_jingtao.controller;
@RestController
@RequestMapping("/category")
public class CategoryController {
@Autowired
private CategoryMapper categoryMapper;
@RequestMapping("/findAllCategory")
@CrossOrigin
public List<Category> findAllCategory(){
return categoryMapper.selectByExample(null);
}
}
五.前端显示
准备工作:vue.js,axios.min.js
创建const.js文件,添加全局变量let serverHost="http://localhost:12345"
1.project_jingtao_web项目(用户访问)
(1)主页index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="vue.js" type="text/javascript"></script>
<script src="axios.min.js" type="text/javascript"></script>
<script src="const.js" type="application/javascript"></script>
</head>
<body>
<div id="app">
<a href="register.html">注册</a>
<a href="login.html">登录</a>
<table>
<tr >
<td @click="findItemByCategoryId(category.categoryId)" v-for="category in categoryList">{{category.categoryName}}</td>
</tr>
</table>
<table>
<tr v-for="item in itemList">
<td>
<a v-bind:href="'detail.html?itemId='+item.itemId">
<img v-bind:src="item.itemImage" />
{{item.itemName}}<p></p>
{{item.itemPrice}}<p></p>
</a>
</td>
</tr>
</table>
</div>
</body>
<script>
var vue=new Vue({
el:"#app",
data:{
categoryList:[],
itemList:[]
},
methods:{
selectAllCategory(){
let serverUrl=serverHost+"/category/findAllCategory";
axios.get(serverUrl)
.then(function(res){
this.vue.categoryList=res.data;
})
},
findItemByCategoryId(categoryId){
let serverUrl=serverHost+"/item/findByCategoryId?categoryId="+categoryId;
axios.get(serverUrl)
.then(function(res){
this.vue.itemList=res.data;
})
}
},
mounted(){
this.selectAllCategory();
this.findItemByCategoryId(1);
}
})
</script>
</html>
(2)item详情页detail.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="vue.js" type="text/javascript"></script>
<script src="axios.min.js" type="text/javascript"></script>
<script src="const.js" type="application/javascript"></script>
</head>
<body>
<div id="app">
<img v-bind:src="item.itemImage" />
{{item.itemName}}<p></p>
{{item.itemPrice}}<p></p>
{{item.itemDesc}}<p></p>
商品评论
</div>
</body>
<script>
var vue=new Vue({
el:"#app",
data:{
item:null
},
mounted(){
var search=location.search;
search=search.substr(1);
var arr=search.split("=");
var itemId=arr[1];
console.log(itemId);
var serverUrl=serverHost+"/item/findByItemId?itemId="+itemId;
axios.get(serverUrl)
.then(function(res){
this.vue.item=res.data;
})
.catch()
}
})
</script>
</html>
(3)用户注册页register.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="axios.min.js"></script>
<script src="const.js" type="text/javascript" ></script>
</head>
<body>
<div id="app">
name:<input v-model="username" /><br>
password:<input v-model="password" /><br>
confirmPassword:<input v-model="confirmPassword"/><br>
<button @click="register">注册</button>
</div>
</body>
<script>
var vue=new Vue({
el:"#app",
data:{
username:"请在这里输入用户名",
password:"请输入密码",
confirmPassword:"请再次确认密码"
},
methods:{
register(){
if(name=""||this.password!=this.confirmPassword){
alert("用户名不能为空或两次密码不一致");
return;
}
var serverUrl=serverHost+"/user/register?username="+this.username
+"&password="+this.password;
axios.get(serverUrl)
.then(function(res){
alert(res.data);
})
.catch()
}
}
})
</script>
</html>
(4)用户登录页login.html
<body>
<div id="app">
用户名:<input v-model="username" />
密码:<input v-model="password" type="password" />
<button type="button" @click="login">登录</button>
</div>
</body>
<script type="text/javascript">
var vue=new Vue({
el:"#app",
data:{
username:"请输入用户名",
password:"请输入密码",
},
methods:{
login:function(){
debugger;
var serverUrl=serverHost+"/user/login?username="+this.username+"&password="+this.password;
axios.get(serverUrl)
.then(function(res){
debugger;
var result=res.data;
console.log(result)
})
.catch()
}
}
})
</script>
2.project_jingtao_admin项目(管理员访问)
(1)管理员登录页面login.html
<body>
<div id="app">
<h1>管理员登录</h1>
<input v-model="adminName" />
<input v-model="adminPassword" type="password" />
<button type="button" @click="login">登录</button>
</div>
</body>
<script type="text/javascript">
var vue=new Vue({
el:"#app",
data:{
adminName:"请输入用户名",
adminPassword:"请输入密码",
},
methods:{
login:function(){
var serverUrl=serverHost+"/admin/login?adminName="+this.adminName+"&adminPassword="+this.adminPassword;
axios.get(serverUrl)
.then(function(res){
var result=res.data;
if(result!=""){
location.href="item.html";
}else{
alert("登录失败")
}
})
.catch()
}
}
})
</script>
(2)商品管理页面item.html
<body>
<a href="item.html">商品管理</a>
<a href="#">订单管理</a>
<div id="app">
<select v-model="categoryId">
<option v-for="category in categoryList" v-bind:value="category.categoryId">
{{category.categoryName}}
</option>
</select>
商品名称:<input v-model="itemName" />
商品价格:<input v-model="itemPrice" />
商品描述:<input v-model="itemDesc" />
商品图片:<input v-model="itemImage" />
<button @click="insert">添加</button>
<table>
<tr>
<td>商品编号</td>
<td>分类编号</td>
<td>商品名称</td>
<td>价格</td>
<td>描述</td>
<td>图片</td>
<td>删除</td>
<td>修改</td>
</tr>
<tr v-for="item in itemList">
<td>{{item.itemId}}</td>
<td>{{item.categoryId}}</td>
<td>{{item.itemName}}</td>
<td>{{item.itemPrice}}</td>
<td>{{item.itemDesc}}</td>
<td>{{item.itemImage}}</td>
<td @click="remove(item.itemId)">删除</td>
<td><a v-bind:href="'update.html?itemId='+item.itemId">修改</a></td>
</tr>
</table>
</div>
</body>
<script>
var vue=new Vue({
el:"#app",
data:{
itemList:[],
categoryList:[],
categoryId:null,
itemName:null,
itemPrice:null,
itemDesc:null,
itemImage:null
},
methods:{
selectItemList:function(){
var url=serverHost+"/item/findAllItems"
axios.get(url)
.then(function(res){
var result=res.data;
this.vue.itemList=result;
})
.catch()
},
remove(itemId){
var con=window.confirm("您确定要删除吗?")
if(con){
var url=serverHost+"/item/deleteByItemId?itemId="+itemId;
axios.get(url)
.then(function(res){
debugger;
alert(res.data);
this.vue.selectItemList();
})
.catch()
}
},
selectCategoty(){
var serverUrl=serverHost+"/category/findAllCategory";
axios.get(serverUrl)
.then(function(res){
this.vue.categoryList=res.data;
})
.catch();
},
insert(){
var serverUrl=serverHost+"/item/insertItem?categoryId="+this.categoryId
+"&itemName="+this.itemName
+"&itemPrice="+this.itemPrice
+"&itemDesc="+this.itemDesc
+"&itemImage="+this.itemImage;
axios.get(serverUrl)
.then(function(res){
debugger;
var result=res.data;
alert(result)
this.vue.selectItemList();
})
.catch()
},
},
mounted(){
this.selectCategoty();
this.selectItemList();
}
})
</script>
(3)修改商品页面update.html
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ca0ede8a2e1bfeb92d09091937507d94.jpeg)
<body>
<div id="app">
商品分类:<select v-model="categoryId">
<option v-for="category in categoryList" v-bind:value="category.categoryId">
{{category.categoryName}}</option>
</select><br>
名称:<input v-model="itemName" /><br>
价格:<input v-model="itemPrice" /><br>
描述:<input v-model="itemDesc" /><br>
图片:<input v-model="itemImage" />
<button @click="update">修改</button>
</div>
</body>
<script>
var vue=new Vue({
el:"#app",
data:{
categoryList:[],
itemName:null,
itemId:null,
categoryId:null,
itemPrice:null,
itemDesc:null,
itemImage:null
},
methods:{
selectCategoty(){
var serverUrl=serverHost+"/category/findAllCategory";
axios.get(serverUrl)
.then(function(res){
this.vue.categoryList=res.data;
console.log(res.data)
})
.catch();
},
selectItemById(itemId){
var url=serverHost+"/item/findByItemId?itemId="+itemId;
axios.get(url)
.then(function(res){
debugger;
var item=res.data;
this.vue.categoryId=item.categoryId;
this.vue.itemId=item.itemId;
this.vue.itemName=item.itemName;
this.vue.itemPrice=item.itemPrice;
this.vue.itemDesc=item.itemDesc;
this.vue.itemImage=item.itemImage;
})
.catch()
},
update(){
var url=serverHost+"/item/update?itemId="+this.itemId
+"&itemName="+this.itemName
+"&itemPrice="+this.itemPrice
+"&itemDesc="+this.itemDesc
+"&itemImage="+this.itemImage
+"&categoryId="+this.categoryId;
axios.get(url)
.then(function(res){
alert(res.data)
location.href="item.html";
})
.catch()
}
},
mounted(){
var search=location.search;
search=search.substr(1);
var arr=search.split("=");
var itemId=arr[1];
this.selectItemById(itemId);
this.selectCategoty();
}
})
</script>