效果图
项目结构:
这里我没有使用规范的 MVC思想和三层架构
项目使用骨架或者说Maven模板创建的,就是阿帕奇 webapp的那个模板
记得在webapp下加入官网下载的layui包
servlet包下代码
package servlet;
import com.alibaba.fastjson.JSON;
import model.User;
import util.DBUtil;
import util.ResultData;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.List;
//设置当前Servelt的前端请求映射路径
@WebServlet("/limit")
public class TurnPagesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Connection conn =null;
PreparedStatement ps=null;
ResultSet rs =null;
Statement st=null;
ResultSet rs2 =null;
/*
获得layui前端传来的数据
layui官方文档说的:
?page=1&limit=30(该参数可通过 request 自定义)
page 代表当前页码、limit 代表每页数据量
*/
int PageNum= Integer.parseInt(req.getParameter("page"));
int PageSize=Integer.parseInt(req.getParameter("limit"));;
//分页查询数据库表中的数据 sql语句
String sql="select * from tb_user limit ?,?";
//获取表的总记录数,用来响应返回给前端layui,也是分页查询必须遵守的格式
String count="SELECT COUNT(*) FROM tb_user";
int anInt=0;
try {
//查询表的总记录数
conn= DBUtil.getConnection();
st= conn.createStatement();
rs2=st.executeQuery(count);
while (rs2.next()){
anInt= rs2.getInt(1);
System.out.println(anInt);
}
//分页查询数据库表中的数据
ps= conn.prepareStatement(sql);
ps.setInt(1,PageNum);
ps.setInt(2,PageSize);
rs=ps.executeQuery();
//使用封装的方法,用List来接收返回类型
List<User> listuser = DBUtil.selectAll(sql,User.class,PageNum,PageSize);
//告诉浏览器返回的数据是json格式的
resp.setContentType("application/json;charset=utf-8");
//准备给浏览器响应写出数据
PrintWriter out = resp.getWriter();
//使用实体类的方式保存数据,这里的数据一定要按照这种方式存放:
/*
{
"code":0,
"msg":"",
"cound":1000,
"data":[{},{}]
}
在前端页面已经强调过的,只有这样layui接收到指定格式的数据才会渲染页面
*/
ResultData resultData = new ResultData( );
resultData.setCode(0);
resultData.setMsg("OK");
resultData.setCount(anInt);
resultData.setData(listuser);
System.out.println("查到数据返回给前端数据");
//使用FastJson专业用于转换JSON(阿里巴巴开源) pom依赖中导入的jar包
//这个方法会根据提供的实体类来帮助我们把数据转换成json格式的数据
//不使用这个方法,那我们就要写很长一段字符串形式的json数据去拼接很长一段的代码
String jsonStr = JSON.toJSONString(resultData);
System.out.println(listuser);
//写出给浏览器,就是谁请求响应给谁
out.write(jsonStr);
} catch (SQLException e) {
e.printStackTrace();
}finally {
//使用封装的工具类关流,st是自己创建的自己关
DBUtil.closeAll(conn,ps,rs);
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
封装的数据库工具类
package util;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* --- 天道酬勤 ---
*
* @author QiuShiju
* @desc
*/
public class DBUtil {
// 创建Properties类对象,专用于操作properties文件
private static final Properties properties = new Properties( );
// 声明Druid连接池的连接池对象
// 数据连接,一般称作数据源 dataSource
private static DruidDataSource dataSource;
static {
try {
InputStream inputStream = DBUtil.class.getResourceAsStream("/jdbc.properties");
properties.load(inputStream);
// 不需要由我们加载驱动
// 需要给dataSource赋值
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
System.out.println("加载驱动异常!!");
e.printStackTrace( );
}
}
public static Connection getConnection() {
Connection conn = null;
try {
// 不需要我们获得连接
// 而是通过Druid获得
conn = dataSource.getConnection( );
} catch (Exception e) {
System.out.println("获得连接出异常!!!");
e.printStackTrace( );
}
return conn;
}
/**
* 关闭所有流
*/
public static void closeAll(Connection conn, Statement s) {
if (conn != null) {
try {
conn.close( );
} catch (SQLException throwables) {
throwables.printStackTrace( );
}
}
if (s != null) {
try {
s.close( );
} catch (SQLException throwables) {
throwables.printStackTrace( );
}
}
}
public static void closeAll(Connection conn, Statement s, ResultSet rs) {
if (conn != null) {
try {
conn.close( );
} catch (SQLException throwables) {
throwables.printStackTrace( );
}
}
if (s != null) {
try {
s.close( );
} catch (SQLException throwables) {
throwables.printStackTrace( );
}
}
if (rs != null) {
try {
rs.close( );
} catch (SQLException throwables) {
throwables.printStackTrace( );
}
}
}
/**
* 封装查询方法,返回一个对象
* 参数1 执行查询的SQL,预处理的,条件用?占位
* select * from tb_user where id = ? and username = ? and password = ?
* 参数2 结果要封装的类
* 参数3 给?赋值,不定长参数,是数组
* 1,admin,123456
*/
public static <T> T selectOne(String sql, Class<T> t, Object... args) {
Connection conn = getConnection( );
PreparedStatement ps = null;
ResultSet rs = null;
T target = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; args != null && i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery( );
/**
* 创建对象
* 从数据库取出数据,并设置对象属性
*/
while (rs.next( )) {
target = t.newInstance( );
Field[] declaredFields = t.getDeclaredFields( );
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
Object value = rs.getObject(field.getName( ));
// 破解私有
field.setAccessible(true);
// 给对象的该字段赋值
field.set(target, value);
}
}
} catch (Exception e) {
e.printStackTrace( );
} finally {
closeAll(conn, ps, rs);
}
return target;
}
public static <T> List<T> selectAll(String sql, Class<T> t, Object... args) {
Connection conn = getConnection( );
PreparedStatement ps = null;
ResultSet rs = null;
T target = null;
ArrayList<T> list = new ArrayList<>( );
try {
ps = conn.prepareStatement(sql);
for (int i = 0; args != null && i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery( );
/**
* 创建对象
* 从数据库取出数据,并设置对象属性
*/
while (rs.next( )) {
target = t.newInstance( );
Field[] declaredFields = t.getDeclaredFields( );
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
Object value=rs.getObject(field.getName( ));
// 破解私有
field.setAccessible(true);
field.set(target,value);
}
list.add(target);
}
} catch (Exception e) {
e.printStackTrace( );
} finally {
closeAll(conn, ps, rs);
}
return list;
}
/**
* 增删改方法一样
*/
public static boolean update(String sql, Object... args) {
Connection conn = getConnection( );
PreparedStatement ps = null;
int num = 0;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; args != null && i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
num = ps.executeUpdate( );
} catch (Exception e) {
e.printStackTrace( );
} finally {
closeAll(conn, ps);
}
return num > 0 ? true : false;
}
}
实体类代码
User实体类
package model;
import java.util.Date;
/**
* -----------天道酬勤---------------
* ---------为了睡抖音美女而努力----
*
* @author: DamianHan
* @create: 2022-11-30 16:13
* @description:
**/
public class User {
private int id;
private String username;
private String password;
private String phone;
private Date createTime;
private double money;
private int sex;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", phone='" + phone + '\'' +
", createTime=" + createTime +
", money=" + money +
", sex=" + sex +
'}';
}
public void m1(int a){
System.out.println("m1(int "+a+")...." );
}
public String m1(){
System.out.println("m1()...." );
return "m1()-ret";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
util包下的ResultData实体类
package util;
/**
* --- 天道酬勤 ---
*
* @author QiuShiju
* @desc 用于前后端交互的数据类
*/
public class ResultData {
private int code;
private int count;
private String msg;
private Object data;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
resources 包下资源文件代码
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/要使用的库?useSSL=false
username=自己数据账号
password=自己数据密码
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
maxWait=5000```
前端页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表格</title>
<!-- 引入Layui.css核心样式-->
<link rel="stylesheet" href="layui-v2.7.6/layui/css/layui.css">
<style>
*{
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<h1 style="text-align: center">tb_user信息表</h1>
<!--layui里的栅格系统-->
<div class="layui-container">
<div class="layui-row">
<!-- layui-col-md-offset3偏移量在原有md8基础上调整位置的-->
<!-- <div class="layui-col-md8 layui-col-md-offset3">-->
<div class="layui-col-md12">
<teble id="test"></teble>
</div>
</div>
</div>
<!--引入Layui.js核心-->
<script src="layui-v2.7.6/layui/layui.js"></script>
<script>
/**
*【非常重要】【非常重要】【非常重要】【非常重要】
* 1 table 渲染数据的前提,后台返回的数据一定是json
* 2 且json格式必须是
* {
* "code":0,
* "msg":"",
* "cound":1000,
* "data":[{},{}]
* }
* ,如果不是,那么就需要通过parseDate来转换
* 3 code必须是0时,认为是成功,才会渲染出效果
*/
//使用layui里的table组件或者模块,具体可以去看看02表单里的说法
layui.use("table",function (){
var table=layui.table;
table.render({
elem:"#test", //绑定表格元素
height:312, //设置表格的高度
url:"http://localhost:8080/limit", //指向后端servlet的路径
page:true, //开启分页功能
//遍历获取后端传来的数据,获取格式都是官方文档给出的
cols:[[
{field:"id",title:"ID"},
{field:"username",title:"用户名"},
{field:"password",title:"密码"},
{field:"phone",title:"手机"},
// templet - 自定义列模板 需要自己查阅官方文档
{field:"createTime",title:"注册时间",templet:function (d){
let now=new Date(d.createTime);
let year=now.getFullYear();
let month=now.getMonth()+1;
let day=now.getDate();
return year+"年"+month+"月"+day+"日"
}},
{field:"money",title:"余额"},
// templet - 自定义列模板 需要自己查阅官方文档
{field:"sex",title:"性别",templet:function (d){
return d.sex==1?'男':'女';
}}
]
],
method:"get", //设置请求方式
limit: 3 //设置分页的页数
})
})
</script>
</body>
</html>
pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hm</groupId>
<artifactId>day52_layui</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>day52_layui Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- servlet-jsp -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- FastJson专业也用于转换JSON(阿里巴巴开源)-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
</dependencies>
</project>