东莞网站制作建设公司,wordpress和django哪个好,门户网站建设经济交流材料,福州餐饮网站建设文章目录 1、功能介绍2、技术栈3、环境准备3.1、数据库准备3.2、在新建web项目中导入依赖3.3、编写Mybatis文件3.4、编写pojo类3.5、编写Mybatis工具类3.6、导入前端素材#xff08;element-ui vue.js axios.js#xff09;3.7、前端页面 4、功能实现4.1、查询所有… 文章目录 1、功能介绍2、技术栈3、环境准备3.1、数据库准备3.2、在新建web项目中导入依赖3.3、编写Mybatis文件3.4、编写pojo类3.5、编写Mybatis工具类3.6、导入前端素材element-ui vue.js axios.js3.7、前端页面 4、功能实现4.1、查询所有功能4.2、添加数据功能4.3、修改数据功能4.4、删除数据功能4.5、批量删除功能4.6、条件分页查询 1、功能介绍 以上是我们在综合案例要实现的功能。对数据的除了对数据的增删改查功能外还有一些复杂的功能如 批量删除、分页查询、条件查询 等功能
批量删除 功能每条数据前都有复选框当我选中多条数据并点击 批量删除 按钮后会发送请求到后端并删除数据库中指定的多条数据。分页查询 功能当数据库中有很多数据时我们不可能将所有的数据展示在一页里这个时候就需要分页展示数据。条件查询 功能数据库量大的时候我们就需要精确的查询一些想看到的数据这个时候就需要通过条件查询。
2、技术栈
servletVueaxiosMybatisTomcat
3、环境准备
3.1、数据库准备
use brand;
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand (-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20),-- 排序字段ordered int,-- 描述信息description varchar(100),-- 状态0禁用 1启用status int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values(华为, 华为技术有限公司, 100, 万物互联, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(格力, 格力电器股份有限公司, 30, 让世界爱上中国造, 1),(阿里巴巴, 阿里巴巴集团控股有限公司, 10, 买买买, 1),(腾讯, 腾讯计算机系统有限公司, 50, 玩玩玩, 0),(百度, 百度在线网络技术公司, 5, 搜搜搜, 0),(京东, 北京京东世纪贸易有限公司, 40, 就是快, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(三只松鼠, 三只松鼠股份有限公司, 5, 好吃不上火, 0),(华为, 华为技术有限公司, 100, 万物互联, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(格力, 格力电器股份有限公司, 30, 让世界爱上中国造, 1),(阿里巴巴, 阿里巴巴集团控股有限公司, 10, 买买买, 1),(腾讯, 腾讯计算机系统有限公司, 50, 玩玩玩, 0),(百度, 百度在线网络技术公司, 5, 搜搜搜, 0),(京东, 北京京东世纪贸易有限公司, 40, 就是快, 1),(华为, 华为技术有限公司, 100, 万物互联, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(格力, 格力电器股份有限公司, 30, 让世界爱上中国造, 1),(阿里巴巴, 阿里巴巴集团控股有限公司, 10, 买买买, 1),(腾讯, 腾讯计算机系统有限公司, 50, 玩玩玩, 0),(百度, 百度在线网络技术公司, 5, 搜搜搜, 0),(京东, 北京京东世纪贸易有限公司, 40, 就是快, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(三只松鼠, 三只松鼠股份有限公司, 5, 好吃不上火, 0),(华为, 华为技术有限公司, 100, 万物互联, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(格力, 格力电器股份有限公司, 30, 让世界爱上中国造, 1),(阿里巴巴, 阿里巴巴集团控股有限公司, 10, 买买买, 1),(腾讯, 腾讯计算机系统有限公司, 50, 玩玩玩, 0),(百度, 百度在线网络技术公司, 5, 搜搜搜, 0),(京东, 北京京东世纪贸易有限公司, 40, 就是快, 1),(华为, 华为技术有限公司, 100, 万物互联, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(格力, 格力电器股份有限公司, 30, 让世界爱上中国造, 1),(阿里巴巴, 阿里巴巴集团控股有限公司, 10, 买买买, 1),(腾讯, 腾讯计算机系统有限公司, 50, 玩玩玩, 0),(百度, 百度在线网络技术公司, 5, 搜搜搜, 0),(京东, 北京京东世纪贸易有限公司, 40, 就是快, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(三只松鼠, 三只松鼠股份有限公司, 5, 好吃不上火, 0),(华为, 华为技术有限公司, 100, 万物互联, 1),(小米, 小米科技有限公司, 50, are you ok, 1),(格力, 格力电器股份有限公司, 30, 让世界爱上中国造, 1),(阿里巴巴, 阿里巴巴集团控股有限公司, 10, 买买买, 1),(腾讯, 腾讯计算机系统有限公司, 50, 玩玩玩, 0),(百度, 百度在线网络技术公司, 5, 搜搜搜, 0),(京东, 北京京东世纪贸易有限公司, 40, 就是快, 1);3.2、在新建web项目中导入依赖
dependencies!--Servlet--dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion3.1.0/versionscopeprovided/scope/dependency!--MyBatis--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.5/version/dependency!--MySQL--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.46/version/dependency!--fastjson--dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.62/version/dependency
/dependencies3.3、编写Mybatis文件
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtdconfigurationsettings!--在控制台显示SQL语句--setting namelogImpl valueSTDOUT_LOGGING/setting namemapUnderscoreToCamelCase valuetrue//settingstypeAliasespackage namecom.demo.pojo//typeAliasesenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC/dataSource typePOOLEDproperty namedriver valuecom.mysql.jdbc.Driver/property nameurl valuejdbc:mysql:///brand?useSSLfalse/property nameusername valueroot/property namepassword value123456//dataSource/environment/environmentsmappers!--扫描mapper--package namecom.demo.mapper//mappers
/configuration3.4、编写pojo类
public class Brand {// id 主键private Integer id;// 品牌名称private String brandName;// 企业名称private String companyName;// 排序字段private Integer ordered;// 描述信息private String description;// 状态0禁用 1启用private Integer status;.....省略方法
}3.5、编写Mybatis工具类
public class MyBatisUtils {private static SqlSessionFactory sqlSessionFactory;// 我们只需要一个SqlSessionFactory,在静态代码块中创建SqlSessionFactorystatic {try {// 编写代码让MyBatis跑起来,执行SQL语句String resource mybatis-config.xml;// 加载核心配置文件InputStream inputStream Resources.getResourceAsStream(resource);// 得到SqlSession工厂,赋值给成员变量sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}// 返回SqlSessionFactorypublic static SqlSessionFactory getSqlSessionFactory() {return sqlSessionFactory;}// 返回SqlSessionpublic static SqlSession openSession() {return sqlSessionFactory.openSession();}public static SqlSession openSession(boolean autoCommit) {return sqlSessionFactory.openSession(autoCommit);}
}3.6、导入前端素材element-ui vue.js axios.js 3.7、前端页面
!DOCTYPE html
html langen
headmeta charsetUTF-8title品牌列表/titlescript srcjs/axios-0.18.0.js/scriptscript srcjs/vue.js/scriptscript srcelement-ui/lib/index.js/scriptlink relstylesheet hrefelement-ui/lib/theme-chalk/index.cssstyle.el-table .warning-row {background: oldlace;}.el-table .success-row {background: #f0f9eb;}/style
/head
bodydiv idapp!--第一行--el-rowel-form :inlinetrue :modelsearchBrand classdemo-form-inlineel-form-item label当前状态el-select v-modelsearchBrand.status placeholder当前状态el-option label禁用 value0/el-optionel-option label启用 value1/el-optionel-option label所有 value/el-option/el-select/el-form-itemel-form-item label企业名称el-input v-modelsearchBrand.companyName placeholder企业名称/el-input/el-form-itemel-form-item label品牌名称el-input v-modelsearchBrand.brandName placeholder品牌名称/el-input/el-form-itemel-form-itemel-button typeprimary clickonSubmit查询/el-button/el-form-item/el-form/el-row!--第二行--el-rowel-button typedanger plain clickdeleteByIds()批量删除/el-buttonel-button typeprimary plain clickdialogVisible true新增/el-button!--添加品牌对话框--el-dialogtitle添加品牌:visible.syncdialogVisiblewidth30%!--对话框里面的表单--el-form :modeladdBrand :rulesrules refaddBrand label-width100px classdemo-ruleFormel-form-item label品牌名称 propbrandNameel-input v-modeladdBrand.brandName/el-input/el-form-itemel-form-item label企业名称 propcompanyNameel-input v-modeladdBrand.companyName/el-input/el-form-itemel-form-item label排序el-input v-modeladdBrand.ordered/el-input/el-form-itemel-form-item label描述el-input typetextarea v-modeladdBrand.description/el-input/el-form-itemel-form-item label状态el-switch v-modeladdBrand.statusactive-value1inactive-value0/el-switch/el-form-itemel-form-itemel-button typeprimary clicksubmitForm(ruleForm)提交/el-buttonel-button clickresetForm(ruleForm)取消/el-button/el-form-item/el-form/el-dialog/el-row!--第三行--el-rowtemplateel-table:datatableDatastylewidth: 100%:row-class-nametableRowClassNameselection-changehandleSelectionChangeel-table-columntypeselectionwidth55/el-table-columnel-table-columntypeindexwidth50/el-table-columnel-table-columnaligncenterpropbrandNamelabel品牌名称/el-table-columnel-table-columnaligncenterpropcompanyNamelabel企业名称/el-table-columnel-table-columnproporderedlabel排序width150/el-table-columnel-table-columnpropstatuslabel当前状态width150template slot-scopescopespan v-ifscope.row.status1启用/spanspan v-else禁用/span/template/el-table-columnel-table-column label操作 width250template slot-scopescopeel-buttonsizeminiclickhandleEdit(scope.$index, scope.row)修改/el-buttonel-buttonsizeminitypedangerclickhandleDelete(scope.$index, scope.row)删除/el-button/template/el-table-column/el-table/template/el-row!--修改品牌对话框--el-dialogtitle修改品牌:visible.syncupdateDialogVisiblewidth30%!--对话框里面的表单--el-form :modelupdateBrand :rulesrules refupdateBrand label-width100px classdemo-ruleFormel-form-item label品牌名称 propbrandNameel-input v-modelupdateBrand.brandName/el-input/el-form-itemel-form-item label企业名称 propcompanyNameel-input v-modelupdateBrand.companyName/el-input/el-form-itemel-form-item label排序el-input v-modelupdateBrand.ordered/el-input/el-form-itemel-form-item label描述el-input typetextarea v-modelupdateBrand.description/el-input/el-form-itemel-form-item label状态el-switch v-modelupdateBrand.status:active-value1:inactive-value0/el-switch/el-form-itemel-form-itemel-button typeprimary clicksubmitFormUpdate(ruleForm)提交/el-buttonel-button clickresetFormUpdate(ruleForm)取消/el-button/el-form-item/el-form/el-dialog!--第四行--el-rowdiv classblock styletext-align: center; margin-top: 15pxel-paginationbackgroundsize-changehandleSizeChangecurrent-changehandleCurrentChange:current-pagecurrentPage:page-sizes[5, 10, 15, 20]:page-sizepageSizelayouttotal, sizes, prev, pager, next, jumper:totaltotalCount/el-pagination/div/el-row
/divscriptnew Vue({el: #app,mounted() {this.reselectAll();},methods: {// 批量删除的方法deleteByIds() {this.$confirm(此操作将永久删除选中的品牌, 是否继续?, 警告, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).then(() {this.selectionIds [];// 遍历对象,取出id,放到selectionIds中;for (let brand of this.multipleSelection) {this.selectionIds.push(brand.id);}console.log(this.selectionIds);// 1.点击批量删除按钮发送ajax请求,携带被选中的id数组数据axios.post(brand/deleteByIds, this.selectionIds).then(resp {// 2.获取标识判断删除是否成功if (resp.data success) {// 给出提示this.$message({showClose: true,message: 恭喜你删除成功,type: success});// 重新查询数据this.reselectAll();}});}).catch(() {this.$message({type: info,message: 已取消删除});});},// 重新加载所有数据reselectAll() {// 1.(查询所有数据) 页面加载完成后发送异步请求获取列表数据axios.get(brand/selectAll).then(resp {// 将数据设置到模型上this.tableData resp.data;});// 2.(分页查询) 页面加载完成后发送异步请求携带当前页码和每页显示条数参数/*axios.get(brand/selectByPage?currentPage this.currentPage pageSize this.pageSize).then(resp {// 将数据设置到模型上this.tableData resp.data.rows; // 这页的数据this.totalCount resp.data.totalCount;});*/// 3.(条件且分页查询) 页面加载完成后发送异步请求携带当前页码和每页显示条数参数// axios.get(brand/selectByPageAndCondition?currentPage this.currentPage pageSize this.pageSize brandName this.searchBrand.brandName companyName this.searchBrand.companyName status this.searchBrand.status)// .then(resp {// // 将数据设置到模型上// this.tableData resp.data.rows; // 这页的数据// this.totalCount resp.data.totalCount;// });},tableRowClassName({row, rowIndex}) {if (rowIndex 1) {return warning-row;} else if (rowIndex 3) {return success-row;}return ;},// 多选按钮状态改变会调用handleSelectionChange(val) {this.multipleSelection val;console.log(this.multipleSelection);},// 点击查询按钮时调用onSubmit() {console.log(准备查询: this.searchBrand);// 每一次点击了查询按钮,当前页码要重置为1this.currentPage 1;// 带条件分页查询this.reselectAll();},// 添加品牌submitForm(formName) {// 1.点击提交按钮发送ajax请求,携带表单数据axios.post(brand/add, this.addBrand).then(resp {// 2.获取数据判断添加是否成功if (resp.data success) {// 关闭窗口this.dialogVisible false;// 重新加载数据this.reselectAll();// 给一个成功的提示this.$message({message: 恭喜你添加品牌成功!,type: success});// 清空模型数据,否则还显示上一次的this.addBrand {brandName: ,companyName: ,ordered: ,description: ,status: 0}}});},// 取消添加品牌resetForm(formName) {this.dialogVisible false;},// 修改品牌submitFormUpdate(formName) {// 1.点击提交按钮发送ajax请求,携带表单数据axios.post(brand/update, this.updateBrand).then(resp {// 2.获取数据判断修改是否成功if (resp.data success) {// 关闭窗口this.updateDialogVisible false;// 重新加载数据this.reselectAll();// 给一个成功的提示this.$message({message: 恭喜你修改品牌成功!,type: success});// 清空模型数据,否则还显示上一次的this.updateBrand {brandName: ,companyName: ,ordered: ,description: ,status: 0}}});},// 取消修改品牌对话框resetFormUpdate(formName) {this.updateDialogVisible false;},// 每页数量发生变化调用handleSizeChange(val) {console.log(每页 ${val} 条);this.pageSize val;// 重新请求数据this.reselectAll();},// 页码变化调用handleCurrentChange(val) {console.log(当前页: ${val});this.currentPage val;// 重新请求数据this.reselectAll();},// 修改品牌handleEdit(index, row) {// 把当前行的数据赋值给修改品牌,让对话框中显示这个数据this.updateBrand row;// 显示修改的对话框this.updateDialogVisible true;},// 删除品牌handleDelete(index, row) {this.$confirm(此操作将永久删除选中的品牌, 是否继续?, 警告, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).then(() {// 根据id删除一个品牌axios.post(brand/deleteOne, id row.id).then(resp {if (resp.data success) {// 重新加载数据this.reselectAll();// 给一个成功的提示this.$message({message: 恭喜你删除品牌成功!,type: success});}});}).catch(() {this.$message({type: info,message: 已取消删除});});}},data() {return {// 保存选中的要删除的idselectionIds: [],// 分页工具条,显示当前第几页currentPage: 1,// 每页显示的数量pageSize: 5,// 总数量totalCount: 100,// 添加品牌的数据addBrand: {brandName: ,companyName: ,ordered: ,description: ,status: 0},// 修改品牌的数据updateBrand: {brandName: ,companyName: ,ordered: ,description: ,status: 0},// 添加和修改品牌的输入验证规则rules: {brandName: [{required: true, message: 请输入品牌名称, trigger: blur},{min: 1, max: 15, message: 品牌名称长度在 1 到 15 个字符, trigger: blur}],companyName: [{required: true, message: 请输入企业名称, trigger: blur},{min: 2, max: 15, message: 企业名称长度在 2 到 15 个字符, trigger: blur}]},// 控制添加品牌对话框是否显示true表示显示,false表示不显示dialogVisible: false,// 控制修改品牌对话框是否显示true表示显示,false表示不显示updateDialogVisible: false,// 第一行表单中查询的数据searchBrand: {brandName: ,companyName: ,status: },// 保存多选按钮选中的数据multipleSelection: [],// 表格中的数据tableData: [{brandName: 华为P50,companyName: 华为科技有限公司,ordered: 1,status: 1}]}}});
/script
/body
/html4、功能实现
4.1、查询所有功能 如上图所示是查询所有品牌数据在页面展示的效果。要实现这个功能要先搞明白如下问题 什么时候发送异步请求 页面加载完毕后就需要在页面上看到所有的品牌数据。所以在 mounted() 这个构造函数中写发送异步请求的代码。 请求需要携带参数吗 查询所有功能不需要携带什么参数。 响应的数据格式是什么样 后端是需要将 ListBrand 对象转换为 JSON 格式的数据并响应回给浏览器。响应数据格式如下
整体流程如下 后端代码实现 1、在 BrandMapper 接口中定义抽象方法并使用 Select 注解编写 sql 语句
/*** 查询所有* return*/
Select(select * from tb_brand)
ListBrand selectAll();2、在service包下创建接口定义查询方法
public interface BrandService {ListBrand selectAll();
}3、同时在service/impl包下创建实现类,同时创建selectAll方法
public class BrandServiceImpl implements BrandService {Overridepublic ListBrand selectAll() {//获取Mybatis连接SqlSession sqlSession MyBatisUtils.openSession();BrandMapper mapper sqlSession.getMapper(BrandMapper.class);//调用查询方法ListBrand brands mapper.selectAll();sqlSession.close();return brands;}
}4、在web包下创建BrandSelectAllServlet
WebServlet(value /brand/selectAll)
public class BrandSelectAllServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//调用BrandService进行查询所有BrandService brandService new BrandServiceImpl();ListBrand brands brandService.selectAll();//设置响应格式为json,将数据转换为字符串发送String jsonString JSON.toJSONString(brands);System.out.println(jsonString);response.setContentType(text/json;charsetutf-8);response.getWriter().write(jsonString);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);doGet(request,response);}
}前端代码 前端需要在页面加载完毕后发送 ajax 请求所以发送请求的逻辑应该放在 mounted() 钩子函数中。而响应回来的数据需要赋值给表格绑定的数据模型从下图可以看出表格绑定的数据模型是 tableData 前端代码如下
reselectAll() {// 1.(查询所有数据) 页面加载完成后发送异步请求获取列表数据axios.get(brand/selectAll).then(resp {// 将数据设置到模型上this.tableData resp.data;
});4.2、添加数据功能 上图是添加数据的对话框当点击 提交 按钮后就需要将数据提交到后端并将数据保存到数据库中。下图是整体的流程 页面发送请求时需要将输入框输入的内容提交给后端程序而这里是以 json 格式进行传递的。而具体的数据格式如下 后端实现 1、在 BrandMapper 接口中定义 add() 添加方法并使用 Insert 注解编写sql语句 Insert(insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status});)void addBrand(Brand brand);2、在 BrandService 接口中定义 add() 添加数据的业务逻辑方法
void addBrand(Brand brand);3、在 BrandServiceImpl 类中重写 add() 方法并进行业务逻辑实现
/*** 添加商品* param brand
*/
Override
public void addBrand(Brand brand) {//获取连接SqlSession sqlSession MyBatisUtils.openSession();BrandMapper mapper sqlSession.getMapper(BrandMapper.class);//调用方法添加数据mapper.addBrand(brand);sqlSession.commit();sqlSession.close();
}4、在 web 包写定义名为 BrandAddServlet 的 Servlet。该 Servlet 的逻辑如下
接收页面提交的数据。页面到时候提交的数据是 json 格式的数据所以此处需要使用输入流读取数据将接收到的数据转换为 Brand 对象调用 service 的 add() 方法进行添加的业务逻辑处理给浏览器响应添加成功的标识这里直接给浏览器响应 success 字符串表示成功
servlet 代码实现如下
WebServlet(value /brand/add)
public class BrandAddServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接受请求数据String addJson request.getReader().readLine();//将json转化为对象Brand brand JSON.parseObject(addJson, Brand.class);//调用方法进行数据添加BrandService brandService new BrandServiceImpl();brandService.addBrand(brand);//响应数据响应成功标识response.setContentType(text/json;charsetutf-8);response.getWriter().write(success);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);doGet(request,response);}
}前端代码实现 上图左边是页面效果里面的 提交 按钮可以通过上图右边看出绑定了一个 单击事件而该事件绑定的是 addBrand 函数所以添加数据功能的逻辑代码应该写在 addBrand() 函数中。在此方法中需要发送异步请求并将表单中输入的数据作为参数进行传递。如下
// 添加数据
addBrand() {var _this this;// 发送ajax请求添加数据axios({method:post,url:http://localhost:8080/brand-case/addServlet,data:_this.brand}).then(function (resp) {//响应数据的处理逻辑})
}在 then 函数中的匿名函数是成功后的回调函数而 resp.data 就可以获取到响应回来的数据如果值是 success 表示数据添加成功。成功后我们需要做一下逻辑处理 关闭新增对话框窗口 如下图所示是添加数据的对话框代码从代码中可以看到此对话框绑定了 dialogVisible 数据模型只需要将该数据模型的值设置为 false就可以关闭新增对话框窗口了。 重新查询数据 数据添加成功与否用户只要能在页面上查看到数据说明添加成功。而此处需要重新发送异步请求获取所有的品牌数据而这段代码在 查询所有 功能中已经实现所以我们可以将此功能代码进行抽取抽取到一个 selectAll() 函数中 // 查询所有数据
selectAll(){var _this this;axios({method:get,url:http://localhost:8080/brand-case/selectAllServlet}).then(function (resp) {_this.tableData resp.data;})
}那么就需要将 mounted() 钩子函数中代码改进为 mounted(){//当页面加载完成后发送异步请求获取数据this.selectAll();
}同时在新增响应的回调中调用 selectAll() 进行数据的重新查询。 弹出消息给用户提示添加成功 上图左边就是 elementUI 官网提供的成功提示代码而上图右边是具体的效果。
综上所述前端代码如下
// 添加数据
addBrand() {var _this this;// 发送ajax请求添加数据axios({method:post,url:http://localhost:8080/brand-case/addServlet,data:_this.brand}).then(function (resp) {if(resp.data success){//添加成功//关闭窗口_this.dialogVisible false;// 重新查询数据_this.selectAll();// 弹出消息提示_this.$message({message: 恭喜你添加成功,type: success});}})
}4.3、修改数据功能 上图是修改数据的对话框当点击 提交 按钮后就需要将数据提交到后端并将数据保存到数据库中。 后端实现 1、在 BrandMapper 接口中定义 updateBrand() 方法
Update(update tb_brand set brand_name #{brandName},company_name #{companyName},ordered #{ordered},description #{description},status #{status} where id #{id};)
void updateBrand(Brand brand);2、在 BrandService 接口中定义 updateBrand()
void updateBrand(Brand brand);3、在 BrandServiceImpl 类中重写 updateBrand() 方法并进行业务逻辑实现
/*** 修改数据* param brand
*/
Override
public void updateBrand(Brand brand) {//获取连接SqlSession sqlSession MyBatisUtils.openSession();BrandMapper mapper sqlSession.getMapper(BrandMapper.class);//调用修改方法mapper.updateBrand(brand);sqlSession.commit();sqlSession.close();
}4、在 web 包写定义名为 BrandUpdateServlet 的 Servlet。该 Servlet 的逻辑如下
WebServlet(value /brand/update)
public class BrandUpdateServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接受数据String BrandJson request.getReader().readLine();//将json数据转化为对象Brand brand JSON.parseObject(BrandJson, Brand.class);//创建对象调用修改方法BrandService brandService new BrandServiceImpl();brandService.updateBrand(brand);//响应数据 successresponse.setContentType(text/json;charsetutf-8);response.getWriter().write(success);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);doGet(request,response);}
}前端代码实现 submitFormUpdate(formName) {// 1.点击提交按钮发送ajax请求,携带表单数据axios.post(brand/update, this.updateBrand).then(resp {// 2.获取数据判断修改是否成功if (resp.data success) {// 关闭窗口this.updateDialogVisible false;// 重新加载数据this.reselectAll();// 给一个成功的提示this.$message({message: 恭喜你修改品牌成功!,type: success});// 清空模型数据,否则还显示上一次的this.updateBrand {brandName: ,companyName: ,ordered: ,description: ,status: 0}}});
}4.4、删除数据功能 后端实现 1、在 BrandMapper 接口中定义 deleteBrand() 方法
Delete(delete from tb_brand where id #{id})
void deleteBrand(int id);2、在 BrandService 接口中定义 deleteBrand()
void deleteBrand(int index);3、在 BrandServiceImpl 类中重写 deleteBrand() 方法并进行业务逻辑实现
/*** 删除数据* param index
*/
Override
public void deleteBrand(int index) {//获取连接SqlSession sqlSession MyBatisUtils.openSession();BrandMapper mapper sqlSession.getMapper(BrandMapper.class);//调用方法mapper.deleteBrand(index);sqlSession.commit();sqlSession.close();}4、在 web 包写定义名为 BrandDeleteServlet 的 Servlet。该 Servlet 的逻辑如下
WebServlet(value /brand/deleteOne)
public class BrandDeleteServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取数据idString id request.getParameter(id);int index Integer.parseInt(id);//调用删除方法BrandService brandService new BrandServiceImpl();brandService.deleteBrand(index);//响应数据 successresponse.setContentType(text/json;charsetutf-8);response.getWriter().write(success);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);doGet(request,response);}
}前端代码实现 // 删除品牌
handleDelete(index, row) {this.$confirm(此操作将永久删除选中的品牌, 是否继续?, 警告, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).then(() {// 根据id删除一个品牌axios.post(brand/deleteOne, id row.id).then(resp {if (resp.data success) {// 重新加载数据this.reselectAll();// 给一个成功的提示this.$message({message: 恭喜你删除品牌成功!,type: success});}});}).catch(() {this.$message({type: info,message: 已取消删除});});
}4.5、批量删除功能
如上图所示点击多条数据前的复选框就意味着要删除这些数据而点击了 批量删除 按钮后需要让用户确认一下因为有可能是用户误操作的当用户确定后需要给后端发送请求并携带者需要删除数据的多个id值后端程序删除数据库中的数据。具体的流程如下 注意
前端发送请求时需要将要删除的多个id值以json格式提交给后端而该json格式数据如下
[1,2,3,4]后端实现 1、 BrandMapper 接口中定义 deleteByIds() 添加方法由于这里面要用到动态 sql 属于复杂的sql操作建议使用映射配置文件。
接口方法声明如下 /*** 批量删除* param ids*/
void deleteByIds(Param(ids) int[] ids);在 BrandMapper.xml 映射配置文件中添加 statement
delete iddeleteByIdsdelete from tb_brand where id inforeach collectionids itemid separator, open( close)#{id}/foreach
/delete2、在 BrandService 接口中定义 deleteByIds() 批量删除的业务逻辑方法
/*** 批量删除* param ids*/
void deleteByIds( int[] ids);3、在 BrandServiceImpl 类中重写 deleteByIds() 方法并进行业务逻辑实现
Override
public void deleteByIds(int[] ids) {//2. 获取SqlSession对象SqlSession sqlSession factory.openSession();//3. 获取BrandMapperBrandMapper mapper sqlSession.getMapper(BrandMapper.class);//4. 调用方法mapper.deleteByIds(ids);sqlSession.commit();//提交事务//5. 释放资源sqlSession.close();
}4、在 BrandServlet 类中定义 deleteByIds() 方法。而该方法的逻辑如下
接收页面提交的数据。页面到时候提交的数据是 json 格式的数据所以此处需要使用输入流读取数据接收页面提交的数据。页面到时候提交的数据是 json 格式的数据所以此处需要使用输入流读取数据将接收到的数据转换为 int[] 数组调用 service 的 deleteByIds() 方法进行批量删除的业务逻辑处理给浏览器响应添加成功的标识这里直接给浏览器响应 success 字符串表示成功
servlet 中 deleteByIds() 方法代码实现如下
WebServlet(value /brand/deleteByIds)
public class deleteByIdsServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 接受数据String idJson request.getReader().readLine();//将json数据转化为数组int[] ints JSON.parseObject(idJson, int[].class);//调用方法BrandService brandService new BrandServiceImpl();brandService.deleteByIds(ints);//响应数据response.setContentType(text/json;charsetutf-8);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);doGet(request,response);}
}前端代码 此功能的前端代码实现稍微有点麻烦分为以下几步实现
1、获取选中的id值 从上图可以看出表格复选框绑定了一个 selection-change 事件该事件是当选择项发生变化时会触发。该事件绑定了 handleSelectionChange 函数而该函数有一个参数 val 该参数是获取选中行的数据如下 而我们只需要将所有选中数据的id值提交给服务端即可获取id的逻辑我们书写在 批量删除 按钮绑定的函数中。
在 批量删除 按钮绑定单击事件并给绑定触发时调用的函数如下 并在Vue对象中的 methods 中定义 deleteByIds() 函数在该函数中从 multipleSelection 数据模型中获取所选数据的id值。要完成这个功能需要在 Vue 对象中定义一个数据模型 selectedIds:[]在 deleteByIds() 函数中遍历 multipleSelection 数组并获取到每一个所选数据的id值存储到 selectedIds 数组中代码实现如下
//1. 创建id数组 [1,2,3], 从 this.multipleSelection 获取即可
for (let i 0; i this.multipleSelection.length; i) {let selectionElement this.multipleSelection[i];this.selectedIds[i] selectionElement.id;
}2、发送异步请求
使用 axios 发送异步请求并经上一步获取到的存储所有的 id 数组作为请求参数
//2. 发送AJAX请求
var _this this;// 发送ajax请求添加数据
axios({method:post,url:http://localhost:8080/brand-case/brand/deleteByIds,data:_this.selectedIds
}).then(function (resp) {if(resp.data success){//删除成功// 重新查询数据_this.selectAll();// 弹出消息提示_this.$message({message: 恭喜你删除成功,type: success});}
})由于删除操作是比较危险的有时候可能是由于用户的误操作点击了 批量删除 按钮所以在点击了按钮后需要先给用户确认提示。而确认框在 elementUI 中也提供了如下图 而在点击 确定 按钮后需要执行之前删除的逻辑。因此前端代码实现如下 // 批量删除
deleteByIds(){// 弹出确认提示框this.$confirm(此操作将删除该数据, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).then(() {//用户点击确认按钮//1. 创建id数组 [1,2,3], 从 this.multipleSelection 获取即可for (let i 0; i this.multipleSelection.length; i) {let selectionElement this.multipleSelection[i];this.selectedIds[i] selectionElement.id;}//2. 发送AJAX请求var _this this;// 发送ajax请求添加数据axios({method:post,url:http://localhost:8080/brand-case/brand/deleteByIds,data:_this.selectedIds}).then(function (resp) {if(resp.data success){//删除成功// 重新查询数据_this.selectAll();// 弹出消息提示_this.$message({message: 恭喜你删除成功,type: success});}})}).catch(() {//用户点击取消按钮this.$message({type: info,message: 已取消删除});});
}4.6、条件分页查询 上图就是用来输入条件查询的条件数据的。要做条件查询功能先明确以下三个问题 3个条件之间什么关系 同时满足所用 SQL 中多个条件需要使用 and 关键字连接 3个条件必须全部填写吗 不需要。想根据哪儿个条件查询就写那个所以这里需要使用动态 sql 语句 条件查询需要分页吗 需要
根据上面三个问题的明确我们就可以确定sql语句了 整个条件分页查询流程如下 后端实现 1、在 BrandMapper 接口中定义 selectByPageAndCondition() 方法 和 selectTotalCountByCondition 方法
/*** 分页条件查询* param begin* param size* return
*/
ListBrand selectByPageAndCondition(Param(begin) int begin,Param(size) int size,Param(brand) Brand brand);/*** 根据条件查询总记录数* return
*/
int selectTotalCountByCondition(Brand brand);参数
begin 分页查询的起始索引size 分页查询的每页条目数brand 用来封装条件的对象
由于这是一个复杂的查询语句需要使用动态sql所以我们在映射配置文件中书写 sql 语句。brand_name 字段和 company_name 字段需要进行模糊查询所以需要使用 % 占位符。映射配置文件中 statement 书写如下
!--查询满足条件的数据并进行分页--
select idselectByPageAndCondition resultMapbrandResultMapselect *from tb_brandwhereif testbrand.brandName ! null and brand.brandName ! and brand_name like #{brand.brandName}/ifif testbrand.companyName ! null and brand.companyName ! and company_name like #{brand.companyName}/ifif testbrand.status ! nulland status #{brand.status}/if/wherelimit #{begin} , #{size}
/select!--查询满足条件的数据条目数--
select idselectTotalCountByCondition resultTypejava.lang.Integerselect count(*)from tb_brandwhereif testbrandName ! null and brandName ! and brand_name like #{brandName}/ifif testcompanyName ! null and companyName ! and company_name like #{companyName}/ifif teststatus ! nulland status #{status}/if/where
/select2、在 BrandService 接口中定义 selectByPageAndCondition() 分页查询数据的业务逻辑方法 /*** 分页条件查询* param currentPage* param pageSize* param brand* return
*/
PageBeanBrand selectByPageAndCondition(int currentPage,int pageSize,Brand brand);3、在 BrandServiceImpl 类中重写 selectByPageAndCondition() 方法并进行业务逻辑实现
Override
public PageBean selectByPageAndCondition(int currentPage, int pageSize, Brand brand) {int start (currentPage - 1) * pageSize;//获取连接SqlSession sqlSession MyBatisUtils.openSession();BrandMapper mapper sqlSession.getMapper(BrandMapper.class);//调用方法,查询条件总数int selectByPageTotal mapper.selectByPageAndConditionTotal(brand);//调用方法查询页面数据ListBrand brands mapper.selectByPageAndCondition(start,pageSize,brand);sqlSession.close();//封装数据PageBean pageBean new PageBean(selectByPageTotal,brands);return pageBean;}4、在 BrandServlet 类中定义 selectByPageAndCondition() 方法。而该方法的逻辑如下 获取页面提交的 当前页码 和 每页显示条目数 两个数据。这两个参数是在url后进行拼接的格式是 url?currentPage1pageSize5。获取这样的参数需要使用 requet.getparameter() 方法获取。 获取页面提交的 条件数据 并将数据封装到一个Brand对象中。由于这部分数据到时候是需要以 json 格式进行提交的所以我们需要通过流获取数据具体代码如下
// 获取查询条件对象
BufferedReader br request.getReader();
String params br.readLine();//json字符串//转为 Brand
Brand brand JSON.parseObject(params, Brand.class);调用 service 的 selectByPageAndCondition() 方法进行分页查询的业务逻辑处理 将查询到的数据转换为 json 格式的数据 响应 json 数据
servlet 中 selectByPageAndCondition() 方法代码实现如下
WebServlet(value /brand/selectByPageAndCondition)
public class SelectByPageAndCondition extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取数据String currentPageStr request.getParameter(currentPage);String pageSizeStr request.getParameter(pageSize);String brandName request.getParameter(brandName);String companyName request.getParameter(companyName);String status request.getParameter(status);int currentPage Integer.parseInt(currentPageStr);int pageSize Integer.parseInt(pageSizeStr);//封装数据Brand brand new Brand();brand.setBrandName(brandName);brand.setCompanyName(companyName);if (status ! null status.length() 0){int i Integer.parseInt(status);brand.setStatus(i);}//调用查询BrandService brandService new BrandServiceImpl();PageBean pageBean brandService.selectByPageAndCondition(currentPage,pageSize,brand);//转化为jsonString jsonString JSON.toJSONString(pageBean);//设置响应response.setContentType(text/json;charsetutf-8);response.getWriter().write(jsonString);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);doGet(request,response);}
}前端代码 前端代码我们从以下几方面实现 查询表单绑定查询条件对象模型 这一步在页面上已经实现了页面代码如下 点击查询按钮查询数据 从上面页面可以看到给 查询 按钮绑定了 onSubmit() 函数而在 onSubmit() 函数中只需要调用 selectAll() 函数进行条件分页查询。 改进 selectAll() 函数 子页面加载完成后发送异步请求需要携带当前页码、每页显示条数、查询条件对象。接下来先对携带的数据进行说明 当前页码 和 每页显示条数 这两个参数我们会拼接到 URL 的后面查询条件对象 这个参数需要以 json 格式提交给后端程序 修改 selectAll() 函数逻辑为
axios.get(brand/selectByPageAndCondition?currentPage this.currentPage pageSize this.pageSize brandName this.searchBrand.brandName companyName this.searchBrand.companyName status this.searchBrand.status).then(resp {// 将数据设置到模型上this.tableData resp.data.rows; // 这页的数据this.totalCount resp.data.totalCount;
});