Javaweb06-JDBC

打印 上一主题 下一主题

主题 925|帖子 925|积分 2775

1、jdbc.properties配置文件

jdbc.properties
  1. driverClass=com.mysql.jdbc.Driver
  2. jdbcUrl=jdbc:mysql://localhost:3306/animedb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8
  3. user=root
  4. password=root
复制代码
2、JDBCUtil 工具类

JDBCUtil.java
  1. package com.kgc.jdbc;
  2. import java.io.InputStream;
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.Statement;
  8. import java.util.Properties;
  9. /**
  10. * JDBC数据库操作工具类-都是公共的静态方法(不需要实例化),减少代码冗余
  11. * @author zhukang
  12. *
  13. */
  14. public class JDBCUtil {
  15.        
  16.         /**
  17.          * 读取外部的数据库连接信息配置文件,获取数据库连接对象
  18.          */
  19.         public static Connection getConnection() throws Exception {
  20.                
  21.                 // 创建Properties属性对象
  22.                 Properties properties = new Properties();
  23.                
  24.                 // 使用反射机制,读取外部配置文件
  25.                 InputStream inputStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
  26.                
  27.                 // 加载输入流对象,获取配置文件内容
  28.                 properties.load(inputStream);
  29.                
  30.                 // 读取数据库连接信息
  31.                 String driverClass = properties.getProperty("driverClass");
  32.                 String jdbcUrl = properties.getProperty("jdbcUrl");
  33.                 String user = properties.getProperty("user");
  34.                 String password = properties.getProperty("password");
  35.                
  36.                 // 加载驱动
  37.                 Class.forName(driverClass);
  38.                
  39.                 // 获取数据库连接对象
  40.                 return DriverManager.getConnection(jdbcUrl, user, password);
  41.         }
  42.        
  43.         /**
  44.          * 增删改的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
  45.          */
  46.         public static int update(String executeSql, Object ... params){
  47.                
  48.                 // 定义数据库连接和预处理操作对象
  49.                 Connection conn = null;
  50.                 PreparedStatement pstmt = null;
  51.                
  52.                 // 定义SQL语句执行的影响行数
  53.                 int row = 0;
  54.                
  55.                 // 公共执行增删改的处理代码
  56.                 try {
  57.                         // 获取数据库连接
  58.                         conn = getConnection();
  59.                        
  60.                         // 创建预处理操作对象
  61.                         pstmt = conn.prepareStatement(executeSql);
  62.                        
  63.                         // 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
  64.                         for (int i = 0; i < params.length; i++) {
  65.                                 pstmt.setObject(i + 1, params[i]);
  66.                         }
  67.                        
  68.                         // 执行增删改操作,并获取影响行数
  69.                         row = pstmt.executeUpdate();
  70.                 } catch (Exception e) {
  71.                         e.printStackTrace();
  72.                 } finally {
  73.                         releaseResource(conn, pstmt, null);
  74.                 }
  75.                
  76.                 // 返回影响行数
  77.                 return row;
  78.                
  79.         }
  80.        
  81.         /**
  82.          * 查询的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
  83.          */
  84.         public static ResultSet select(String executeSql, Object ... params){
  85.                
  86.                 // 定义数据库连接,预处理操作对象,结果集对象
  87.                 Connection conn = null;
  88.                 PreparedStatement pstmt = null;
  89.                 ResultSet rs = null;
  90.                
  91.                 // 公共执行查询的处理代码
  92.                 try {
  93.                         // 获取数据库连接
  94.                         conn = getConnection();
  95.                        
  96.                         // 创建预处理操作对象
  97.                         pstmt = conn.prepareStatement(executeSql);
  98.                        
  99.                         // 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
  100.                         for (int i = 0; i < params.length; i++) {
  101.                                 pstmt.setObject(i + 1, params[i]);
  102.                         }
  103.                        
  104.                         // 执行查询操作,并获取结果集
  105.                         rs = pstmt.executeQuery();
  106.                 } catch (Exception e) {
  107.                         e.printStackTrace();
  108.                 } finally {
  109.                         //最好不释放资源,因为rs要返回,关闭后,直接外层不可以使用
  110.                         releaseResource(conn, pstmt, rs);
  111.                 }
  112.                
  113.                 // 返回查询结果集
  114.                 return rs;
  115.                
  116.         }
  117.        
  118.         /**
  119.          * 释放数据库操作对象资源
  120.          */
  121.         public static void releaseResource(Connection conn, Statement stmt, ResultSet rs){
  122.                 try {
  123.                         // 手动释放
  124.                         if (null != rs) {
  125.                                 rs.close();
  126.                         }
  127.                        
  128.                         if (null != stmt) {
  129.                                 stmt.close();
  130.                         }
  131.                         if (null != conn) {
  132.                                 conn.close();
  133.                         }
  134.                 } catch (Exception e) {
  135.                         e.printStackTrace();
  136.                 }
  137.         }
  138. }
复制代码
3、作业总结技巧 (JdbcUtil 页面跳转  Jstl)

这些只是我个人的思考,可能会比较冗余,我是为了多思考,记录当时的感受;
且以访问资源为主和jstl,后面的以Ajax为主;
3.1Jstl妙用 (基于 Jstl遍历数据添加元素)

3.1 类型cid->类型名  显示数据时 外键信息对应

animesList:为动漫list集合的数据,放在request域中;
categoriesList:为动漫的类型,放在session域中(主要是因为方便修改和添加的时候方便获取类型);
外层循环,遍历每条动漫数据,内层循环,查询动漫对应的类型名称;
  1. <c:forEach items="${animesList}" var ="anime" varStatus="status">
  2.    
  3.     <c:forEach items="${categoriesList}" var ="category" varStatus="status">
  4.         
  5.         <c:if test="${ anime.cid eq category.id}" var="flag">
  6.             ${category.name}
  7.         </c:if>
  8.     </c:forEach>
  9. </c:forEach>
复制代码
3.2 类型cid->类型名   修改数据时  外键信息对应

修改动漫数据,跳修改页面后显示数据,类型可以选择并且,选择了以前的类型selected="selected"
  1. <select name="cid" id="categories">
  2.     <c:forEach items="${categoriesList}" var ="category" varStatus="status">
  3.         <option value="${category.id }"
  4.             <c:if test="${ upAnimes.cid eq category.id}" var="flag">
  5.                     selected="selected"
  6.             </c:if>
  7.         >${category.name }</option>
  8.     </c:forEach>
  9. </select>
复制代码
3.2.response 返回弹窗,并跳转

直接在返回中写javaScript;
  1. resp.getWriter().print("");
复制代码
3.3 getPartment(str) 再次理解

如果属性,没有参数就是空字符串“”  ,如果没有属性,获取的就是null
  1. getPartment(str); //如果属性,没有参数就是空字符串“”  ,如果没有属性,获取的就是null
  2. getPartment(str).trim(); //防止不小心多输入空格,去掉前后的空格,但是 trim()必须保证参数值不为 null
复制代码
3.4 模糊 sql拼接

like concat(''%,?,'%') 方便模糊查询
sql拼接及 Object数组 数组动态添加参数的弊端(后面使用List集合添加数组,最后在转成数组)
  1. //注意这种参数判断的思想
  2. //条件查询动漫
  3. public List<Animes> searchAnimes(Search search) throws SQLException{
  4.     List<Animes> animesList = new ArrayList<>();
  5.     String executeSql = "select `id`,`cid`,`name`,`author`,`actor`,`produce`,`create_date` from animes";
  6.     //参数
  7.     Object[] params = {};
  8.     //如果有参数
  9.     if(!"".equals(String.valueOf(search.getAnimeName())) || !"".equals(String.valueOf(search.getAnimeAuthor())) || !"0".equals(String.valueOf(search.getAnimeCategory()))) {
  10.         executeSql = executeSql.concat(" where");
  11.     }
  12.     //如果有动漫名
  13.     if(!"".equals(String.valueOf(search.getAnimeName()))) {
  14.         executeSql = executeSql.concat(" name like concat('%',?,'%')");
  15.         Object[] params1 = {search.getAnimeName()};
  16.         params = params1;
  17.     }
  18.     //如果有动漫名 和作者
  19.     if(!"".equals(String.valueOf(search.getAnimeName())) && !"".equals(String.valueOf(search.getAnimeAuthor()))) {
  20.         executeSql = executeSql.concat(" and author like concat('%',?,'%')");
  21.         Object[] params2 = {search.getAnimeName(),search.getAnimeAuthor()};
  22.         params = params2;
  23.     }else if(!"".equals(String.valueOf(search.getAnimeAuthor()))){
  24.         //如果 作者
  25.         executeSql = executeSql.concat(" author like concat('%',?,'%')");
  26.         Object[] params3 = {search.getAnimeAuthor()};
  27.         params = params3;
  28.     }
  29.     //如果有 作者名 和 动漫名 和 类型
  30.     if(!"".equals(String.valueOf(search.getAnimeName())) && !"".equals(String.valueOf(search.getAnimeAuthor())) && !"0".equals(String.valueOf(search.getAnimeCategory()))) {
  31.         executeSql = executeSql.concat(" and cid = ?");
  32.         Object[] params4 = {search.getAnimeName(),search.getAnimeAuthor(),search.getAnimeCategory()};
  33.         params = params4;
  34.     }else if(!"".equals(String.valueOf(search.getAnimeName())) && !"0".equals(String.valueOf(search.getAnimeCategory()))) {
  35.         //动漫名 和 类型
  36.         executeSql = executeSql.concat(" and cid = ?");
  37.         Object[] params5 = {search.getAnimeName(),search.getAnimeCategory()};
  38.         params = params5;
  39.     }else if(!"".equals(String.valueOf(search.getAnimeAuthor())) && !"0".equals(String.valueOf(search.getAnimeCategory()))) {
  40.         //作者 和 类型
  41.         executeSql = executeSql.concat(" and cid = ?");
  42.         Object[] params6 = {search.getAnimeAuthor(),search.getAnimeCategory()};
  43.         params = params6;
  44.     }else if(!"0".equals(String.valueOf(search.getAnimeCategory()))){
  45.         //类型
  46.         executeSql = executeSql.concat(" cid = ?");
  47.         Object[] params7 = {search.getAnimeCategory()};
  48.         params = params7;
  49.     }
  50.     System.out.println("searchAnimes 搜索的SQL==>"+executeSql);
  51.     ResultSet rs = JDBCUtil.select(executeSql, params);
  52.     while(rs.next()) {
  53.         Animes anime = new Animes();
  54.         anime.setId(rs.getInt("id"));
  55.         anime.setCid(rs.getInt("cid"));
  56.         anime.setName(rs.getString("name"));
  57.         anime.setAuthor(rs.getString("author"));
  58.         anime.setActor(rs.getString("actor"));
  59.         anime.setProduce(rs.getString("produce"));
  60.         anime.setCreate_date(rs.getDate("create_date"));
  61.         animesList.add(anime);
  62.     }
  63.     System.out.println("----- AnimesImpl  遍历数据库中查询的数据 ----");
  64.     for (int i = 0; i < animesList.size(); i++) {
  65.         System.out.println(animesList.get(i).toString());
  66.     }
  67.     System.out.println("----- AnimesImpl  遍历数据库中查询的数据结束 ---");
  68.     return animesList;
  69. }
复制代码
3.5  标记 搜索关键字

在数据查询的时候将关键字进行替换 replace(oldstr,new str);
  1. //标记关键字 name
  2. String markName = "replace(`name`,'"+search.getAnimeName() +"',""+search.getAnimeName()+"") as 'name'";
  3. //标记关键字 author
  4. String markAuthor = "replace(`author`,'"+search.getAnimeAuthor() +"',""+search.getAnimeAuthor()+"") as 'author'";
  5. //执行的sql
  6. String executeSql = "select `id`,`cid`,"+markName+","+markAuthor+",`actor`,`produce`,`create_date` from animes";
复制代码
3.6 分页查询
  1. //分页查询所有的动漫数据
  2. public List<Animes> pageSelectAllAnimes(PageUtil pageUtil) throws SQLException{
  3.     List<Animes> animesList = new ArrayList<>();
  4.     String executeSql = "select `id`,`cid`,`name`,`author`,`actor`,`produce`,`create_date` from animes limit ?,?";
  5.     //参数
  6.     Object[] params = {(pageUtil.getPageNum()-1)*pageUtil.getPageSize(),pageUtil.getPageSize()};
  7.     ResultSet rs = JDBCUtil.select(executeSql, params);
  8.     while(rs.next()) {
  9.         Animes anime = new Animes();
  10.         anime.setId(rs.getInt("id"));
  11.         anime.setCid(rs.getInt("cid"));
  12.         anime.setName(rs.getString("name"));
  13.         anime.setAuthor(rs.getString("author"));
  14.         anime.setActor(rs.getString("actor"));
  15.         anime.setProduce(rs.getString("produce"));
  16.         anime.setCreate_date(rs.getDate("create_date"));
  17.         animesList.add(anime);
  18.     }
  19.     System.out.println("----- AnimesImpl 打印测试  当前页=》"+pageUtil.getPageNum()+",页面大小=》"+pageUtil.getPageSize());
  20.     for (int i = 0; i < animesList.size(); i++) {
  21.         System.out.println(animesList.get(i).toString());
  22.     }
  23.     System.out.println("-----------------------------------");
  24.     return animesList;
  25. }
复制代码
3.7 分页工具类
  1. //分页工具类
  2. public class PageUtil {
  3.         //一共多少条数据
  4.         private int dateCount;
  5.         //每页显示的数据条数
  6.         private int pageSize = 5;
  7.         //当前页
  8.         private int pageNum = 1;
  9.         //最大页数
  10.         private int maxPageNum;
  11.        
  12.         //构造方法,需要  数据量 和 页面大小
  13.         public PageUtil(int dateCount) {
  14.                 this.dateCount = dateCount;
  15.                 this.maxPageNum = (this.dateCount%pageSize) == 0 ? (this.dateCount/pageSize) : (this.dateCount/pageSize) +1 ;
  16.         }
  17.         //获取当前页面
  18.         public int getPageNum() {
  19.                 return pageNum;
  20.         }
  21.        
  22.         //设置当前页面
  23.         public void setPageNum(int pageNum) {
  24.                 this.pageNum = pageNum;
  25.         }
  26.         //获取最大页面数
  27.         public int getMaxPageNum() {
  28.                 return this.maxPageNum;
  29.         }
  30.         //获取页面大小
  31.         public int getPageSize() {
  32.                 return pageSize;
  33.         }
  34.         //设置页面大小
  35.         public void setPageSize(int pageSize) {
  36.                 this.pageSize = pageSize;
  37.                 //页面大小切换后应该重新切换页面数量
  38.                 this.maxPageNum = (this.dateCount%pageSize) == 0 ? (this.dateCount/pageSize) : (this.dateCount/pageSize) +1 ;
  39.         }
  40.         //获取数据总条数
  41.         public int getDateCount() {
  42.                 return dateCount;
  43.         }
  44.        
  45. }
复制代码
3.8  获取select的值 change()事件动态获取pageSize  并拼接参数

select标签的change()事件, 切换选项时触发;
  1. [/code]跳转页面的链接 [b]首页,上一页,下一页,尾页[/b]
  2. [code]<a target="_blank" href="https://www.cnblogs.com/pageSearch?pageNum=1&pageSize=" >首页</a> | 
  3. <c:if test="${pageUtil.pageNum ne 1}" var="sexFlag">
  4.     <a target="_blank" href="https://www.cnblogs.com/pageSearch?pageNum=${pageUtil.pageNum -1 }&pageSize=" ><<上一页</a> | 
  5. </c:if>
  6. <c:if test="${pageUtil.pageNum ne pageUtil.maxPageNum}" var="sexFlag">
  7.     <a target="_blank" href="https://www.cnblogs.com/pageSearch?pageNum=${pageUtil.pageNum +1 }&pageSize=" >下一页>></a> | 
  8. </c:if>
  9. <a target="_blank" href="https://www.cnblogs.com/pageSearch?pageNum=${pageUtil.maxPageNum }&pageSize=" >尾页</a> | 
复制代码
3.9 动态显示pageSize
  1. <select name="pageSize" id="pageSize">
  2.    
  3.     <c:forEach items="${pageSizeList}" var ="pageSize" varStatus="status">
  4.         <option value="${pageSize.pageSize}"
  5.                 <c:if test="${pageUtil.pageSize eq pageSize.pageSize}">
  6.         selected = "selected"
  7.         </c:if>
  8.     >${pageSize.pageSize}</option>
  9. </c:forEach>
  10. </select>
复制代码
3.10 登录 AnimeServlet 第一次跳转到展示页面 需要准备一些数据
  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3.     //======从数据库获取动漫数据  不走条件查询======
  4.     List<Animes> animesList = new ArrayList<>();
  5.     AnimesImpl animesImpl = new AnimesImpl();
  6.     //                try {
  7.     //                        animesList = animesImpl.selectAllAnimes();
  8.     //                } catch (SQLException e) {
  9.     //                        e.printStackTrace();
  10.     //                }
  11.     //======从数据库获取动漫数据  走条件查询======
  12.     //获取动漫的总条数
  13.     int dateCount = 0;
  14.     try {
  15.         dateCount = animesImpl.selectAllAnimesCounts();
  16.     } catch (SQLException e) {
  17.         e.printStackTrace();
  18.     }
  19.     PageUtil pageUtil = new PageUtil(dateCount);
  20.     //将分页对象放进session域中,初始化页面对象
  21.     req.getSession().setAttribute("pageUtil", pageUtil);
  22.     try {
  23.         animesList = animesImpl.pageSelectAllAnimes(pageUtil);
  24.     } catch (SQLException e) {
  25.         e.printStackTrace();
  26.     }
  27.     //将动漫集合放入request中
  28.     req.setAttribute("animesList", animesList);
  29.     //======动漫类型======
  30.     List<Category> categoriesList = new ArrayList<>();
  31.     CategoryImpl categoryImpl = new CategoryImpl();
  32.     try {
  33.         categoriesList = categoryImpl.selectAllCategories();
  34.     } catch (SQLException e) {
  35.         e.printStackTrace();
  36.     }
  37.     //将类型数据放进session中
  38.     req.getSession().setAttribute("categoriesList", categoriesList);
  39.     //页面大小
  40.     List<PageSize> pageSizeList = new ArrayList<PageSize>();
  41.     pageSizeList.add(new PageSize("3"));
  42.     pageSizeList.add(new PageSize("5"));
  43.     pageSizeList.add(new PageSize("10"));
  44.     pageSizeList.add(new PageSize("15"));
  45.     //将pageSize放进session中
  46.     req.getSession().setAttribute("pageSizeList", pageSizeList);
  47.     System.out.println("==AnimeServlet 动漫数据条数"+dateCount+"当前页"+pageUtil.getPageNum()+"最大页"+pageUtil.getMaxPageNum()+"===");
  48.     //转发到动漫列表页面
  49.     req.getRequestDispatcher("web6Jdbc/animeListJson.jsp").forward(req, resp);
  50. }
复制代码
3.11 分页Servlet->PageSelectAnimeServlet
  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3.     //第几页
  4.     int pageNum = Integer.parseInt(req.getParameter("pageNum")==null ? "1" :req.getParameter("pageNum"));
  5.     //页面大小
  6.     int pageSize = Integer.parseInt(req.getParameter("pageSize")==null ? "5" :req.getParameter("pageSize"));
  7.     System.out.println("PageSelectAnimeServlet 当前页=》"+pageNum+",页面大小=》"+pageSize);
  8.     AnimesImpl animesImpl = new AnimesImpl();
  9.     PageUtil pageUtil = null;
  10.     try {
  11.         //现在每次实例化都先获取数据总数,后面考虑更好的方法 ??小问题
  12.         pageUtil = new PageUtil(animesImpl.selectAllAnimesCounts());
  13.     } catch (SQLException e1) {
  14.         e1.printStackTrace();
  15.     }
  16.     pageUtil.setPageNum(pageNum);
  17.     pageUtil.setPageSize(pageSize);
  18.     //每次分页查询要将分页工具类重新更新
  19.     req.getSession().setAttribute("pageUtil", pageUtil);
  20.     List<Animes> animesList = new ArrayList<Animes>();
  21.     try {
  22.         animesList = animesImpl.pageSelectAllAnimes(pageUtil);
  23.         //将动漫集合放入request中
  24.         req.setAttribute("animesList", animesList);
  25.     } catch (SQLException e) {
  26.         e.printStackTrace();
  27.     }
  28.     //转发到动漫列表页面
  29.     req.getRequestDispatcher("web6Jdbc/animeListJson.jsp").forward(req, resp);
  30. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户云卷云舒

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表