前端页面js代码
整套datatable初始化代码
注意"serverSide": true,这个配置必须设置
$(function () {
$('#contenttable').DataTable({
"ajax": {
url: "/test/selectTestList",
type: "POST",
data: function(d) {
// 获取查询条件的值
var name = $("#nameSelect").val();
var age = $("#ageSelect").val();
// 添加额外的参数传给服务器
d.name = name;
d.age = age;
},
},
"serverSide": true, // 服务端分页处理
"dom": "<'row'<'col-xs-8 toolbar'><'col-xs-4'f>>" +
"t" +
"<'row'<'col-xs-2'l><'col-xs-4'i><'col-xs-6'p>>",
columns: [
{data: "name",class:"text-center"},
{data: "age",class:"text-center"},
{data: "sex",class:"text-center"},
],
initComplete: function () {
var tooldiv = $("div.toolbar");
// 名字筛选 column(0)下标0开始
var column_name = this.api().column(0);
$('<label class="control-label" style="text-align: left">名字:</label>').appendTo(tooldiv);
$('<select class="form-control" id="nameSelect"><option value="">全部</option></select>').appendTo(tooldiv)
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
column_name.search( val ? '^'+val+'$' : '', true, false ).draw();
});
// 年龄筛选
var column_age = this.api().column(1);
$('<label class="control-label" style="text-align: left">年龄:</label>').appendTo(tooldiv);
$('<select class="form-control" id="ageSelect"><option value="">全部</option></select>').appendTo(tooldiv)
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
column_age.search( val ? '^'+val+'$' : '', true, false ).draw();
});
// 在datatable中的initComplete事件中初始化的时候调用一次ajax请求所有下拉框的数据
$.ajax({
type: "GET",
url: "/test/selectTypeList",
dataType: "json",
success: function (json) {
if (json.code == "0000") {
var name = json.data.nameList;
var age = json.data.ageList;
for (var i = 0; i < name.length; i++) {
$("<option></option>").val(name[i]).text(name[i]).appendTo($("#nameSelect"));
}
for (var i = 0; i < age.length; i++) {
$("<option></option>").val(age[i]).text(age[i]).appendTo($("#ageSelect"));
}
} else {
alert("获取筛选类型失败");
}
}
});
}
});
});
后端代码
定义一个与前端交互的泛型<T>类JqueryDataTableDto
import java.io.Serializable;
public class JqueryDataTableDto<T> implements Serializable{
// 请求序号,前端传什么值就返回什么值
private String draw;
// 全部数据总条数
private int recordsTotal;
// 过滤后的总数(就是根据前端页面下拉框、搜索框等传参过来查询后的数据总数)
private int recordsFiltered;
private T data;
public String getDraw() {
return draw;
}
public void setDraw(String draw) {
this.draw = draw;
}
public int getRecordsTotal() {
return recordsTotal;
}
public void setRecordsTotal(int recordsTotal) {
this.recordsTotal = recordsTotal;
}
public int getRecordsFiltered() {
return recordsFiltered;
}
public void setRecordsFiltered(int recordsFiltered) {
this.recordsFiltered = recordsFiltered;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
定义一个实体类TestList
public class TestList {
private int id;
private String name;
private String age;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
TestController控制器代码
import net.sf.json.JSONObject;
import org.springframework.ui.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Autowired
private TestService testService;
@RequestMapping("/selectTestList")
public String selectTestList(Model model,HttpServletRequest request) throws Exception{
String draw = request.getParameter("draw");
String name = request.getParameter("name");
String name = request.getParameter("age");
String searchName = request.getParameter("search[value]");
String start = request.getParameter("start");
String count = request.getParameter("length");
JqueryDataTableDto jqueryDataTableDto = testService.selectTestList(name,age,searchName,start,count);
jqueryDataTableDto.setDraw(draw);
String data= net.sf.json.JSONObject.fromObject(jqueryDataTableDto).toString();
model.addAttribute("json", data);
return "/common/json";
}
@RequestMapping(value = "/selectTypeList")
public String selectTypeList(Model model) throws Exception {
JSONObject obj = testService.selectTypeList();
model.addAttribute("json", obj.toString());
return "/common/json";
}
}
TestService接口
public interface TestService {
public JqueryDataTableDto selectTestList(String name, String age, String searchName, String start, String count);
public JSONObject selectTypeList();
}
TestServiceImpl业务逻辑实现类
import net.sf.json.JSONObject;
import net.sf.json.JSONArray;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
@Override
public JqueryDataTableDto selectTestList(String name, String age, String searchName, String start, String count) {
JqueryDataTableDto jqueryDataTableDto=new JqueryDataTableDto();
List<TestList> list = testMapper.selectTestList(name,age,searchName,start,count);
int total = testMapper.selectTotalCount();
int filterTotal = testMapper.selectRecordsFiltered(name,age,searchName);
jqueryDataTableDto.setRecordsTotal(total);
jqueryDataTableDto.setRecordsFiltered(filterTotal);
jqueryDataTableDto.setData(list);
return jqueryDataTableDto;
}
@Override
public JSONObject selectTypeList() {
Map<String,String> map = new HashMap<>();
JSONObject obj = new JSONObject();
JSONArray array = new JSONArray();
TypeList typeList = new TypeList();
List<String> nameList = testMapper.selectNameList();
List<String> ageList = testMapper.selectAgeList();
array.addAll(nameList);
array.addAll(ageList);
map.put("data", array.toString());
obj.putAll(map);
return obj;
}
}
TestMapper接口加载mybatis映射文件
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface TestMapper {
// 查询总数
public int selectTotalCount();
// 根据条件获取筛选后的总数
public int selectRecordsFiltered(@Param("name") String name,
@Param("age") String age,
@Param("searchName") String searchName);
// 名字集合
public List<String> selectNameList();
// 年龄集合
public List<String> selectAgeList();
// 分页数据
public List<TestList> selectTestList(@Param("name") String name,
@Param("age") String age,
@Param("searchName") String searchName,
@Param("start") String start,
@Param("count") String count);
}
TestMapper.xml映射文件
<?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.test.www.TestMapper">
<select id="selectTestList" resultType="TestList">
SELECT
DISTINCT id,name,age,sex
FROM test
WHERE isDeleted=0
<include refid="search"></include>
limit ${start},${count}
</select>
<select id="selectRecordsFiltered" resultType="int">
SELECT COUNT(*)
FROM test
WHERE isDeleted=0
<include refid="search"></include>
</select>
<sql id="search">
<if test="name!=null and name!=''">
AND name=#{name}
</if>
<if test="age!=null and age!=''">
AND age=#{age}
</if>
<if test="searchName!=null and searchName!=''">
AND CONCAT(IFNULL(name,''),IFNULL(age,''),IFNULL(sex,'')) LIKE CONCAT('%',#{searchName},'%')
</if>
</sql>
<select id="selectTotalCount" resultType="int">
SELECT count(*) FROM test WHERE isDeleted = 0
</select>
<select id="selectNameList" resultType="String">
SELECT DISTINCT name
FROM test
WHERE isDeleted = 0
</select>
<select id="selectAgeList" resultType="String">
SELECT DISTINCT age
FROM test
WHERE isDeleted = 0
</select>
</mapper>
如果遇到多张表模糊查询的时可以使用GROUP_CONCAT拼接页面上可以搜索的字段
当中的selectRecordsFiltered方法可修改为如下写法
<select id="selectRecordsFiltered" resultType="int">
SELECT COUNT(*) FROM (
SELECT
GROUP_CONCAT(CONCAT(t.testName,p.projectName,f.fieldName,u.userName,t.createTime))
AS searchName
FROM test t LEFT JOIN user u ON s.creator=u.userId
JOIN field f ON t.fieldId = f.fieldId
LEFT JOIN project p ON t.projectId = p.projectId
WHERE t.isDeleted=0
GROUP BY t.testId
<if test="searchName != null and searchName != ''">
HAVING searchName LIKE CONCAT('%',#{searchName},'%')
</if>
) AS s
</select>
其中查询所有的selectTestList修改为如下写法
<select id="selectTestList" resultType="TestList">
SELECT
DISTINCT t.testName,f.fieldName,
u.userName,t.createTime,f.fieldName,
p.projectId,p.projectName,
GROUP_CONCAT(CONCAT(t.testName,p.projectName,f.fieldName,u.userName,t.createTime))
AS searchName
FROM test t
JOIN user u ON t.creator=u.userId
JOIN field f ON s.fieldId = f.fieldId
LEFT JOIN project p ON t.projectId = p.projectId
WHERE s.isDeleted=0
<include refid="search"></include>
GROUP BY t.testId
<if test="searchName != null and searchName != ''">
HAVING searchName LIKE CONCAT('%',#{searchName},'%')
</if>
ORDER BY t.testId DESC
limit ${start},${count}
</select>
如果数据量大,多张表join on关联查询慢的话,我们可以为被驱动表的join字段添加索引,比如:
user表的userId field表的fieldId project表的projectId 都单独添加上普通索引