一、前言
在上一次前端框架Layui分享选项卡的使用中,可以看到点击左侧右侧找不到路径(因为还未编写),所以这次基于上次的内容进行编写对用户管理页面进行增删改查操作。
因为这里的url页面我项目中还没有编写,所以404是必然的,不用管他!!!
1.什么是表格
表格(Table)是Web开发中常用的一种数据展示方式,用于以行和列的形式呈现结构化数据。表格由单元格(cell)组成,每个单元格可以包含文本、图像、链接等内容。
HTML中的表格通过<table>标签来定义,<tr>表示表格的行,<td>表示表格的单元格。可以使用<th>标签定义表格的表头(header)。
下面是一个简单的HTML表格示例:
<table> <tr> <th>姓名</th> <th>年龄</th> </tr> <tr> <td>小明</td> <td>20</td> </tr> <tr> <td>小红</td> <td>22</td> </tr> </table>
在这个示例中,表格有两列(姓名和年龄),第一行是表头,下面两行是数据行。每个单元格中的内容被包含在<td>标签中,而表头单元格则使用<th>标签。
通过使用表格,我们可以清晰地组织和显示大量的数据,例如展示员工列表、商品价格表、课程时间表等。可以使用CSS对表格进行样式化,调整表格的边框样式、背景颜色、字体样式等,以满足特定的设计要求。
需要注意的是,在使用表格时,应根据具体的需求选择合适的数据结构和布局方式。在某些情况下,使用表格可能不是最佳的解决方案,可以考虑使用其他的数据展示方式,例如列表、卡片布局等。
2.表格的使用范围
表格在Web开发中被广泛应用于不同场景,以下是一些表格的常见使用范围:
- 1. 数据展示:表格是一种常见的数据展示形式,适用于展示结构化的数据集合。例如,可以使用表格展示面向用户的数据,如员工列表、产品目录、订单信息等。
- 2. 数据分析:表格可以用于以表格形式展示、比较和分析数据。通过对表格进行排序、过滤和计算,可以更好地理解和解读数据。数据分析工具和报表系统通常使用表格来呈现结果。
- 3. 排名和比较:表格可以用于比较不同项的属性或指标,从而进行排名和排序。例如,可以使用表格展示运动员的成绩排名、学生的考试成绩等。表格可以根据特定的字段对数据进行排序,方便查找和对比。
- 4. 表单输入:表格常用于用户输入和编辑数据的场景。例如,可以使用表格来创建注册表单、调查问卷等。每个表格单元格可以包含各种输入字段(如文本框、复选框、下拉菜单等),方便用户输入和提交数据。
- 5. 日程安排和时间表:表格可以用于展示日程安排、课程时间表、会议日程等。每个单元格可以表示一个时间段,每一行代表一个时间点或一个实体(如人员、地点等)。
- 6. 响应式布局:表格可以通过CSS和响应式设计技术进行适应性布局,使其在不同屏幕尺寸下保持良好的显示效果。通过使用滚动、隐藏列、自适应宽度等功能,可以在小屏幕设备上显示较大的表格。
需要注意的是,在使用表格时应考虑数据的复杂性和可读性。对于大型数据集或复杂的数据结构,可以使用分页、筛选和搜索功能来改善用户体验。另外,合理地使用样式和交互效果可以提升表格的可用性和美观性。
二、案例实现
1.案例分析
①根据需求找到文档源码
这一次我们运用的组件是表格所以在官网中找到想要的组件内容进行“cv”操作即可。
②查询结果在实体中没有该属性
我们可以观察到表中有字段rid(角色身份),但是数据展示的时候需要将数字转换成相对应的字符,所以我们查询表的时候就要追加一个字段用来显示角色身份,但是我们eclipse的实体中并没有该属性,如果再写一个的以后遇到这种问题还是需要进行编写比较麻烦,所以我们可以采用Map集合的方式进行保存数据。
跟多细节在编写过程中慢慢讲解,下面请欣赏小编所写代码!!!
2.dao层编写
①BaseDao工具类
package com.zking.util; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 所有Dao层的父类 BookDao UserDao OrderDao ... * * @author Administrator * * @param <T> */ public class BaseDao<T> { /** * 适合多表联查的数据返回 * @param sql * @param pageBean * @return * @throws SQLException * @throws InstantiationException * @throws IllegalAccessException */ public List<Map<String, Object>> executeQuery(String sql, PageBean pageBean) throws SQLException, InstantiationException, IllegalAccessException { List<Map<String, Object>> list = new ArrayList<>(); Connection con = DBAccess.getConnection(); PreparedStatement pst = null; ResultSet rs = null; /* * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...) */ if (pageBean != null && pageBean.isPagination()) { // 必须分页(列表需求) String countSQL = getCountSQL(sql); pst = con.prepareStatement(countSQL); rs = pst.executeQuery(); if (rs.next()) { pageBean.setTotal(String.valueOf(rs.getObject(1))); } // 挪动到下面,是因为最后才处理返回的结果集 // -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%' // -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据 // -- countSql=select count(1) from (sql) t 符合条件的总记录数 String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据 pst = con.prepareStatement(pageSQL); rs = pst.executeQuery(); } else { // 不分页(select需求) pst = con.prepareStatement(sql);// 符合条件的所有数据 rs = pst.executeQuery(); } // 获取源数据 ResultSetMetaData md = rs.getMetaData(); int count = md.getColumnCount(); Map<String, Object> map = null; while (rs.next()) { map = new HashMap<>(); for (int i = 1; i <= count; i++) { // map.put(md.getColumnName(i), rs.getObject(i)); map.put(md.getColumnLabel(i), rs.getObject(i)); } list.add(map); } return list; } /** * * @param sql * @param attrs * map中的key * @param paMap * jsp向后台传递的参数集合 * @return * @throws SQLException * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalArgumentException * @throws IllegalAccessException */ public int executeUpdate(String sql, String[] attrs, Map<String, String[]> paMap) throws SQLException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Connection con = DBAccess.getConnection(); PreparedStatement pst = con.prepareStatement(sql); for (int i = 0; i < attrs.length; i++) { pst.setObject(i + 1, JsonUtils.getParamVal(paMap, attrs[i])); } return pst.executeUpdate(); } /** * 批处理 * @param sqlLst * @return */ public static int executeUpdateBatch(String[] sqlLst) { Connection conn = null; PreparedStatement stmt = null; try { conn = DBAccess.getConnection(); // 设置不自动提交 conn.setAutoCommit(false); for (String sql : sqlLst) { stmt = conn.prepareStatement(sql); stmt.executeUpdate(); } conn.commit(); } catch (Exception e) { try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); throw new RuntimeException(e1); } e.printStackTrace(); throw new RuntimeException(e); } finally { DBAccess.close(conn, stmt, null); } return sqlLst.length; } /** * 通用的增删改方法 * * @param book * @throws Exception */ public int executeUpdate(String sql, T t, String[] attrs) throws Exception { // String[] attrs = new String[] {"bid", "bname", "price"}; Connection con = DBAccess.getConnection(); PreparedStatement pst = con.prepareStatement(sql); // pst.setObject(1, book.getBid()); // pst.setObject(2, book.getBname()); // pst.setObject(3, book.getPrice()); /* * 思路: 1.从传进来的t中读取属性值 2.往预定义对象中设置了值 * * t->book f->bid */ for (int i = 0; i < attrs.length; i++) { Field f = t.getClass().getDeclaredField(attrs[i]); f.setAccessible(true); pst.setObject(i + 1, f.get(t)); } return pst.executeUpdate(); } /** * 通用分页查询 * * @param sql * @param clz * @return * @throws Exception */ public List<T> executeQuery(String sql, Class<T> clz, PageBean pageBean) throws Exception { List<T> list = new ArrayList<T>(); Connection con = DBAccess.getConnection(); ; PreparedStatement pst = null; ResultSet rs = null; /* * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...) */ if (pageBean != null && pageBean.isPagination()) { // 必须分页(列表需求) String countSQL = getCountSQL(sql); pst = con.prepareStatement(countSQL); rs = pst.executeQuery(); if (rs.next()) { pageBean.setTotal(String.valueOf(rs.getObject(1))); } // 挪动到下面,是因为最后才处理返回的结果集 // -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%' // -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据 // -- countSql=select count(1) from (sql) t 符合条件的总记录数 String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据 pst = con.prepareStatement(pageSQL); rs = pst.executeQuery(); } else { // 不分页(select需求) pst = con.prepareStatement(sql);// 符合条件的所有数据 rs = pst.executeQuery(); } while (rs.next()) { T t = clz.newInstance(); Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); f.set(t, rs.getObject(f.getName())); } list.add(t); } return list; } /** * 将原生SQL转换成符合条件的总记录数countSQL * * @param sql * @return */ private String getCountSQL(String sql) { // -- countSql=select count(1) from (sql) t 符合条件的总记录数 return "select count(1) from (" + sql + ") t"; } /** * 将原生SQL转换成pageSQL * * @param sql * @param pageBean * @return */ private String getPageSQL(String sql, PageBean pageBean) { // (this.page - 1) * this.rows // pageSql=sql limit (page-1)*rows,rows return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows(); } }
小贴士:
结合上面的案例需求,这里重构了executeQuery,可以发现这里的返回值不再是集合实体而是list集合里面存放Map集合,这样就算来再多字段我们也不用重新编写我们的实体类,直接调用该方法,利用Map进行存储即可。