目录
1、项目功能介绍
编辑
2、环境准备
创建项目
准备数据库
准备Mybatis核心配置文件
创建实体类与Mapper映射文件
补全项目结构
1、在pom.xml中导入相关依赖
2、导入axios、vue的js文件
3、导入Element-ui
3、查询所有功能的实现
3.1、后端的实现
3.1.1、dao层方法的实现:
3.1.2、service方法的实现
3.1.3、servlet实现
3.1.4、测试后端程序
3.2、前端实现
3.2.1、创建brand.html页面
3.2.2、官网复制Element组件代码
4、添加功能的实现
4.1、后端的实现
4.1.1、dao层方法的实现
4.1.2、serivce方法的实现
4.1.3、servlet的实现
4.2、前端实现
5、Servlet代码优化
5.1、问题引入
5.2、代码优化
5.2.1、后端代码的优化
5.2.2、前端代码的优化
6、批量删除功能实现
6.1、后端实现
6.1.1、dao层代码的实现
编辑
6.1.2、service方法实现
6.1.2、servlet的实现
6.2、前端实现
6.2.1、获取选择的id值
6.2.2、发送异步请求
6.2.3、确认框提示
7、分页查询功能的实现
7.1、分析
7.1.1、分页查询sql
7.1.2、前后端数据的分析
7.1.3、流程分析
7.2、后端实现
7.2.1、dao层方法的实现
7.2.2、service方法实现
7.2.3、servlet实现
7.2.4、测试
7.3、前端实现
7.3.1、selectAll()的改进
7.3.2、改变每页条目数
7.3.3、 改变当前页码
8、条件查询功能实现
8.1、后端实现
8.1.1、dao层实现
8.1.2、service的实现
8.1.3、servlet的实现
8.2、前端实现
10、修改功能的实现
10.1、后端实现
10.1.1、dao层方法的实现
10.1.2、service方法的实现
10.1.3、servlet实现
10.2、前端实现
以上是我们在综合案例要实现的功能。对数据的除了对数据的增删改查功能外,还有一些复杂的功能,如 批量删除
、分页查询
、条件查询
等功能
批量删除
功能:每条数据前都有复选框,当我选中多条数据并点击 批量删除
按钮后,会发送请求到后端并删除数据库中指定的多条数据。
分页查询
功能:当数据库中有很多数据时,我们不可能将所有的数据展示在一页里,这个时候就需要分页展示数据。
条件查询
功能:数据库量大的时候,我们就需要精确的查询一些想看到的数据,这个时候就需要通过条件查询。
修改品牌:
删除品牌
1、创建Maven项目,如下
为项目起名
在pom.xml中加入如下,是这个模块变为web模块
然后依次点击 Apply ,Ok
做完上述操作以后,项目结构如下:
创建一个名为 db2 的数据库,建表语句如下:
create database db2;
在db2 下准备数据库表,如下
-- 删除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);
建好的的表如下:
1、在resources目录下添加mybaits核心配置文件,去mybatis官方复制粘贴,然后修改即可,步骤如下:
1)创建 mybatis-config.xml
2)修改后的mybatis核心配置文件如下所示
因为一个实体类对应这一个mapper映射文件,因此需要先创建实体类
1、创建实体类
根据数据库表tb_brand,我们创建一个Brand实体类
步骤:右击java -> New -> Java Class
根据数据库表 tb_brand 在实体类Brand中创建对应的属性及get、set方法,如下所示
代码如下:
package com.clear.pojo;
public class Brand {
private Integer id;
private String brandName;
private String companyName;
private Integer ordered;
private String description;
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
2、创建mapper映射文件
在创建mapper映射文件之前,在创建一个mapper接口,如下所示
步骤:右击java -> New -> Java Class -> 选择Interface
接下来在resources目录下创建一个与BrandMapper接口在同一目录下的映射文件(因为项目部署时mapper接口生成的class字节码文件需要与mapper映射文件xml在同一目录下)
步骤视图如下:
接着我们与创建mybatis核心配置时一样,依然去myabtis官网复制粘贴,然后修改,修改后的映射文件如下所示:
紧接着去修改mybatis核心配置文件中mapper标签 中 resource属性的值,如下所示:
如下所示
需要连接MySQL——导入MySQL相关依赖
使用了mybatis简化JDBC——导入mybatis依赖
需要使用JSON在前后端传递数据——导入fastjson
是Java的web项目——导入servlet(注意scope为provided)
为了方便启动服务器——导入tomcat7插件
pom.xml如下所示
4.0.0
org.example
brand-case
1.0-SNAPSHOT
war
8
8
javax.servlet
javax.servlet-api
3.1.0
provided
org.mybatis
mybatis
3.5.5
mysql
mysql-connector-java
5.1.46
com.alibaba
fastjson
1.2.62
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
至此,基本的环境就准备的差不多了,如果还需要其他的,后续在补充
如上图所示是查询所有品牌数据在页面展示的效果。要实现这个功能,要先搞明白如下问题:
1)什么时候发送异步请求?
页面加载完毕后就需要在页面上看到所有的品牌数据。所以在 mounted()
这个构造函数中写发送异步请求的代码。
2)请求需要携带参数吗?
查询所有功能不需要携带什么参数。
3)响应的数据格式是什么样?
后端是需要将 List
对象转换为 JSON 格式的数据并响应回给浏览器。响应数据格式如下:
整体流程如下:
我们先实现后端程序,然后再实现前端程序。
在com.clear.mapper.BrandMapper接口中定义抽象方法,并使用注解来编写SQL语句,如下所示
但是这样肯定会出问题的,因为我们刚开始创建实体类Brand时,Brand中的属性与数据库表tb_brand中的字段名没有一一对应,这样mybatis无法帮我们完成自动封装,所以我们需要在BrandMapper映射文件中定义结果映射 ,使用resultMap标签。如下所示:
定义完结果映射关系后,在接口selectAll()方法上引用该结构映射。使用@ResultMap()注解来完成,如下所示:
接着我们来优化一下上面的配置:
我们发现,在BrandMapper映射文件中resultMap标签中的type属性需要填写Brand实体类的全限定名,这显然有点不简洁了,我们可以通过在mybatis核心配置文件中定义typeAliases标签来简化它,如下所示:
接着修改BrandMapper映射文件,如下所示
在com.clear.service包下创建BrandService的接口,在该接口中定义查询所有的抽象方法
并在com.clear.service下再创建impl包;impl表示是放 service 层接口的实现类的包。 在该包下创建名为BrandServiceImpl类
这时就要疑惑了,之前我们都是直接定义service类,然后在里面定义方法,此处为什么要给 service 定义接口呢?因为service定义了接口后,在 servlet 中就可以使用多态的形式创建Service实现类的对象,如下:
这里使用多态是因为方便我们后期解除Servlet和service的耦合。从上面的代码我们可以看到SelectAllServlet类和BrandServiceImpl类之间是耦合在一起的,如果后期 BrandService
有其它更好的实现类(例如叫 BrandServiceImpl
),那就需要修改SelectAllServlet类中的代码。后面我们学习了Spring框架后就可以解除SelectAllServlet类和红色框括起来的代码耦合。而现在咱们还做不到解除耦合,在这里只需要理解为什么定义接口即可。
BrandServiceImpl类代码如下:
package com.clear.service.impl;
import com.clear.mapper.BrandMapper;
import com.clear.pojo.Brand;
import com.clear.service.BrandService;
import com.clear.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class BrandServiceImpl implements BrandService {
//1. 创建SqlSessionFactory 工厂对象
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
/**
* 查询所有
* @return
*/
@Override
public List selectAll() {
//2. 获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 获取BrandMapper
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
List brands = brandMapper.selectAll();
//5. 释放资源
sqlSession.close();
return brands;
}
}
上述中用到了一个工厂对象,在com.clear.util包下创建SqlSessionFactoryUtils类,工厂对象的代码如下:
package com.clear.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
/**
* 获取SqlSessionFactory对象的工具类
*/
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
//静态代码块会随着类的加载而自动执行,且只执行一次
static {
InputStream inputStream = null;
try {
String resource = "mybatis-config.xml";
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
}
在 com.clear.web.servlet 包下定义名为SelectAllServlet的查询所有的servlet。该servlet逻辑如下:
1)调用service的selectAll()方法查询到所有的品牌数据,并返回结果
2)将返回的结果封装为json数据
3)响应json数据至前端
servlet代码如下:
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService brandService = new BrandServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1、调用service查询
List brands = brandService.selectAll();
// 2、转为json
String jsonString =JSON.toJSONString(brands);
// 3、写数据
response.setContentType("text/json;charset=utf-8"); //告知浏览器响应的数据类型, 告知浏览器使用什么字符集进行解码
PrintWriter writer = response.getWriter();
// 响应数据至浏览器
writer.write(jsonString);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在浏览器输入访问 servlet 的资源路径 http://localhost:8080/brand-case/selectAllServlet
,如果没有报错,并能看到如下信息表明后端程序没有问题
在webapp目录下创建brand.html页面,如下所示:
Title
在页面引入Element 的css、js文件 和 Vue.js,如下:
一般是是在
标签之前引入
创建Vue核心对象,如下所示:
创建 Vue 对象时,需要传递一个 js 对象,而该对象中需要如下属性:
1)el: 用来指定哪些标签受 Vue 管理。 该属性取值
#app
中的app
需要是受管理的标签的id属性值2)data:用来定义数据模型
3)methods:用来定义函数。
定义div标签,它有一个id属性,值为app,如下:
去Element官网复制组件代码,然后进行修改,步骤如下:
将html标签拷贝到 中,如下:
将css样式拷贝到我们页面的 head
标签中,如下
将方法和模型数据拷贝到 Vue 对象指定的位置
拷贝修改后的brand.html页面如下:
Title