对《慕课网》分页教程的感悟一

Posted startor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对《慕课网》分页教程的感悟一相关的知识,希望对你有一定的参考价值。

  金秋十月,国庆中秋佳节之际,或是以观慕课网而学之。

  分页:这个以前我无数次所使用过的功能,但是这一次看过之后,才知道是我以前所理解的是如此的稚嫩。

  简单的说一下感悟吧,或者说是简单的将一些自己还没有做到的东西来进行观摩。当然,得谢谢慕课网的老师进行的分享。

   

  对于分页,作者从 sublist 以及 sql 语句和hibernate框架三个方面进行讲解:

  首先,我们说一下使用 sublist 方法进行的其中奥义:

  程序总体采用MVC的设计模式,来进行分析。

  这是整个目录的结构

    提点:

      1.再程序中使用了filter , 这个功能似乎看起来是如此的不起眼,但是我们又有多少人会去主动的使用这个功能呢

          具体: 实现 Filter 接口,将 请求和响应的编码进行统一的设置,保证了比较合理的编码统一性。

          代码实现:

          

package com.imooc.page;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class EncodingFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

 

       2.其次,再平常我们所使用jdbc进行链接数据库的时候,都是直接将代码进行设置用户名和密码,但是这里我们使用的jdbc.properties ,然后在链接的工具类中进行设置,就能达到代码的复用性。还有作者在处理异常方面,也是以前的我并没有考虑过的问题,以前都是直接将异常捕捉但是没有任何的动作,作者在这里将异常进行处理了。

    

  throw new RuntimeException("读取数据库配置文件异常!", e);  //我们在进行异常处理的时候,就应该是这样来进行处理的

      jdbc.properties 这个文件是比较好建立的,但是怎么在程序中将他读出来呢?

      

       以反射的方式就能以流的方式将这个文件里面的内容进行传递。这一点我们需要学习。

      另外,想过这个方法在什么时候加载呢?

      我们可以将这个方法放在static代码块里面,在类第一次加载的时候进行加载,并且只会加载一次。静态方法只能调用静态方法哦!!!

      另外,复写过带参数的构造方法之后一定要记得在重写一个无参的构造方法。

       在使用sql语句中,使用到了占位符,这个东西也是我们以后必备,并且这里还是有着怎么填占位符里面的内容。

    另外这里记录一个错误:

        eclipse报错:Description Resource Path Location Type Target runtime com.genuitec.runtime.

        这个问题的解决方案网上有一种:打开org.eclipse.wst.common.project.facet.core.xml文件,并删除里面的一句<runtime name="" 即可,但是楼主并不清楚这样做有什么好处,还望告知。

      完整jdbcutil工具代码如下:

      

//------------------------------jdbc.properties------------------------------//
jdbc.username=root jdbc.password=123456 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/imooc
//---------------------------------------------------JdbcUtil-------------------------------// 

package
com.imooc.page.util; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; 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; import java.util.Properties; public class JdbcUtil { // 表示定义数据库的用户名 private static String USERNAME; // 定义数据库的密码 private static String PASSWORD; // 定义数据库的驱动信息 private static String DRIVER; // 定义访问数据库的地址 private static String URL; // 定义数据库的链接 private Connection connection; // 定义sql语句的执行对象 private PreparedStatement pstmt; // 定义查询返回的结果集合 private ResultSet resultSet; static { // 加载数据库配置信息,并给相关的属性赋值 loadConfig(); } /** * 加载数据库配置信息,并给相关的属性赋值 */ public static void loadConfig() { try { InputStream inStream = JdbcUtil.class.getResourceAsStream("/jdbc.properties"); Properties prop = new Properties(); prop.load(inStream); USERNAME = prop.getProperty("jdbc.username"); PASSWORD = prop.getProperty("jdbc.password"); DRIVER = prop.getProperty("jdbc.driver"); URL = prop.getProperty("jdbc.url"); } catch (Exception e) { throw new RuntimeException("读取数据库配置文件异常!", e); } } public JdbcUtil() { } /** * 获取数据库连接 * * @return 数据库连接 */ public Connection getConnection() { try { Class.forName(DRIVER); // 注册驱动 connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); // 获取连接 } catch (Exception e) { throw new RuntimeException("get connection error!", e); } return connection; } /** * 执行更新操作 * * @param sql * sql语句 * @param params * 执行参数 * @return 执行结果 * @throws SQLException */ public boolean updateByPreparedStatement(String sql, List<?> params) throws SQLException { boolean flag = false; int result = -1;// 表示当用户执行添加删除和修改的时候所影响数据库的行数 pstmt = connection.prepareStatement(sql); int index = 1; // 填充sql语句中的占位符 // 遍历一个list集合 if (params != null && !params.isEmpty()) { for (int i = 0; i < params.size(); i++) { pstmt.setObject(index++, params.get(i)); } } result = pstmt.executeUpdate(); flag = result > 0 ? true : false; return flag; } /** * 执行查询操作 * * @param sql * sql语句 * @param params * 执行参数 * @return * @throws SQLException */ public List<Map<String, Object>> findResult(String sql, List<?> params) throws SQLException { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); int index = 1; pstmt = connection.prepareStatement(sql); if (params != null && !params.isEmpty()) { for (int i = 0; i < params.size(); i++) { pstmt.setObject(index++, params.get(i)); } } resultSet = pstmt.executeQuery(); ResultSetMetaData metaData = resultSet.getMetaData(); int cols_len = metaData.getColumnCount(); while (resultSet.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < cols_len; i++) { String cols_name = metaData.getColumnName(i + 1); Object cols_value = resultSet.getObject(cols_name); if (cols_value == null) { cols_value = ""; } map.put(cols_name, cols_value); } list.add(map); } return list; } /** * 释放资源 */ public void releaseConn() { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException("释放资源失败", e); } } if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { throw new RuntimeException("释放资源失败", e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException("释放资源失败", e); } } } public static void main(String[] args) { JdbcUtil jdbcUtil = new JdbcUtil(); jdbcUtil.getConnection(); try { List<Map<String, Object>> result = jdbcUtil.findResult("select * from t_student", null); for (Map<String, Object> m : result) { System.out.println(m); } } catch (SQLException e) { throw new RuntimeException("查询数据失败", e); } finally { jdbcUtil.releaseConn(); } } }

另外数据库附上:

  

DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `stu_name` varchar(16) NOT NULL,
  `gender` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `address` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

INSERT INTO `t_student` VALUES (\'1\', \'王小军\', \'1\', \'17\', \'北京市东城区\');
INSERT INTO `t_student` VALUES (\'2\', \'李雷雷\', \'1\', \'16\', \'北京市朝阳区\');
INSERT INTO `t_student` VALUES (\'3\', \'张静\', \'2\', \'16\', \'北京市昌平区\');
INSERT INTO `t_student` VALUES (\'4\', \'王晓萌\', \'2\', \'17\', \'北京市顺义区\');
INSERT INTO `t_student` VALUES (\'5\', \'韩梅梅\', \'2\', \'16\', \'北京市朝阳区\');
INSERT INTO `t_student` VALUES (\'6\', \'李小军\', \'1\', \'17\', \'北京市海淀区\');
INSERT INTO `t_student` VALUES (\'7\', \'成龙\', \'1\', \'16\', \'北京市石景山区\');
INSERT INTO `t_student` VALUES (\'8\', \'李海飞\', \'2\', \'16\', \'北京市海淀区\');
INSERT INTO `t_student` VALUES (\'9\', \'罗红\', \'2\', \'16\', \'北京市朝阳区\');
INSERT INTO `t_student` VALUES (\'10\', \'孙海杰\', \'1\', \'16\', \'北京市石景山区\');
INSERT INTO `t_student` VALUES (\'11\', \'王海龙\', \'1\', \'16\', \'北京市东城区\');

 

  -----------------------------------------------------------------------以上就是对里面的一些基础内容和jdbc的连接方式产生的优异点----------------------------------------------------------------

 

  -----------------------------------------------------------------------下面我们开始步入正题--------------------------------------------------------------------------

  首先,我们先看modal层:

      modal层和我平时最大的不同点就是,他用了极多的构造方法。

  这是两个构造方法,第一个可以理解为赋值,后者呢?应该也是赋值的方法,只是这样多写一个构造方法或许有些得不偿失,当然,可能是有其他的功能, 具体我们在接着往下看。

  

 ------------------------------------------------------------Student.java-------------------------------------------


package
com.imooc.page.model; import java.io.Serializable; import java.util.Map; public class Student implements Serializable {
  
  
  //可以看到这里使用了序列化,但是序列化有什么作用呢?什么时候进行序列化呢?
  //序列化应该是和流有关系的,方便数据在网络中进行存储,那么在这里有什么作用呢?
private static final long serialVersionUID = -7476381137287496245L; private int id; //学生记录id private String stuName;//学生姓名 private int age; //学生年龄 private int gender; //学生性别 private String address;//学生住址 public Student() { super(); } public Student(int id, String stuName, int age, int gender, String address) { super(); this.id = id; this.stuName = stuName; this.age = age; this.gender = gender; this.address = address; } public Student(Map<String, Object> map){ this.id = (int)map.get("id"); this.stuName = (String)map.get("stu_name"); this.age = (int)map.get("age"); this.gender = (int)map.get("gender"); this.address = (String)map.get("address"); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Student [id=" + id + ", stuName=" + stuName + ", age=" + age + ", gender=" + gender + ", address=" + address + "]"; } }

 

 我们的主要功能是分页,那么就肯定有分页的一个对象类。

-----------------------------------------------------------------Pager<T>.java-------------------------------------------------
package
com.imooc.page.model; import java.io.Serializable; import java.util.List; public class Pager<T> implements Serializable { private static final long serialVersionUID = -8741766802354222579L; private int pageSize; // 每页显示多少条记录 private int currentPage; // 当前第几页数据 private int totalRecord; // 一共多少条记录 private int totalPage; // 一共多少页记录 private List<T> dataList; // 要显示的数据 /** * * @param pageNum * 就是所点击的页数 * @param pageSize * 每页显示多少条记录 * @param sourceList * 要显示的数据 对于其他的一些数据我们在程序中就能知道里面的具体参数数据 */ public Pager(int pageNum, int pageSize, List<T> sourceList) { if (sourceList == null || sourceList.isEmpty()) { return; } // 总记录条数 this.totalRecord = sourceList.size(); // 每页显示多少条记录 this.pageSize = pageSize; // 获取总页数 this.totalPage = this.totalRecord / this.pageSize; if (this.totalRecord % this.pageSize != 0) { this.totalPage = this.totalPage + 1; } // 当前第几页数据 this.currentPage = this.totalPage < pageNum ? this.totalPage : pageNum; // 起始索引 int fromIndex = this.pageSize * (this.currentPage - 1); // 结束索引 int toIndex = this.pageSize * this.currentPage > this.totalRecord ? this.totalRecord : this.pageSize * this.currentPage; this.dataList = sourceList.subList(fromIndex, toIndex); } public Pager() { } public Pager(int pageSize, int currentPage, int totalRecord, int totalPage, List<T> dataList) { super(); this.pageSize = pageSize; this.currentPage = currentPage; this.totalRecord = totalRecord; this.totalPage = totalPage; this.dataList = dataList; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalRecord() { return totalRecord; } public void setTotalRecord(int totalRecord) { this.totalRecord = totalRecord; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public List<T> getDataList() { return dataList; } public void setDataList(List<T> dataList) { this.dataList = dataList; } }

  这里还有一个常量类,可以将程序的复用性大大的增加:

  

package com.imooc.page;

public class Constant {

    /**
     * 男性
     */
    public static final int GENDER_MALE = 1;
    
    /**
     * 女性
     */
    public static final int GENDER_FEMALE = 2;
    
    /**
     * 默认每页显示多少条记录
     */
    public static final int DEFAULT_PAGE_SIZE = 5;
    
    /**
     * 默认显示第几页记录
     */
    public static final int DEFAULT_PAGE_NUM = 1;
    
    /**
     * 默认学生性别
     */
    public static final int DEFAULT_GENDER = 0;
}

 

 看完了我们有的modal层,我们就来看一下控制层,servlet

  判断从前端获取的数据是不是空的:

  

    另外还有如何校验参数是不是一个大于0的数字:

    

----------------------------------------------StringUtil.java-----------------------------------------------
package
com.imooc.page.util; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringUtil { /** * 校验字符串是否是大于0的数字 * @param string * @return */ public static boolean isNum(String string){
    //这是在java中对正则表达式的匹配方法,java中提供了专门的类来进行使用 Pattern Pattern pattern
= Pattern.compile("[1-9]{1}\\\\d*"); Matcher matcher = pattern.matcher(string); return matcher.matches(); } }

  

----------------------------------------------------------------SublistServlet.java-------------------------------------------------
package
com.imooc.page.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.imooc.page.Constant; import com.imooc.page.model.Pager; import com.imooc.page.model.Student; import com.imooc.page.service.StudentService; import com.imooc.page.service.SublistStudentServiceImpl; import com.imooc.page.util.StringUtil; public class SublistServlet extends HttpServlet { private static final long serialVersionUID = -3658128508633145268L; private StudentService studentService = new SublistStudentServiceImpl(); public java文件下载有啥区别慕课

Fiddler对安卓App抓包(逍遥模拟器APP)

前端学习资源汇总

慕课网初始机器学习.md

JavaScript入门--慕课网学习笔记

[Windows] 油猴脚本慕课网视频下载链接解析工具