这是基于DataTable框架下的java后台代码,主要展示的是分页和模糊查询的处理方式。话不多少,直接上代码:

  1. 前端页面
    .
  2. house表结构
create table house (
			houseId int (11),
			title varchar (96),
			price int (11),
			area float ,
			room int (11),
			floor int (11),
			totalFloor int (11),
			watchTimes int (11),
			buildYear int (4),
			status int (4),
			createTime datetime ,
			lastUpdateTime datetime ,
			cityEnName varchar (96),
			regionEnName varchar (765),
			cover varchar (96),
			direction int (11),
			distanceToSubway int (11),
			parlour int (11),
			district varchar (96),
			adminId int (11),
			bathroom int (11),
			street varchar (96),
			houseCode text ,
			primary key(houseId)
		);
  1. 前端返回值的封装
package com.kejizhentan.utils;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

/**
* @Description:    前端状态返回值的枚举类(用于封装状态码即对应的信息)
* @Author:         kejizhentan
* @CreateDate:     2021/2/12 18:41
* @UpdateUser:     kejizhentan
* @UpdateDate:     2021/2/12 18:41
* @UpdateRemark:  
* @Version:        1.0
*/
public enum StatusEnum {

    SUCCESS(200,"success"),
    PARAMS_NULL(10000, "params is null"),
    RESULR_BAD(1002,"result is bad"),
    RESULT_NULL(10001, "result is null");
    @Getter
    @Setter
    private int code;
    @Getter
    @Setter
    private String message;

    StatusEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

}
package com.kejizhentan.utils;

import lombok.Getter;
import lombok.Setter;

/**
* @Description:    接口返回前端通用JSON格式
* @Author:         kejizhentan
* @CreateDate:     2021/2/12 18:57
* @UpdateUser:     kejizhentan
* @UpdateDate:     2021/2/12 18:57
* @UpdateRemark:   无
* @Version:        1.0
*/

public class ApiResponse{
    @Getter
    @Setter
    private  int code; //状态码
    @Getter
    @Setter
    private  String message; //状态码
    @Getter
    @Setter
    private Object data; //返回结果

    public ApiResponse(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * @author kejizhentan
     * @params Object data
     * @return ApiResponse
     * @date 2021/2/12 21:15
     * @Description 返回前端成功的API
    */

    public static ApiResponse ofSuccessMessage(Object data){
        return new ApiResponse(StatusEnum.SUCCESS.getCode(),StatusEnum.SUCCESS.getMessage(),data);
    }

    /**
     * @author kejizhentan
     * @params Object data
     * @return ApiResponse
     * @date 2021/2/12 21:15
     * @Description 返回前端失败的API
     */
    public static ApiResponse ofErrorMessage(int code,String message){
        return new ApiResponse(code,message,null);
    }

    public ApiResponse() {
    }
}
package com.kejizhentan.utils;

import lombok.Data;

@Data
public class ApiDataTablesResponse extends ApiResponse {

    private int draw;//Datatables发送的draw是多少那么服务器就返回多少
    private int recordsTotal;//数据库里总共记录数
    private int recordsFiltered;//过滤后的记录数

    public ApiDataTablesResponse( int draw, int recordsTotal, int recordsFiltered) {
        this.draw = draw;
        this.recordsTotal = recordsTotal;
        this.recordsFiltered = recordsFiltered;
    }
}
  1. 实体类
package com.kejizhentan.entity;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * @Author: likang
 * @Date: 2019/11/12 9:01
 * @Description: 房源管理查询参数字段封装对象
 */
@Data
public class DataTableSearch {

    private String direction;//排序方式
    private String orderBy;//排序字段

    @DateTimeFormat(pattern = "yyyy-MM-dd")//将接收到的时间类型转换成固定格式
    private Date createTimeMin;//创建时间--最小值
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date createTimeMax;//创建时间--最大值

    private int draw;//前端传输的特殊参数,无需做任何处理,直接传到后台即可
    private int start;//开始数据下标
    private int length;//请求个数


    private String city;//城市
    private String title;//标题
    private String status;//状态

}
package com.kejizhentan.entity;

import lombok.Data;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;

/**
 * @Author: kejizhentan
 * @Date: 2019/5/21 17:34
 * @Description: 房屋信息
 */

@Data
public class House {

    private Long houseId;//房屋ID

    //NotNull:当前对象在数据封装的时候,当前带有此注解,则不能为空,如果为空,则提示message信息
    @NotNull(message = "大标题不允许为空!")
    //Size:字段长度限制
    @Size(min = 1, max = 30, message = "标题长度必须在1~30之间")
    private String title;//大标题

    @NotNull(message = "必须填写租赁价格")
    @Min(value = 1)
    private int price;//价格

    @NotNull(message = "必须填写面积")
    private float area;//面积

    @NotNull(message = "必须填写卧室数量")
    @Min(value = 1, message = "非法的卧室数量")
    private int room;//卧室数量

    @NotNull(message = "必须填写所属楼层")
    private int floor;//楼层

    @NotNull(message = "必须填写总楼层")
    private int totalFloor;//总楼层
    private int watchTimes;//被看次数

    @NotNull(message = "必须填写建筑起始时间")
    @Min(value = 1900, message = "非法的建筑起始时间")
    private int buildYear;//建立年限
    private int status;//房屋状态 0-未审核 1-审核通过 2-已出租 3-逻辑删除
    private Date createTime;//创建时间
    private Date lastUpdateTime;//最近数据更新时间

    @NotNull(message = "必须选中一个城市")
    @Size(min = 1, message = "非法的城市")
    private String cityEnName;//城市标记缩写 如:bj

    @NotNull(message = "必须选中一个地区")
    @Size(min = 1, message = "非法的地区")
    private String regionEnName;//地区英文简写 如:昌平区 cpq
    private String cover;//封面

    @NotNull(message = "必须填写房屋朝向")
    private int direction;//房屋朝向
    private int distanceToSubway;//距地铁距离 默认-1 附近无地铁
    private int parlour;//客厅数量

    @NotNull(message = "必须填写小区")
    private String district;//所在小区
    private String adminId;//所属管理员id
    private int bathroom;

    @NotNull(message = "必须填写街道")
    @Size(min = 1, message = "非法的街道")
    private String street;//街道
    private String houseCode;//房本(唯一认证标识)


//    private HouseDetail houseDetail;//房屋详细信息

    @Size(max = 255)
    private String description;//详细描述
    private String layoutDesc;//户型介绍
    private String traffic;//交通出行
    private String roundService;//周边配套

    @NotNull(message = "必须选中一个租赁方式")
    @Min(value = 0)
    @Max(value = 1)
    private int rentWay;//租赁方式

    @NotNull(message = "详细地址不允许为空!")
    @Size(min = 1, max = 30, message = "详细地址长度必须在1~30之间")
    private String address;//详细地址
    private int subwayId;//附近地铁线id
    private String subwayName;//附近地铁线名称
    private int subwayStationId;//地铁站id
    private String subwayStationName;//地铁站名


    //private HouseDetail houseDetail;

    private List<HousePicture> photos;//房屋图片

    //private List<HouseTag> houseTags;

    private List<String> tags;//房屋标签名称


    private int subscribeStatus;//预约状态 1-加入待看清单 2-已预约看房时间 3-看房完成



}
  1. 控制层Controller
package com.kejizhentan.controller;

import com.kejizhentan.entity.DataTableSearch;
import com.kejizhentan.entity.House;
import com.kejizhentan.service.IHouseService;

import com.kejizhentan.utils.ApiDataTablesResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;


/**
 * @Author: kejizhentan
 * @Date: 2019/11/12 8:54
 * @Description: 房源管理列表控制器
 */
@Controller
public class AdminHouseListController {


    @Autowired
    IHouseService houseService;


    /**
    * @Description: 查询房源信息
     * ModelAttribute:可加,可以不加
     * 作用:前端请求参数中,只会按照名称进行匹配dataTableSearch中,不会安装类型匹配(过滤类型)(实体类中日期格式进行了转换)
     * 一般在dataTableSearch中,有进行数据类型的转换的时候,建议增加此注解
    * @Author: likang
    * @Date: 2019/11/12 9:04
    * @Param: [dataTableSearch]
    * @Return: com.xdl.utils.ApiDataTablesResponse
    * @Exception:
    */
    @PostMapping("/admin/houseList")
    public @ResponseBody
    ApiDataTablesResponse houseList(@ModelAttribute DataTableSearch dataTableSearch){

       List<House> houseList = houseService.queryHouseList(dataTableSearch);

        ApiDataTablesResponse apiDataTablesResponse =
                new ApiDataTablesResponse(dataTableSearch.getDraw(), houseService.houseCount(), houseList.size());
        apiDataTablesResponse.setData(houseList);

        return apiDataTablesResponse;

    }


}
  1. 服务层
package com.kejizhentan.service.impl;
import com.kejizhentan.dao.HouseDAO;
import com.kejizhentan.entity.*;
import com.kejizhentan.service.IHouseService;
import com.kejizhentan.utils.ServiceResult;
import com.kejizhentan.utils.UserInfoUtil;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class HouseServiceImpl implements IHouseService {

    @Autowired
    HouseDAO houseDAO;
    
    @Override
    public List<House> queryHouseList(DataTableSearch dataTableSearch) {
        return houseDAO.queryHouseList(dataTableSearch);
    }

    @Override
    public int houseCount() {
        return houseDAO.houseCount();
    }
}
package com.kejizhentan.service;


import com.kejizhentan.entity.DataTableSearch;
import com.kejizhentan.entity.House;
import com.kejizhentan.utils.ServiceResult;

import java.util.List;

/**
 * @Author: kejizhentan
 * @Date: 2019/11/8 10:51
 * @Description: 房屋信息接口---服务层
 */
public interface IHouseService {
    /**
     * @Description: 根据条件查询房源列表
     * @Author: likang
     * @Date: 2019/11/12 9:07
     * @Param: [dataTableSearch]
     * @Return: java.util.List<com.xdl.entity.House>
     * @Exception:
     */
    List<House> queryHouseList(DataTableSearch dataTableSearch);

    /**
     * @Description: 查询房源总条数
     * @Author: likang
     * @Date: 2019/11/12 9:24
     * @Param: []
     * @Return: int
     * @Exception:
     */
    int houseCount();

}
  1. DAO层
package com.kejizhentan.dao;


import com.kejizhentan.entity.*;

import java.util.List;

/**
 * @Author: kejizhentan
 * @Date: 2019/11/8 11:04
 * @Description: 房屋信息---持久化层
 */
public interface HouseDAO {
    /**
     * @Description: 根据条件查询房源列表
     * @Author: likang
     * @Date: 2019/11/12 9:08
     * @Param: [dataTableSearch]
     * @Return: java.util.List<com.xdl.entity.House>
     * @Exception:
     */
    List<House> queryHouseList(DataTableSearch dataTableSearch);

    /**
     * @Description: 查询房源总条数
     * @Author: likang
     * @Date: 2019/11/12 9:24
     * @Param: []
     * @Return: int
     * @Exception:
     */
    int houseCount();
}
  1. mapper.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.kejizhentan.dao.HouseDAO">
	<!--根据条件查询房源列表-->
    <select id="queryHouseList" parameterType="com.kejizhentan.entity.DataTableSearch" resultType="com.kejizhentan.entity.House">
        select *
        from house
        where 1=1
        <if test="city != null and city != ''">
            and cityEnName = #{city}
        </if>
        <if test="title != null and title != ''">
            and title like concat('%',#{title},'%')
        </if>
        <if test="createTimeMin != null">
            and createTime <![CDATA[ >= ]]>#{createTimeMin}
        </if>
        <if test="createTimeMax != null">
            and createTime <![CDATA[ <= ]]>#{createTimeMax}
        </if>
        order by ${orderBy} ${direction}
        limit #{start},#{length}
    </select>
    <!--查询房源总条数-->
    <select id="houseCount" resultType="java.lang.Integer">
        select count(1) from house
    </select>
</mapper>

知识点:
     1.@DateTimeFormat(pattern = “yyyy-MM-dd”)注解的使用
     2.@ModelAttribute注解的使用
     3.xml中的注意点:
       ①if条件中“并且”用and,“或者”用or
       ②注意拼接字符串concat(’%’,#{title},’%’)方法的使用
       ③注意转义符号<![CDATA[ ]]>的使用
       ④注意${}和#{}的区别,使用#传入参数是,sql语句解析是会加上"",当成字符串来解析,这样相比于${}的好处是比较明显对的吧,#{}传参能防止sql注入,如果你传入的参数为 单引号,那么如果用${}这种方式会报错的。另外一种场景是,如果要做动态的排序,比如 order by column,这个时候务必要用${}