1.项目架构
2.config配置
JdbcConfig
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager ds = new DataSourceTransactionManager(dataSource);
return ds;
}
}
MyBatisConfig
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setTypeAliasesPackage("cn.itaxu.domain");
factoryBean.setDataSource(dataSource);
return factoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("cn.itaxu.dao");
return msc;
}
}
ServletConfig
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
// 加载spring配置
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
// 加载springMVC配置
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
// 设置哪些方法归属springMVC处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 处理POST请求中文乱码问题
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter("UTF-8");
return new Filter[]{filter};
}
}
SpringConfig
@Configuration
@ComponentScan("cn.itaxu.service")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MyBatisConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
SpringMvcConfig
@Configuration
@ComponentScan({"cn.itaxu.controller","cn.itaxu.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
SpringMvcSupport
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/img/**").addResourceLocations("/img/");
}
}
3.controller控制
BrandController
@RestController
@RequestMapping("/brands")
public class BrandController {
@Autowired
private BrandService brandService;
@PostMapping
public Result save(@RequestBody Brand brand){
boolean flag = brandService.save(brand);
return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
}
@DeleteMapping("/{id}")
public Result deleteById(@PathVariable Integer id){
boolean flag = brandService.deleteById(id);
return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@DeleteMapping
public Result deleteMultiply(@RequestBody int[] ids){
boolean flag = brandService.deleteMultiply(ids);
return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@PutMapping
public Result update(@RequestBody Brand brand){
System.out.println(brand);
boolean flag = brandService.update(brand);
return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id){
Brand brand = brandService.getById(id);
Integer code =brand != null ? Code.GET_OK:Code.GET_ERR;
String msg = brand != null ? "success":"fail";
return new Result(code,brand,msg);
}
@GetMapping
public Result getAll(){
List<Brand> brandList = brandService.getAll();
Integer code = brandList != null ? Code.GET_OK:Code.GET_ERR;
String msg = brandList != null ? "success":"fail";
return new Result(code,brandList,msg);
}
@PostMapping("/{currentPage}/{pageSize}")
public Result selectByPageAndCondition(@PathVariable int currentPage,@PathVariable int pageSize,
@RequestBody Brand brand) {
PageBean<Brand> pageBean = brandService.selectByPageAndCondition(currentPage, pageSize, brand);
Integer code = pageBean != null ? Code.GET_OK:Code.GET_ERR;
String msg = pageBean != null ? "success":"fail";
return new Result(code,pageBean,msg);
}
}
Code 响应状态码
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer GET_ERR = 20040;
public static final Integer SYSTEM_ERR = 50001;
public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
public static final Integer SYSTEM_UNKNOW_ERR = 59999;
public static final Integer BUSINESS_ERR = 60002;
}
ProjectExceptionAdvice 项目异常通知
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
// 记录日志
// 发送消息给运维
// 发送消息给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),"null","系统异常");
}
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
return new Result(ex.getCode(),"null","业务异常");
}
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
// 记录日志
// 发送消息给运维
// 发送消息给开发人员,ex对象发送给开发人员
return new Result(Code.SYSTEM_UNKNOW_ERR,"null","系统繁忙,请稍后再试!");
}
}
Result 统一格式数据
public class Result {
private Object data;
private Integer code;
private String msg;
public Result() {
}
public Result(Integer code,Object data) {
this.data = data;
this.code = code;
}
public Result(Integer code, Object data, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
4.exception 细化异常
BusinessException 业务异常
public class BusinessException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
SystemException 系统异常
public class SystemException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public SystemException(Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
5.service
BrandService接口
@Transactional
public interface BrandService {
/**
* 添加数据
* @param brand
* @return
*/
public boolean save(Brand brand);
/**
* 根据id删除
* @param id
* @return
*/
public boolean deleteById(Integer id);
/**
* 根据ids批量删除
* @param ids
* @return
*/
public boolean deleteMultiply(@Param("ids") int[] ids);
/**
* 修改数据
* @param brand
* @return
*/
public boolean update(Brand brand);
/**
* 查询单条
* @param id
* @return
*/
public Brand getById(Integer id);
/**
* 查询所有
* @return
*/
public List<Brand> getAll();
/**
* 分页查询
* @param currentPage
* @param pageSize
* @return
*/
PageBean<Brand> selectByPage(int currentPage, int pageSize);
/**
* 分页条件查询
* @param currentPage
* @param pageSize
* @param brand
* @return
*/
PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand);
}
BrandServiceImpl
@Service
public class BrandServiceImpl implements BrandService {
@Autowired
private BrandDao brandDao;
@Override
public boolean save(Brand brand) {
return brandDao.save(brand) > 0;
}
@Override
public boolean deleteById(Integer id) {
return brandDao.deleteById(id) > 0;
}
@Override
public boolean deleteMultiply(int[] ids) {
return brandDao.deleteMultiply(ids) > 0;
}
@Override
public boolean update(Brand brand) {
return brandDao.update(brand) > 0;
}
@Override
public Brand getById(Integer id) {
return brandDao.getById(id);
}
@Override
public List<Brand> getAll() {
return brandDao.getAll();
}
@Override
public PageBean<Brand> selectByPage(int currentPage, int pageSize) {
int begin = (currentPage-1) * pageSize;
int size = pageSize;
List<Brand> rows = brandDao.selectByPage(begin, size);
int totalCount = brandDao.selectTotalCount();
PageBean<Brand> pageBean = new PageBean<Brand>();
pageBean.setRows(rows);
pageBean.setTotalCount(totalCount);
return pageBean;
}
@Override
public PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand) {
int begin = (currentPage-1) * pageSize;
int size = pageSize;
// 处理模糊查询
String brandName = brand.getBrandName();
if (brandName!=null&&brandName.length()>0){
brand.setBrandName("%"+brandName+"%");
}
String companyName = brand.getCompanyName();
if (companyName!=null&&companyName.length()>0){
brand.setCompanyName("%"+companyName+"%");
}
// 查询当前页数据
List<Brand> brandList = brandDao.selectByPageAndCondition(begin, size, brand);
// 查询当前页总记录条数
int totalCount = brandDao.selectTotalCountByCondition(brand);
// 封装PageBean
PageBean<Brand> pageBean = new PageBean<>(brandList,totalCount);
return pageBean;
}
}
6.前端代码
<div id="app">
<!-- 导航菜单-->
<el-menu
:default-active="activeIndex2"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<template>
<h3 align="center"><img src="../img/E-commerce.png" width="50" height="50" align="center">
电商后台数据模型
</h3>
</template>
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">后台品牌模型</el-menu-item>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
</el-menu>
<!-- 搜索表单-->
<el-form :inline="true" :model="brand" class="demo-form-inline">
<el-form-item label="当前状态">
<el-select v-model="brand.status" placeholder="当前状态">
<el-option label="启用" value="1"></el-option>
<el-option label="禁用" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="企业名称">
<el-input v-model="brand.companyName" placeholder="企业名称"></el-input>
</el-form-item>
<el-form-item label="品牌名称">
<el-input v-model="brand.brandName" placeholder="品牌名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
<!-- 按钮-->
<el-row style="margin-left: 20%">
<el-button type="danger" plain @click="deleteBrandByIds">批量删除</el-button>
<el-button type="primary" plain @click="dialogVisible = true">新增</el-button>
</el-row>
<!-- 添加数据的对话框表单-->
<el-dialog
title="编辑品牌"
:visible.sync="dialogVisible"
width="30%"
>
<el-form ref="form" :model="brand_add" label-width="80px">
<el-form-item label="品牌名称">
<el-input v-model="brand_add.brandName"></el-input>
</el-form-item>
<el-form-item label="企业名称">
<el-input v-model="brand_add.companyName"></el-input>
</el-form-item>
<el-form-item label="排序">
<el-input v-model="brand_add.ordered"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input type="textarea" v-model="brand_add.description"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-switch
v-model="brand_add.status"
active-value="1"
inactive-value="0"
>
</el-switch>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addBrand">提交</el-button>
<el-button @click="cancelAdd">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 修改数据的对话框表单-->
<el-dialog
title="修改数据"
:visible.sync="updateDialogVisible"
width="30%">
<el-form ref="form" :model="update" label-width="80px">
<el-form-item label="品牌名称">
<el-input v-model="update.brandName"></el-input>
</el-form-item>
<el-form-item label="企业名称">
<el-input v-model="update.companyName"></el-input>
</el-form-item>
<el-form-item label="排序">
<el-input v-model="update.ordered"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input type="textarea" v-model="update.description"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-switch
v-model="update.status"
active-value="1"
inactive-value="0">
</el-switch>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateBrand">提交</el-button>
<el-button @click="cancel">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<h4 align="center"><img src="../img/product.png" width="50" height="50" align="center"><font color="gray">产品列表
</font></h4>
<!-- 表格-->
<template>
<el-table
:data="tableData"
style="width: 100%"
:row-class-name="tableRowClassName"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
>
</el-table-column>
<el-table-column
type="index"
width="50">
</el-table-column>
<el-table-column
prop="brandName"
label="品牌名称"
align="center"
>
</el-table-column>
<el-table-column
prop="companyName"
label="企业名称"
align="center"
>
</el-table-column>
<el-table-column
prop="ordered"
label="排序"
align="center"
>
</el-table-column>
<el-table-column
prop="description"
label="备注"
align="center"
>
</el-table-column>
<el-table-column
prop="statusStr"
label="当前状态"
align="center"
>
</el-table-column>
<el-table-column
prop="address"
label="操作"
align="center"
>
<el-row>
<el-button type="primary" @click="modify">修改</el-button>
<el-button type="danger" @click="deleteById">删除</el-button>
</el-row>
</el-table-column>
</el-table>
</template>
<!-- 分页工具条-->
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalCount">
</el-pagination>
</div>
</div>
js
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.13/dist/vue.js"></script>
<script src="https://cdn.staticfile.org/axios/1.1.3/axios.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.10/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://cdn.staticfile.org/element-ui/2.15.10/index.js"></script>
<script>
new Vue({
el:"#app",
mounted(){
//当页面加载完毕后,发送异步请求
this.selectAll();
},
methods: {
// 查询所有品牌数据
selectAll(){
axios({
method:"post",
url:`/brands/${this.currentPage}/${this.pageSize}`,
data:this.brand,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}).then((resp)=>{
if (resp.data.code == 20041) {
this.tableData = resp.data.data.rows;
this.totalCount = resp.data.data.totalCount
}else if (resp.data.code == 20040){
this.$message.error('获取数据失败!').center = true;
}else {
this.$message.error(resp.data.msg).center = true;
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
cancelAdd(){
this.dialogVisible = false;
// 用户点击了取消按钮
this.$message({
showClose: true,
message: '您取消了添加数据!',
center:true
});
},
modify(){
for (let i = 0; i < this.multipleSelection.length; i++) {
var selectionElement = this.multipleSelection[i];
this.update.id = selectionElement.id;
}
if (this.update.id == '' || this.update.id == null){
this.$message({
showClose: true,
message: '请选中您要修改的数据!',
type: 'error',
center:true,
});
return;
}
axios.get(`/brands/${this.update.id}`).then((resp)=>{
if (resp.data.code==20041){
this.update = resp.data.data;
this.updateDialogVisible = true;
}
});
},
cancel(){
this.updateDialogVisible = false;
this.$message({
showClose: true,
message: '您已取消修改',
center:true
});
},
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
},
// 复选框选中后执行的方法
handleSelectionChange(val) {
this.multipleSelection = val;
},
// 查询的方法
onSubmit() {
this.selectAll();
},
// 添加数据
addBrand(){
axios({
method:'post',
url:'/brands',
data:this.brand_add,
headers:{
'Content-Type':'application/json;charset=UTF-8'
}
}).then( (resp) => {
if (resp.data.code==20011){
// 关闭添加数据对话框表单
this.dialogVisible = false;
// 弹出提示信息
this.$message({
message: '添加数据成功!',
type: 'success',
center: true
});
}else if (resp.data.code==20010){
this.$message.error("添加数据失败!").center = true;
}else {
this.$message.error(resp.data.msg).center = true;
}
}).finally(()=>{
// 重新查询数据
this.selectAll();
this.resetForm(this.brand_add)
})
},
// 更新数据
updateBrand(){
axios.put("/brands",this.update).then(resp=>{
if (resp.data.code == 20031) {
this.updateDialogVisible = false;
this.$message({
showClose: true,
message: '更新数据成功!',
type: 'success',
center: true
});
}else if (resp.data.code == 20030){
this.$message.error("更新数据失败!").center = true
}else {
this.$message.error(resp.data.msg).center = true
}
}).finally(()=>{
this.selectAll();
});
this.update.id = '';
},
// 批量删除
deleteBrandByIds(){
// 弹出确认提示框
this.$confirm('此操作将永久删除数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 1.创建id数组,从this.multipleSelection中获取
for (let i = 0; i < this.multipleSelection.length; i++) {
let selectionElement = this.multipleSelection[i];
this.selectedIds[i] = selectionElement.id
}
if (this.selectedIds.length < 1){
this.$message({
showClose: true,
message: '请选中您要删除的数据!',
type: 'error',
center:true,
});
return;
}
// 2.发送ajax请求
axios({
method: 'delete',
url: '/brands',
data:this.selectedIds,
headers:{
'Content-Type':'application/json;charset=utf-8'
}
}).then( (resp) => {
if (resp.data.code == 20021) {
// 重新查询数据
this.selectAll();
this.$message({
type: 'success',
message: '删除成功!',
center: true
});
}else if (resp.data.code == 20020){
this.$message.error("删除失败!").center = true
}else {
this.$message.error(resp.data.msg).center = true
}
});
}).catch(() => {
// 用户点击取消按钮
this.$message({
type: 'info',
message: '您已取消删除',
center:true
});
});
// 清除数组
this.selectedIds = [];
},
// 删除单条数据
deleteById(){
for (let i = 0; i < this.multipleSelection.length; i++) {
var selectionElement = this.multipleSelection[i];
this.selectedId = selectionElement.id;
}
if (this.selectedId == '' || this.selectedId == null){
this.$message({
showClose: true,
message: '请选中您要删除的数据!',
type: 'error',
center:true,
});
return;
}
axios.delete(`/brands/${this.selectedId}`)
.then(resp=>{
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (resp.data.code == 20021) {
this.$message({
type: 'success',
message: '删除成功!',
center: true
});
}else if (resp.data.code == 20020){
this.$message.error("删除失败!").center = true
}else {
this.$message.error(resp.data.msg).center = true
}
}).catch(() => {
this.$message({
type: 'info',
message: '您已取消删除',
center:true,
});
});
}).finally(()=>{
// 重新查询数据
this.selectAll();
});
// 清空selectedId
this.selectedId = ''
},
// 分页
handleSizeChange(val) {
// 重新设置每页显示条数
this.pageSize = val;
this.selectAll();
},
handleCurrentChange(val) {
// 重新设置当前页码
this.currentPage = val;
this.selectAll();
}
},
data() {
return {
// 被选中的单个id
selectedId:'',
// 总记录条数
totalCount:'',
// 每页显示条数
pageSize:10,
// 修改数据表单显示状态
updateDialogVisible:false,
// 当前页码
currentPage:1,
// 控制添加数据对话框表单是否显示
dialogVisible: false,
// 品牌模型数据
brand: {
companyName: '',
status: '',
brandName:'',
id:'',
ordered:'',
description:'',
},
// 更新模型数据
update: {
companyName: '',
status: '',
brandName:'',
id:'',
ordered:'',
description:'',
},
// 添加模型数据
brand_add: {
companyName: '',
status: '',
brandName:'',
id:'',
ordered:'',
description:'',
},
// 复选框选中数据集合
multipleSelection:[],
// 被选中的id数组
selectedIds:[],
// 表格数据
tableData: []
}
},
})
</script>
7.页面展示
结语:
希望这些能够帮助到你的学习!!! 如果有需要源码的私信我