因为前端并不难,这里前后端就一起实现。一共分为四个步骤
步骤一 ① SQL部分
分页条件查询其实就是在分页的基础上增加条件,这里有两个主要的函数需要去实现,一个是根据分页以及条件去查询数据,另一个是根据条件去统计数据。
明显第二个更为简单,先从第二个开始分析。
- 根据条件统计满足条件的数量。
原本统计的SQL只需要一句:select count(*) form 表名
。完事儿了,这就可以统计所有的条目数。现在的需求是什么,假设用户添加了条件:我想看品牌名称是华为的。那么只需要在SQL后面添加条件就可以了。因此这个的SQL还是很好实现的。只消注意的是,这里需要使用动态SQL,因为用户非常大的可能不会一次全部都输入。
实现该统计的SQL如下:
mapper部分
/**
* 根据条件查询总记录数
* @return
*/
int selectTotalCountByCondition(Brand brand);
xml中实现部分
<select id="selectTotalCountByCondition" resultType="java.lang.Integer">
select count(*) from tb_brand
<where>
<if test=" brandName != null and brandName != '' ">
and brand_name like #{ brandName}
</if>
<if test=" companyName != null and companyName != '' ">
and company_name like #{ companyName}
</if>
<if test=" status != null">
and status like #{ status}
</if>
</where>
</select>
- 根据条件以及分页来查询数据。这里要的是什么数据,打个比方说:用户想要品牌名称为华为的所有结果,而且,我还要进行分页展示。那分页我们之前写了吧,只需要传入当前页以及页面大小就可以了,那只需要添加条件就可以了。这里的代码比较复杂,没有使用注解开发。
mapper部分
/**
* 分页条件查询
* @param begin
* @param size
* @return
*/
List<Brand> selectByPageAndCondition(@Param("begin") int begin, @Param("size")int size, @Param("brand")Brand brand);
这里我就要讲两句了,看下图,可以对照前面查询总记录数传入的参数来看,人家怎么没写注解呢?因为人家只有一个参数,不需要注解。但是咱们这里有三个参数,不仅是需要注解,还需要使用注解里面的值。
xml实现部分
<select id="selectByPageAndCondition" resultMap="brandResultMap">
select * from tb_brand
<where>
<if test="brand.brandName != null and brand.brandName != '' ">
and brand_name like #{brand.brandName}
</if>
<if test="brand.companyName != null and brand.companyName != '' ">
and company_name like #{brand.companyName}
</if>
<if test="brand.status != null">
and status like #{brand.status}
</if>
</where>
limit #{begin}, #{size}
</select>
因此呢这里可以小结一下
如果我们只有一个参数,比如只需要传入brand对象,那里面可以直接使用它里面的属性, <if test=" brandName != null and brandName != '' ">
,像这一条,brandName是它里面的属性吧,没事直接用。
但是如果有多个参数需要传递就必须要使用注解了,一旦要使用注解,那对象里面的属性就不能直接使用了,比如说你要这么用:brand.brandName != null
。
步骤二 ② service层部分
- 老规矩,接口这一块。
接口这里和之前写的分页查询查不到哪里去,唯二的区别就是方法名改变了、传入的参数多了一个brand对象。下面是代码:
/**
* 分页条件查询
* @param currentPage 当前页码
* @param pageSize 每页展示条数
* @return
*/
PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand);
- serviceImpl这一块
这一块的话总体其实也有什么变化的,主要就是需要换一下方法名,还有比较重要的工作就是,处理brand的查询条件,这里搞成模糊查询,其实就是把比如说的华为,从对象里拿出来,左右两边拼接一下百分号,再存到对象里面。主要进行模糊查询代码:
//处理brand条件 模糊表达式
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 + "%");
}
总体的代码:
@Override
public PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand) {
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//计算开始索引
int begin = (currentPage -1) * pageSize;
//查询的条目数(总数)
int size = pageSize;
//处理brand条件 模糊表达式
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> rows = mapper.selectByPageAndCondition(begin, size, brand);
//查询总记录数
int totalCount = mapper.selectTotalCountByCondition(brand);
//封装成PageBean对象
PageBean<Brand> PageBean = new PageBean<>();
PageBean.setRows(rows);
PageBean.setTotalCount(totalCount);
//释放资源
sqlSession.close();
return PageBean;
}
步骤三 ③servlet这一块
这里比之前分页查询就多加了一步。想一想多加了什么。条件嘛。什么条件?其实就是一个brand对象,我们要从前端把这个brand对象接收过来,至于当前页和页面大小之前不是写过嘛,直接使用就可以了。那这里的工作主要就是:复制、粘贴、改一下函数名、接收一下传过来json版本的brand对象,转成我们能用的Java对象。下面是总体的代码:
/**
* 分页条件查询
* @param request
* @param response
* @throws IOException
*/
public void selectByPageAndCondition(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1.接收参数: 当前页码 和 每页分的条目数 url?currentPage=1&pageSize=5
String _currentPage = request.getParameter("currentPage");
String _pageSize = request.getParameter("pageSize");
//转换成int类型的
int currentPage = Integer.parseInt(_currentPage);
int pageSize = Integer.parseInt(_pageSize);
//获取查询条件对象
BufferedReader br = request.getReader();
String params = br.readLine();//这个就是接收到的参数字符串
//转为brand类型
Brand brand = JSON.parseObject(params, Brand.class);
//调用service进行查询
PageBean<Brand> pageBean = brandService.selectByPageAndCondition(currentPage,pageSize,brand);
//2. 转为json
String jsonString = JSON.toJSONString(pageBean);
//3. 防止乱码以及写数据
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
步骤四④前端这一块
前端需要传值嘛。传什么值?之前element已经给我们定义好了,输入条件之后自然会给我们封装好一个brand对象,只要把这个brand对象传过去就可以了。那就设置一下,点击下面的查询按钮,我们重新进行查询,刷新一下界面呗。就一句代码,调用查询的方法就可以。
那查询这个方法怎么把数据传到后台去呢?这里将之前的get方法改成了post方法,我们再传个参数–brand对象。下面是实现部分代码:
var that = this;
axios({
method:"post",
url:"http://localhost:8080/brand/selectByPageAndCondition?currentPage="+that.currentPage +"&pageSize=" + that.pageSize,
data:that.brand
}).then(function (resp){
//设置表格数据
that.tableData = resp.data.rows;
//设置总记录数
that.totalCount = resp.data.totalCount;
})
也就是说,这里级使用了在url中发送数据的方式,又使用了post传送brand对象的方式。
多学一个 resp=>的使用:
可以看到,在axios里面的then中,不能直接使用this,必须先用一个that或者其他来代替。那将function直接替换成resp=>{}。上面的代码可以写成这样:
axios({
method:"post",
url:"http://localhost:8080/brand/selectByPageAndCondition?currentPage="+this.currentPage +"&pageSize=" + this.pageSize,
data:this.brand
}).then(resp=>{
//设置表格数据
this.tableData = resp.data.rows;
//设置总记录数
this.totalCount = resp.data.totalCount;
})
这样就不需要给this换成其他的值了。
可以看到,效果还是一样的。
总结一下。
和分页查询相比,其实就是多了一个条件,我们需要做的其实就是将对象传回去。那改动比较大的就是SQL部分,因为这一部分添加了动态SQL,但是大部分也可以根据之前的内容进行粘贴复制。其次就是service层的改动,这里需要我们做一个小处理:模糊查询。后面的servlet和前端部分只需要传值和接收,改动不大。