前后端分离的意思是,前后端只通过 JSON 来交流,组件化、工程化不需要依赖后端去实现:
下面以代码来讲解使用Ajax跨域请求后端数据并分页展示在前台中:
后端代码如下:
Dao层:数据访问层,实现对数据表的Select(查询),Insert(插入),Update(更新),Delete(删除)等操作,以及对象实体的持久化;
BaseDao 执行数据库操作的工具类
package com.cn.Demo.dao; import com.cn.Demo.util.DatabaseUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * 执行数据库操作的工具类。 */ public class BaseDao { private Connection conn; /** * 增、删、改操作的方法 * * @param sql sql语句 * @param prams 参数数组 * @return 执行结果 * @throws SQLException */ protected int executeUpdate(String sql, Object... params) throws SQLException { int result = 0; conn=DatabaseUtil.getConnection(); PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { pstmt.setObject(i + 1, params[i]); } result = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); throw e; } finally { DatabaseUtil.closeAll(null, pstmt, null); } return result; } /** * 查询操作的方法 * * @param sql sql语句 * @param params 参数数组 * @return 查询结果集 * @throws SQLException */ protected ResultSet executeQuery(String sql, Object... params) throws SQLException { PreparedStatement pstmt = null; conn=DatabaseUtil.getConnection(); ResultSet rs = null; try { pstmt = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { pstmt.setObject(i + 1, params[i]); } rs = pstmt.executeQuery(); } catch (SQLException e) { e.printStackTrace(); throw e; } return rs; } }
UserDao用户信息分页展示的接口:
package com.cn.Demo.dao; import com.cn.Demo.vo.User; import java.util.List; import java.util.Map; public interface UserDao { /** * 分页查询数据 * @param param 分页内容 * @return 数据集合 */ public List<User> getPagination(Map<String, Object> param); }
UserDaoImpl:UserDao接口的实现类
package com.cn.Demo.dao.Impl; import com.cn.Demo.dao.BaseDao; import com.cn.Demo.dao.UserDao; import com.cn.Demo.entity.User; import com.cn.Demo.util.DatabaseUtil; import com.cn.Demo.vo.User; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; public class UserDaoImpl extends BaseDao implements UserDao { @Override public List<User> getPagination(Map<String, Object> param) { List<User> userList = new ArrayList<User>(); ResultSet rs = null; try { //拼接Sql语句
StringBuffer sb = new StringBuffer();
sb.append("select * from easybuy_user ");
if (param.get("pageIndex") != null && param.get("pageSize") != null) { sb.append(" Limit ?,? "); } //拼接可变参数 Object[] pa = new Object[]{param.get("pageIndex"), param.get("pageSize")}; //获取结果集 rs = executeQuery(sb.toString(),pa); while (rs.next()) { User user = new User(); user.setId(rs.getInt("id")); user.setLoginName(rs.getString("loginName")); user.setUserName(rs.getString("userName")); user.setPassword(rs.getString("password")); user.setSex(rs.getInt("sex")); user.setIdentityCode(rs.getString("identityCode")); user.setEmail(rs.getString("email")); user.setMobile(rs.getString("mobile")); user.setType(rs.getInt("type")); userList.add(user); } } catch (SQLException e) { e.printStackTrace(); } finally { DatabaseUtil.closeAll(null, null, rs); } return userList; } }
entity:User的实体类(对应数据库的字段)
package com.cn.Demo.entity; import java.io.Serializable; public class User implements Serializable { private Integer id=null; //用户id private String loginName=null; //用户登录名 private String userName=null;//用户名称 private String password=null;//登陆密码 private Integer sex=null;//用户性别 private String identityCode=null;//用户身份证号 private String email=null;//用户邮箱 private String mobile=null;//用户手机 private Integer type=null;//用户类型 //省略getter和setter方法 }
service层:业务逻辑层负责系统领域业务的处理,负责逻辑性数据的生成、处理及转换。对所输入的逻辑性数据的正确性及有效性负责,但对输出的逻辑性数据及用户性数据的正确性不负责,对数据的呈现样式不负责;
UserService :业务逻辑层的接口
package com.cn.Demo.service; import com.cn.Demo.entity.User; import com.cn.Demo.vo.User; import java.util.List; import java.util.Map; public interface UserService { /** * 分页查询数据 * @param param 分页内容 * @return 数据集合 */ public List<User> getPagination(Map<String, Object> param); }
UserServiceImpl:UserService接口的实现类
package com.cn.Demo.service.Impl; import com.cn.Demo.dao.Impl.UserDaoImpl; import com.cn.Demo.dao.UserDao; import com.cn.Demo.entity.User; import com.cn.Demo.service.UserService; import com.cn.Demo.vo.User; import java.util.List; import java.util.Map; public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoImpl(); @Override public List<User> getPagination(Map<String, Object> param) { return userDao.getPagination(param); } }
servlet:实现对前端数据的打印,将数据输出给前端
userServlet
package com.cn.Demo.servlet; import com.alibaba.fastjson.JSONObject; import com.cn.Demo.dto.ResultDTO; import com.cn.Demo.entity.User; import com.cn.Demo.service.Impl.UserServiceImpl; import com.cn.Demo.service.UserService; import com.cn.Demo.vo.UserVO; 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.util.HashMap; import java.util.List; import java.util.Map; @WebServlet(name = "userServlet", value = "/user") public class userServlet extends HttpServlet { private UserService userService = new UserServiceImpl(); int pageSize = 5;//页面大小 int pageIndex = 1;//当前页数 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); //开启跨域请求 response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Methods","POST,GET"); Map<String, Object> param = new HashMap<>(); //获取分页参数以及页码参数 if (request.getParameter("pageIndex") != null) { pageIndex = Integer.valueOf(request.getParameter("pageIndex")); } if (request.getParameter("pageSize") != null) { pageSize = Integer.valueOf(request.getParameter("pageSize")); } param.put("pageIndex", (pageIndex - 1) * pageSize); param.put("pageSize", pageSize); List<User> list = userService.getPagination(param);//输出前台 response.getWriter().write(JSONObject.toJSONString(dot,true)); } }
util:工具类:
ConfigManager:数据库参数配置文件查找工具类
package com.cn.Demo.util; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 数据库参数配置文件查找工具类 * @author 逆風〠飛 * */ public class ConfigManager { private static Properties props = null; static { InputStream is = null; is = ConfigManager.class.getClassLoader().getResourceAsStream("DB.properties"); if (is == null) throw new RuntimeException("找不到数据库参数配置文件"); props = new Properties(); try { props.load(is); } catch (IOException e) { throw new RuntimeException("数据库配置参数加载错误!", e); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } public static String getProperty(String key) { return props.getProperty(key); } }
DatabaseUtil :数据库参数配置文件查找工具类
package com.cn.Demo.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 数据库连接与关闭工具类 * */ public class DatabaseUtil { private static String driver = ConfigManager.getProperty("jdbc.driver");// 数据库驱动字符串 private static String url = ConfigManager.getProperty("jdbc.url"); // 连接URL字符�? private static String user = ConfigManager.getProperty("jdbc.username"); // 数据库用户名 private static String password = ConfigManager.getProperty("jdbc.password"); // 用户密码 static { try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 获取数据库连接对象 */ public static Connection getConnection() throws SQLException { // 获取连接并捕获异常 Connection conn = null; try { conn = DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.printStackTrace(); throw e; } return conn;// 返回连接对象 } /** * * 关闭数据库连连接 * @param conn 数据库连接 * @param stmt Statement对象 * @param rs 结果集 */ public static void closeAll(Connection conn, Statement stmt, ResultSet rs) { // 若结果集对象不为空,则关闭 try { if (rs != null && !rs.isClosed()) rs.close(); } catch (Exception e) { e.printStackTrace(); } // 若Statement对象不为空,则关闭 try { if (stmt != null && !stmt.isClosed()) stmt.close(); } catch (Exception e) { e.printStackTrace(); } // 若数据库连接对象不为空,则关闭 try { if (conn != null && !conn.isClosed()) conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
前端代码:
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="css/index.css"> <script rel="script" src="js/jquery-3.3.1.min.js"></script> <script rel="script" src="js/index.js"></script> </head> <body> <div class="container"> <div class="left"> <h2>此处图片为固定参照物</h2> <img src="image/pic02.jpg" alt=""> </div> <div class="right"> <table class="tb" border="0" cellpadding="0" cellspacing="0"> <tr> <th>id</th> <th>账号</th> <th>昵称</th> <th>性别</th> <th>手机</th> <th>邮箱</th> <th>类型</th> <th>identityCode</th> <th>操作</th> </tr> <tbody id="t_body"> </tbody> </table> <div class="page"> <button id="firstPage">首页</button>    <button id="previous">上一页</button>    第<input type="text" id="index" value="1" size="1" >页    <button id="next">下一页</button>    <button id="last">尾页</button> <div id="pageCount" style="display: inline-block"></div> </div> </div> </div> </body> </html>
css:简单的css布局
*{margin: 0;padding: 0} .container{width: 90%;border: 1px solid #999;margin: 0px auto;margin: 80px} .container>div{float: left} .container:after{content: '';display: block;clear: both} .left{width: 24%;border: 1px solid #f40000} .right{width: 70%;border: 1px solid rgba(255,255,255,.5)} .tb{width: 1050px} .tb th{background-color: #108ee9;color: #fff} .tb tr{height: 40px;line-height: 40px;text-align: center} .tb tr:hover{background: #9af5ff } h2{text-align: center} img{width: 330px;padding: 1px} .page{margin-left: 35%;margin-top: 10px;background-color: #f0f0f0;width: 297px;} #index{text-align: center;border: none;font-weight: bold}
js:Ajax异步请求后台数据并在前台并分页展示
var pageSize = "5";//每页行数 var pageIndex = "1";//当前页 var totalPageCount = "0";//总页数 var totalCount = "0";//总记录数 //jquery代码随着document加载完毕而加载 $(document).ready(function () { //分页查询 function queryForPages() { $.ajax({ url: 'http://localhost:8080/user', type: 'post', dataType: 'json', data: "pageIndex=" + pageIndex + "&pageSize=" + pageSize, success: function callbackFun(data) { //清空数据 clearDate(); //查询数据 fillTable(data); } }); } //填充数据 function fillTable(data) { var trs = "";//不初始化字符串"",会默认"undefined"
for (var i in data.data) { totalCount++; var tr="<tr>" +"<td>"+data.data[i].id+"</td>" +"<td>"+data.data[i].loginName+"</td>" +"<td>"+data.data[i].userName+"</td>" +"<td>"+data.data[i].sex+"</td>" +"<td>"+data.data[i].mobile+"</td>" +"<td>"+data.data[i].email+"</td>" +"<td>"+data.data[i].type+"</td>" +"<td>"+data.data[i].identityCode+"</td>" +"<td>删除</td>" +"</tr>"; trs += tr; $("#t_body").html(trs); } totalPageCount = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize + 1); } //清空数据 function clearDate() { $("#t_body").html(""); } //首页 $("#firstPage").click(function () { //var index=$("#index").val(); pageIndex = "1"; $("#index").val(pageIndex); queryForPages(); }); //上一页 $("#previous").click(function () { if (pageIndex > 1) { pageIndex--; } $("#index").val(pageIndex); queryForPages(); }); //下一页 $("#next").click(function () { if (pageIndex < totalPageCount) { pageIndex++; } $("#index").val(pageIndex); queryForPages(); }); //尾页 $("#last").click(function () { pageIndex = totalPageCount; $("#index").val(pageIndex); queryForPages(); }); });
Mysql数据库字段如下:
展示效果: