使用spring boot写一个含有增删改查的页面
首先创建一个spring boot项目使用
mybatis puls 自动生成代码
提前准备好数据库数据
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sms_advertise
-- ----------------------------
DROP TABLE IF EXISTS `sms_advertise`;
CREATE TABLE `sms_advertise` (
`id` int(0) NOT NULL AUTO_INCREMENT COMMENT '广告编号',
`name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '广告名称',
`position_id` int(0) NOT NULL COMMENT '位置编号',
`status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '上下线状态:0->下线;1->上线',
`order_count` int(0) NULL DEFAULT NULL COMMENT '下单数',
`url` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '链接地址',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sms_advertise
-- ----------------------------
INSERT INTO `sms_advertise` VALUES (1, '广告01', 1, '上线', 666, 'baidu1.com');
INSERT INTO `sms_advertise` VALUES (2, '广告02', 2, '下线', 111, 'baidu2.com');
INSERT INTO `sms_advertise` VALUES (3, '广告03', 3, '上线', 111, 'baidu3.com');
INSERT INTO `sms_advertise` VALUES (4, '广告04', 4, '下线', 111, 'baidu4.com');
INSERT INTO `sms_advertise` VALUES (5, '广告05', 1, '上线', 111, 'baidu5.com');
INSERT INTO `sms_advertise` VALUES (6, '广告06', 2, '上线', 111, 'baidu6.com');
INSERT INTO `sms_advertise` VALUES (7, '广告07', 3, '上线', 111, 'baidu7.com');
INSERT INTO `sms_advertise` VALUES (8, '广告08', 4, '上线', 111, 'baidu8.com');
INSERT INTO `sms_advertise` VALUES (9, '广告09', 1, '上线', 111, 'baidu1.com');
INSERT INTO `sms_advertise` VALUES (10, '广告10', 2, '上线', 111, 'baidu2.com');
INSERT INTO `sms_advertise` VALUES (11, '广告11', 1, '上线', 111, 'jd1.com');
INSERT INTO `sms_advertise` VALUES (12, 'gg119999', 1, '下线', 222, 'jd2.com');
-- ----------------------------
-- Table structure for sms_position
-- ----------------------------
DROP TABLE IF EXISTS `sms_position`;
CREATE TABLE `sms_position` (
`pid` int(0) NOT NULL AUTO_INCREMENT COMMENT '位置编号',
`pname` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '广告位置名称',
PRIMARY KEY (`pid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sms_position
-- ----------------------------
INSERT INTO `sms_position` VALUES (1, '首页顶部');
INSERT INTO `sms_position` VALUES (2, '首页底部');
INSERT INTO `sms_position` VALUES (3, '首页左侧');
INSERT INTO `sms_position` VALUES (4, '首页右侧');
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Table structure for sms_position
-- ----------------------------
DROP TABLE IF EXISTS `sms_position`;
CREATE TABLE `sms_position` (
`pid` int(0) NOT NULL AUTO_INCREMENT COMMENT '位置编号',
`pname` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '广告位置名称',
PRIMARY KEY (`pid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sms_position
-- ----------------------------
INSERT INTO `sms_position` VALUES (1, '首页顶部');
INSERT INTO `sms_position` VALUES (2, '首页底部');
INSERT INTO `sms_position` VALUES (3, '首页左侧');
INSERT INTO `sms_position` VALUES (4, '首页右侧');
SET FOREIGN_KEY_CHECKS = 1;
导入依赖(此项目的所有依赖)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.aaa</groupId>
<artifactId>springboot_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_test</name>
<description>springboot_test</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
<!--mybatis和springboot整合的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!--pageHelper的依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.5</version>
</dependency>
<!--mp的依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--引入swagger2依赖-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
<!--图形化依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<!--mp的代码生成器依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
</dependencies>
</project>
配置springboot配置文件
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=1234
spring.datasource.druid.url=jdbc:mysql://localhost:3306/qy666?serverTimezone=Asia/Shanghai
spring.datasource.druid.initial-size=5
spring.datasource.druid.max-active=10
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis.mapper-locations=classpath:/mapper/*.xml
配置接口文档和mybatis puls
@Configuration
public class MpConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
@Configuration
public class SwaggerConfig {
@Bean
public Docket docket(){
Docket docket=new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getInfo())//设置文档信息
.select()//指定哪些包生成接口文档
.apis(RequestHandlerSelectors.basePackage("com.aaa.controller"))
.build();
return docket;
}
private ApiInfo getInfo(){
Contact DEFAULT_CONTACT = new Contact("高姚燕", "http://www.wjy.com", "110@qq.com");
ApiInfo info = new ApiInfo("项目名称", "项目简介,接口文档测试", "自定义版本号", "termsOfServiceUrl:http://www.jd.com",
DEFAULT_CONTACT, "Apache 2.0", "http://www.baidu.com", new ArrayList<VendorExtension>());
return info;
}
}
创建生成代码类,配置想要的代码生成
配置自动生成代码
public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/qy666?serverTimezone=Asia/Shanghai", "root", "1234")
.globalConfig(builder -> {
builder.author("szy") // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D:/qy168/springboot_test/src/main/java"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.aaa") // 设置父包名
//.moduleName("system") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, "D:/qy168/springboot_test/src/main/resources/mapper")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("sms_advertise","sms_position") // 设置需要生成的表名
.addTablePrefix("sms_"); // 设置过滤表前缀
builder.entityBuilder().enableLombok(); //是否开启lombok
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
代码注释中有详细的解释说明,运行代码后就会生成想要的代码
mybatis puls 联表查询
mp只能自动对单表完成增删改查的操作(如果仅操作单表的增删改查,那么只需要mp自动生成代码后就可以不再修改了),联表查询的话还要手动写代码。
此项目中为广告表和位置表的联表分页查询。
dao层
@Mapper
public interface AdvertiseMapper extends BaseMapper<Advertise> {
IPage<Advertise> selectPageWithAd(IPage<Advertise> page, @Param("ew") Wrapper<Advertise> queryWrapper);
}
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.aaa.mapper.AdvertiseMapper">
<resultMap id="baseAdMapper" type="com.aaa.entity.Advertise" autoMapping="true">
<id property="id" column="id"/>
<result property="positionId" column="position_id"/>
<result property="orderCount" column="order_count"/>
<association property="position" javaType="com.aaa.entity.Position" autoMapping="true">
<id property="pid" column="pid"/>
<result property="pname" column="pname"/>
</association>
</resultMap>
<select id="selectPageWithAd" resultMap="baseAdMapper">
select * from sms_advertise a join sms_position p on a.position_id= p.pid
<if test="ew!=null and ew.customSqlSegment!=null">
${ew.customSqlSegment}
</if>
</select>
</mapper>
Service层
public interface IAdvertiseService extends IService<Advertise> {
public Result findAll(Integer current, Integer pageSize, Advertise advertise);
}
@Service
public class AdvertiseServiceImpl extends ServiceImpl<AdvertiseMapper, Advertise> implements IAdvertiseService {
@Autowired
private AdvertiseMapper advertiseMapper;
@Override
public Result findAll(Integer current, Integer pageSize, Advertise advertise) {
IPage<Advertise> page = new Page<>(current, pageSize);
QueryWrapper<Advertise> wrapper = new QueryWrapper<>();
wrapper.like(StringUtils.hasText(advertise.getStatus()),"status",advertise.getStatus());
IPage<Advertise> page1 = advertiseMapper.selectPageWithAd(page,wrapper);
return new Result(200,"查询成功",page1);
}
}
vo层
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("统一json对象")
public class Result {
@ApiModelProperty(value = "状态码:200表示成功 500表示失败")
private Integer code;
@ApiModelProperty(value = "提示的消息内容")
private String msg;
@ApiModelProperty(value = "响应的数据")
private Object data;
}
因为生成代码时 添加了接口文档代码,所以注解也要写上相应注解。
controller
controller层就需要自己手动写自己的需求了,mp只能为我们自动生成一个模版。
@RestController
@RequestMapping("/ad")
@Api
public class AdvertiseController {
@Autowired
private IAdvertiseService iAdvertiseService;
@ApiOperation(value = "添加广告")
@PostMapping("/insert")
public Result insert(@RequestBody Advertise advertise){
return new Result(200,"增加成功",iAdvertiseService.save(advertise));
}
@ApiOperation(value = "修改广告")
@PostMapping("/update")
public Result update(@RequestBody Advertise advertise){
return new Result(200,"更新成功",iAdvertiseService.updateById(advertise));
}
@ApiOperation(value = "根据id删除员工")
@ApiImplicitParams(
value = {
@ApiImplicitParam(name="id",value = "广告编号",required = true,dataType = "integer",paramType = "integer")
}
)
@DeleteMapping("/delete")
public Result deleteById(Integer id){
return new Result(200,"删除成功",iAdvertiseService.removeById(id));
}
@ApiOperation(value = "根据id查找广告")
@ApiImplicitParams(
value = {
@ApiImplicitParam(name="id",value = "广告编号",required = true,dataType = "integer",paramType = "integer")
}
)
@GetMapping("/getById")
public Result getById(Integer id){
return new Result(200,"查询成功",iAdvertiseService.getById(id));
}
@ApiOperation(value = "查询所有广告")
@ApiImplicitParams(
value = {
@ApiImplicitParam(name="current",value = "当前页",required = true,dataType = "Integer",paramType = "Integer"),
@ApiImplicitParam(name="pageSize",value = "当前页大小",required = true,dataType = "Integer",paramType = "Integer"),
@ApiImplicitParam(name="advertise",value = "广告对象",required = true,dataType = "Object",paramType = "Object")
}
)
@PostMapping("/getAll/{current}/{pageSize}")
public Result getAll(@PathVariable Integer current,@PathVariable Integer pageSize,@RequestBody Advertise advertise){
return iAdvertiseService.findAll(current, pageSize, advertise);
}
}
@RestController
@RequestMapping("/position")
public class PositionController {
@Autowired
private IPositionService iPositionService;
@ApiOperation(value = "查询所有位置信息")
@GetMapping("/list")
public Result getAll(){
return new Result(200,"查询成功",iPositionService.list());
}
}
现在开始编写前端代码
在element ui 中引入所需文件
编写ad.html页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="/js/vue.js"></script>
<script type="text/javascript" src="/js/index.js"></script>
<script type="text/javascript" src="/js/axios.min.js"></script>
<link type="text/css" rel="stylesheet" href="/css/index.css">
</head>
<body>
<div id="app">
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
<el-form-item label="名称">
<el-input v-model="searchForm.status" placeholder="状态"></el-input>
</el-form-item>
<el-button type="primary" round size="small" @click="searchEmp">搜索</el-button>
<el-button type="success" round size="small" @click="add" >添加</el-button>
</el-form-item>
</el-form>
<el-table
:data="tableData"
border
style="width: 100%">
</el-table-column>
<el-table-column
prop="name"
label="广告名称"
>
</el-table-column>
<el-table-column
prop="position.pname"
label="位置"
>
</el-table-column>
<el-table-column
prop="status"
label="状态">
</el-table-column>
<el-table-column
prop="orderCount"
label="点击量">
</el-table-column>
<el-table-column
prop="url"
label="链接">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
>
<template slot-scope="scope">
<el-button type="warning" round size="small" @click="edit(scope.row)">修改</el-button>
<el-button type="danger" round size="small" @click="remove(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
@close="closeAdd"
>
<el-form ref="form" :model="form" label-width="80px" :rules="myrules">
<el-form-item label="广告名称" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="位置" prop="positionId">
<el-select v-model="form.positionId" placeholder="请选择位置">
<el-option v-for="position in positions" :label="position.pname" :value="position.pid"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="位置" prop="positionId">
<el-input v-model="form.positionId"></el-input>
</el-form-item>-->
<el-form-item label="状态" prop="status">
<el-input v-model="form.status"></el-input>
</el-form-item>
<el-form-item label="点击量" prop="orderCount">
<el-input v-model="form.orderCount"></el-input>
</el-form-item>
<el-form-item label="链接" prop="url">
<el-input v-model="form.url"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmAdd('form')">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="提示"
:visible.sync="editdialogVisible"
width="30%"
>
<el-form ref="editform" :model="editform" label-width="80px" :rules="myrules">
<el-form-item label="广告名称" prop="name">
<el-input v-model="editform.name"></el-input>
</el-form-item>
<el-form-item label="位置" prop="positionId">
<el-select v-model="editform.positionId" placeholder="请选择位置">
<el-option v-for="position in positions" :label="position.pname" :value="position.pid"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="位置" prop="positionId">
<el-input v-model="editform.positionId"></el-input>
</el-form-item>-->
<el-form-item label="状态" prop="status">
<el-input v-model="editform.status"></el-input>
</el-form-item>
<el-form-item label="点击量" prop="orderCount">
<el-input v-model="editform.orderCount"></el-input>
</el-form-item>
<el-form-item label="链接" prop="url">
<el-input v-model="editform.url"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editdialogVisible = false">取 消</el-button>
<el-button type="primary" @click="update">确 定</el-button>
</span>
</el-dialog>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="current"
:page-sizes="[5, 10, 15, 20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</body>
<script>
var app = new Vue({
el: "#app",
data: {
tableData: [],
searchForm: {},
form:{},
editform:{},
current: 1,
pageSize: 5,
total: 0,
dialogVisible:false,
editdialogVisible:false,
positions:[],
myrules:{
name:[
{ required: true, message: '请输入广告名', trigger: 'blur' }
],
positionId:[
{ required: true, message: '请选择位置', trigger: 'blur' }
] ,
status:[
{ required: true, message: '请输入状态', trigger: 'blur' }
] ,
orderCount:[
{ required: true, message: '请输入点击率', trigger: 'blur' }
],
url:[
{ required: true, message: '请输入链接', trigger: 'blur' }
]
},
},
created(){
this.initTable();
this.getAllPosition();
},
methods:{
initTable(){
axios.post("/ad/getAll/"+this.current+"/"+this.pageSize,this.searchForm).then(result=>{
//console.log(result);
this.tableData=result.data.data.records;
this.total=result.data.data.total;
})
},
searchEmp(){
this.initTable();
},
add(){
this.dialogVisible=true;
},
confirmAdd(form){
this.$refs[form].validate((valid) => {
if (valid) {
axios.post("/ad/insert",this.form).then(result=>{
if(result.data.data==1){
this.$message.success("添加成功");
this.dialogVisible=false;
this.initTable();
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
closeAdd(){
this.$refs.form.resetFields();
},
edit(row){
this.editdialogVisible=true;
this.editform=row;
},
update(){
axios.post("/ad/update",this.editform).then(result=>{
this.editdialogVisible=false
this.initTable()
if(result.data.data){
this.$message.success("修改成功");
}else {
this.$message.error("修改失败");
}
})
},
getAllPosition(){
axios.get("/position/list").then(result=>{
this.positions=result.data.data;
})
},
remove(id){
this.$confirm('是否删除该记录?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.delete("/ad/delete?id="+id).then(result=>{
if(result.data.data==1){
this.$message.success("删除成功");
this.initTable();
}
})
})
},
handleSizeChange(val) {
this.pageSize=val;
this.initTable();
},
handleCurrentChange(val) {
this.current=val;
this.initTable();
}
},
})
</script>
</html>
项目整体
启动 localhost:8080/ad.html
启动 localhost:8080/doc.html