1.小组分工
我们组课程设计的题目是: 仓库管理系统 ,我认领的功能模块是: 零件管理
2.新建数据表
通过python自动生成虚拟数据,导出为excel表格,直接导入mysql数据库,创建数据表component。具体数据表如下:
3.实现对表的查询和分页
(1)建立数据库的连接
(2)编写前端页面
对于前端页面要包括显示数据的表格和分页组件,还要编写对应的方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="./js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="element-ui/index.css">
<script src="./element-ui/index.js"></script>
</head>
<body>
<h1 style="text-align: center">零件信息表</h1>
<div id="app">
<el-table
:data="ComponentData.filter(data => !search || data.cname.toLowerCase().includes(search.toLowerCase()))"
style="width: 80%;margin: auto " >
<el-table-column
align="center"
label="零件号"
prop="cno">
</el-table-column>
<el-table-column
align="center"
label="零件名"
prop="cname">
</el-table-column>
<el-table-column
align="center"
label="尺寸"
prop="csize">
</el-table-column>
<el-table-column
align="center"
label="单价"
prop="cprice">
</el-table-column>
<el-table-column
align="center"
label="描述"
prop="ctext">
</el-table-column>
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[5, 10, 15, 20,25]"
:page-size="5"
layout="sizes, prev, pager, next"
:total="total">
</el-pagination>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
ComponentData:[],
search:'',
currentPage: 1,// 当前页码
pageSize:5,
total:100
}
},
methods:{
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
console.log(index, row);
},
handleSizeChange(val) {
this.pageSize=val;
this.show();
},
handleCurrentChange(val) {
this.currentPage =val;
this.show();
},
show(){
axios(`/page/${this.pageSize}/${this.currentPage}`).then(r=>{
if(r.data.statusCode==1){
this.ComponentData=r.data.data.rows;
this.total=r.data.data.total;
}
}).catch(error=>{
console.error(error);
})
}
},
mounted(){
this.show();
}
})
</script>
</body>
</html>
(3)后端代码
对于后端代码要包括mapper、service、controller以及pojo四个主要包,主要代码如下:
ComponentMapper.interface:
@Mapper
public interface ComponentMapper {
@Select("select * from component")
public List<Component> Select();
}
ComponentService.interface:
public interface ComponentService {
public List<Component> SelectService();
public PageBean page(Integer pageNumber, Integer pageSize);
}
ComponentServiceA.class:
@Service
public class ComponentServiceA implements ComponentService {
@Autowired
ComponentMapper componentMapper;
@Override
public List<Component> SelectService(){
return componentMapper.Select();
}
@Override
public PageBean page(Integer pageNumber, Integer pageSize) {
PageHelper.startPage(pageNumber, pageSize);
List<Component> com=componentMapper.Select();
PageInfo<Component> p = new PageInfo<>(com);
PageBean pageBean = new PageBean(p.getTotal(),p.getPages(),p.getPageNum(),p.getPageSize(),p.getList());
return pageBean;
}
}
ComponentController.class :
@RestController
public class ComponentController {
@Autowired
ComponentService componentService;
@RequestMapping("/show")
public Result Select(){
return Result.success(componentService.SelectService());
}
@RequestMapping("/page/{PageSize}/{PageNumber}")
public Result page(@PathVariable Integer PageSize, @PathVariable Integer PageNumber){
PageBean page=componentService.page(PageNumber,PageSize);
return Result.success(page);
}
}
Component.class:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Component {
private String cno;
public String cname;
private String csize;
private Float cprice;
private String ctext;
}
Result.class:
public class Result {
private int statusCode;
private String message;
private Object data;
// 私有构造器,防止外部直接实例化
public Result() {
}
public Result(int statusCode, String message, Object data) {
this.data=data;
this.message=message;
this.statusCode=statusCode;
}
// 成功响应的静态构造器
public static Result success(Object data) {
Result result = new Result();
result.statusCode = 1;
result.message = "操作成功";
result.data = data;
return result;
}
public static Result success(){
Result result = new Result();
result.statusCode = 1;
result.message = "操作成功";
result.data = null;
return result;
}
public static Result erro(){
Result result=new Result();
result.statusCode=0;
result.message="操作失败";
result.data=null;
return result;
}
// 失败响应的静态构造器
public static Result fail(String message) {
Result result = new Result();
result.statusCode = 0;
result.message = message;
result.data = null;
return result;
}
// Getter和Setter方法
public int getStatusCode() {
return statusCode;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"statusCode=" + statusCode +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
PageBean.class:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageBean {
private long total;//总记录条数
private int totalPage;//总页数
private int pageNumber;//当前页码
private int pageSize;//本页显示的数据数
//private int startIndex;//每页起始索引 (pageNumber-1)*pageSize
private List rows;//每页显示的数据行数组
}
页面实现效果如下:
4.实现表的增删改查
(1)修改数据
在修改数据的操作中,首先要通过show.html页面将修改数据的零件号传递到update.html页面,这个功能通过window.location.href="update.html?con="+row.cno实现,在update.html页面中通过getCno方法将传递过来的cno赋值给vue中的变量this.cno。将cno号传递到update.html页面后,编写方法selectPart通过showpart接口实现数据查询功能,查询出cno对应的json数据。在页面created钩子方法中调用此selectPart方法和getCno方法,在无序列表中通过v-model实现双向数据的绑定,实现数据的展示。同时编写另一个update方法绑定到按钮提交上,在update方法中可以通过调用接口update实现数据的修改,需要注意的是,在传递数据componentlist时需要将它转化为json格式的数据JSON.stringify(this.componentlist),也需要设置请求格式为json数据'Content-Type': 'application/json'。
(1)前端代码
show.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="./js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="element-ui/index.css">
<script src="./element-ui/index.js"></script>
</head>
<body>
<h1 style="text-align: center">零件信息表</h1>
<div id="app">
<el-table
:data="ComponentData.filter(data => !search || data.cname.toLowerCase().includes(search.toLowerCase()))"
style="width: 80%;margin: auto " >
<el-table-column
align="center"
label="零件号"
prop="cno">
</el-table-column>
<el-table-column
align="center"
label="零件名"
prop="cname">
</el-table-column>
<el-table-column
align="center"
label="尺寸"
prop="csize">
</el-table-column>
<el-table-column
align="center"
label="单价"
prop="cprice">
</el-table-column>
<el-table-column
align="center"
label="描述"
prop="ctext">
</el-table-column>
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[5, 10, 15, 20,25]"
:page-size="pageSize"
layout="sizes, prev, pager, next"
:total="total">
</el-pagination>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
ComponentData:[],
search:'',
currentPage: 1,// 当前页码
pageSize:5,
total:100,
index:''
}
},
methods:{
handleEdit(row) {
window.location.href="update.html?con="+row.cno;
},
handleDelete(index, row) {
console.log(index, row);
},
handleSizeChange(val) {
this.pageSize=val;
this.show();
},
handleCurrentChange(val) {
this.currentPage =val;
this.show();
},
show(){
axios(`/page/${this.pageSize}/${this.currentPage}`).then(r=>{
if(r.data.statusCode==1){
this.ComponentData=r.data.data.rows;
this.total=r.data.data.total;
}
}).catch(error=>{
console.error(error);
})
}
},
created(){
this.show();
}
})
</script>
</body>
</html>
update.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>update</title>
<script src="./js/vue.js"></script>
<script src="./js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="element-ui/index.css">
<script src="./element-ui/index.js"></script>
</head>
<body>
<h1 style="text-align: center">修改零件数据</h1>
<div id="app">
<ul style="list-style: none ">
<li>
零件号:<input type="text" v-model="cno">
</li>
<li>
零件名:<input type="text" v-model="componentlist.cname">
</li>
<li>
尺寸:<input type="text" v-model="componentlist.csize">
</li>
<li>
单价:<input type="text" v-model="componentlist.cprice">
</li>
<li>
描述:<input type="text" v-model="componentlist.ctext">
</li>
<li>
<input type="button" v-on:click="update" value="提交">
</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
componentlist:{},
cno:''
}
},
methods:{
getCno(){
var search = window.location.search;
search = search.substring(5);
this.cno=search;
},
selectPart(){
axios.get(`/showpart/${this.cno}`).then(r=>{
if(r.data.statusCode==1){
if (Array.isArray(r.data.data) && r.data.data.length > 0) {
this.componentlist = r.data.data[0];
} else {
this.componentlist = {};
}
}
else{
console.log(r.data.message);
}
}).catch(error=>{
console.error(error);
})
},
update(){
axios.post("/update",JSON.stringify(this.componentlist),{headers: {
'Content-Type': 'application/json'
}}).then((r)=>{
if(r.data.statusCode==1){
location.href='show.html';
console.log(JSON.stringify(this.componentlist))
}
else{
console.log(r.data.message);
}
}).catch(error=>{
console.error(error);
})
}
},
created(){
this.getCno();
this.selectPart();
}
})
</script>
</body>
</html>
(2)后端代码
ComponentMapper.interface:
@Mapper
public interface ComponentMapper {
@Select("select * from component")
public List<Component> Select();
@Select("select * from component where CNo=#{cno}")
public List<Component> SelectPart(String cno);
@Update("update Component set CName=#{cname},CSize=#{csize},CPrice=#{cprice},CText=#{ctext} where CNo=#{cno}")
public boolean Update(Component component);
@Insert("insert into Component values (#{cno},#{cname},#{csize},#{cprice},#{ctext})")
public boolean Insert(Component component);
@Delete("delete from Component where CNo=#{cno}")
public boolean Delete(String cno);
}
ComponentService.interface:
public interface ComponentService {
public List<Component> SelectService();
public PageBean page(Integer pageNumber, Integer pageSize);
public List<Component> SelectPartService(String cno);
public boolean UpdateService(Component component);
public boolean InsertService(Component component);
public boolean DeleteService(String cno);
}
ComponentServiceA.class:
@Service
public class ComponentServiceA implements ComponentService {
@Autowired
ComponentMapper componentMapper;
@Override
public List<Component> SelectService(){
return componentMapper.Select();
}
@Override
public PageBean page(Integer pageNumber, Integer pageSize) {
PageHelper.startPage(pageNumber, pageSize);
List<Component> com=componentMapper.Select();
PageInfo<Component> p = new PageInfo<>(com);
PageBean pageBean = new PageBean(p.getTotal(),p.getPages(),p.getPageNum(),p.getPageSize(),p.getList());
return pageBean;
}
@Override
public List<Component> SelectPartService(String cno) {
return componentMapper.SelectPart(cno);
}
@Override
public boolean UpdateService(Component component) {
return componentMapper.Update(component);
}
@Override
public boolean InsertService(Component component) {
return componentMapper.Insert(component);
}
@Override
public boolean DeleteService(String cno) {
return componentMapper.Delete(cno);
}
}
ComponentController.class :
@RequestMapping("/showpart/{cno}")
public Result SelectPart( @PathVariable String cno){
return Result.success(componentService.SelectPartService(cno));
}
@RequestMapping("/update")
public Result Update(@RequestBody Component component){
return Result.success(componentService.UpdateService(component));
}
(3)实现页面
(2) 删除数据
(1)前端代码
删除数据只需要获取当前行的零件号并将它传递给接口delete即可,删除完成以后再次调用show方法实现数据显示的更新即可。
show.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="./js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="element-ui/index.css">
<script src="./element-ui/index.js"></script>
</head>
<body>
<h1 style="text-align: center">零件信息表</h1>
<div id="app">
<el-table
:data="ComponentData.filter(data => !search || data.cname.toLowerCase().includes(search.toLowerCase()))"
style="width: 80%;margin: auto " >
<el-table-column
align="center"
label="零件号"
prop="cno">
</el-table-column>
<el-table-column
align="center"
label="零件名"
prop="cname">
</el-table-column>
<el-table-column
align="center"
label="尺寸"
prop="csize">
</el-table-column>
<el-table-column
align="center"
label="单价"
prop="cprice">
</el-table-column>
<el-table-column
align="center"
label="描述"
prop="ctext">
</el-table-column>
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[5, 10, 15, 20,25]"
:page-size="pageSize"
layout="sizes, prev, pager, next"
:total="total">
</el-pagination>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
ComponentData:[],
search:'',
currentPage: 1,// 当前页码
pageSize:5,
total:100,
index:''
}
},
methods:{
handleEdit(row) {
window.location.href="update.html?con="+row.cno;
},
handleDelete(row) {
if(window.confirm("你确定要删除这条数据吗?")){
axios.post(`/delete/${row.cno}`).then(r=>{
if(r.data.statusCode==1){
alert("删除成功!")
this.show();
}
}).catch(error=>{
console.error(error);
})
}
},
handleSizeChange(val) {
this.pageSize=val;
this.show();
},
handleCurrentChange(val) {
this.currentPage =val;
this.show();
},
show(){
axios(`/page/${this.pageSize}/${this.currentPage}`).then(r=>{
if(r.data.statusCode==1){
this.ComponentData=r.data.data.rows;
this.total=r.data.data.total;
}
}).catch(error=>{
console.error(error);
})
}
},
created(){
this.show();
}
})
</script>
</body>
</html>
(2)后端页面同修改
(3)实现效果
(3)添加数据
(1)前端代码
添加数据时需要点击超链接添加零件跳转到insert.html页面,在insert.html页面中实现数据的添加,利用addP方法实现insert接口实现数据的添加,添加完成后跳转到show.html页面。
show.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="./js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="element-ui/index.css">
<script src="./element-ui/index.js"></script>
</head>
<body>
<h1 style="text-align: center">零件信息表</h1>
<div id="app">
<div style="text-align: center"><a href="insert.html">添加零件</a></div>
<el-table
:data="ComponentData.filter(data => !search || data.cname.toLowerCase().includes(search.toLowerCase()))"
style="width: 80%;margin: auto " >
<el-table-column
align="center"
label="零件号"
prop="cno">
</el-table-column>
<el-table-column
align="center"
label="零件名"
prop="cname">
</el-table-column>
<el-table-column
align="center"
label="尺寸"
prop="csize">
</el-table-column>
<el-table-column
align="center"
label="单价"
prop="cprice">
</el-table-column>
<el-table-column
align="center"
label="描述"
prop="ctext">
</el-table-column>
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[5, 10, 15, 20,25]"
:page-size="pageSize"
layout="sizes, prev, pager, next"
:total="total">
</el-pagination>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
ComponentData:[],
search:'',
currentPage: 1,// 当前页码
pageSize:5,
total:100,
index:''
}
},
methods:{
handleEdit(row) {
window.location.href="update.html?con="+row.cno;
},
handleDelete(row) {
if(window.confirm("你确定要删除这条数据吗?")){
axios.post(`/delete/${row.cno}`).then(r=>{
if(r.data.statusCode==1){
alert("删除成功!")
this.show();
}
}).catch(error=>{
console.error(error);
})
}
},
handleSizeChange(val) {
this.pageSize=val;
this.show();
},
handleCurrentChange(val) {
this.currentPage =val;
this.show();
},
show(){
axios(`/page/${this.pageSize}/${this.currentPage}`).then(r=>{
if(r.data.statusCode==1){
this.ComponentData=r.data.data.rows;
this.total=r.data.data.total;
}
}).catch(error=>{
console.error(error);
})
}
},
created(){
this.show();
}
})
</script>
</body>
</html>
insert.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="./js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="element-ui/index.css">
<script src="./element-ui/index.js"></script>
</head>
<body>
<div id="app" style="width: 500px">
<ul style="list-style: none ">
<li>
<el-input v-model="Plist.cno" placeholder="零件号"></el-input>
</li>
<li>
<el-input v-model="Plist.cname" placeholder="零件名"></el-input>
</li>
<li>
<el-input v-model="Plist.csize" placeholder="尺寸"></el-input>
</li>
<li>
<el-input v-model="Plist.cprice" placeholder="单价"></el-input>
</li>
<li>
<el-input v-model="Plist.ctext" placeholder="描述"></el-input>
</li>
<li>
<br>
<el-button type="success" v-on:click="addP">提交</el-button>
</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
Plist:{}
}
},
methods:{
addP(){
axios.post("/insert",this.Plist).then(r=>{
if(r.data.statusCode==1){
location.href='show.html';
}
else{
console.log(r.data.message);
}
}).catch(error=>{
console.error(error);
})
}
},
created(){
}
})
</script>
</body>
</html>
(2)后端代码同上
(3)实现效果
4.修改错误
@GetMapping("/peom1/{page}/{pageSize}")
public Result findAll_chaxun(@PathVariable Integer page,
@PathVariable Integer pageSize,
String author,
String style){
PageBean pageBean = peomFenyeService.list_chaxun(page,pageSize,author,style);
return Result.success(pageBean);
}
上述代码中并没有为author、style参数定义来源,并不能从任何地方获取author、style参数。可以将他们修改为以路径参数的方式传递参数。修改后的代码如下:
@GetMapping("/peom1/{page}/{pageSize}")
public Result findAll_chaxun(@PathVariable Integer page,
@PathVariable Integer pageSize,
@PathVariable String author,
@PathVariable String style){
PageBean pageBean = peomFenyeService.list_chaxun(page,pageSize,author,style);
return Result.success(pageBean);
}