百木园-与人分享,
就是让自己快乐。

Javaweb06-JDBC

1、jdbc.properties配置文件

jdbc.properties

driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/animedb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8
user=root
password=root

2、JDBCUtil 工具类

JDBCUtil.java

package com.kgc.jdbc;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

/**
 * JDBC数据库操作工具类-都是公共的静态方法(不需要实例化),减少代码冗余
 * @author zhukang
 *
 */
public class JDBCUtil {
	
	/**
	 * 读取外部的数据库连接信息配置文件,获取数据库连接对象
	 */
	public static Connection getConnection() throws Exception {
		
		// 创建Properties属性对象
		Properties properties = new Properties();
		
		// 使用反射机制,读取外部配置文件
		InputStream inputStream = JDBCUtil.class.getClassLoader().getResourceAsStream(\"jdbc.properties\");
		
		// 加载输入流对象,获取配置文件内容
		properties.load(inputStream);
		
		// 读取数据库连接信息
		String driverClass = properties.getProperty(\"driverClass\");
		String jdbcUrl = properties.getProperty(\"jdbcUrl\");
		String user = properties.getProperty(\"user\");
		String password = properties.getProperty(\"password\");
		
		// 加载驱动
		Class.forName(driverClass);
		
		// 获取数据库连接对象
		return DriverManager.getConnection(jdbcUrl, user, password);
	}
	
	/**
	 * 增删改的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
	 */
	public static int update(String executeSql, Object ... params){
		
		// 定义数据库连接和预处理操作对象
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		// 定义SQL语句执行的影响行数
		int row = 0;
		
		// 公共执行增删改的处理代码
		try {
			// 获取数据库连接
			conn = getConnection();
			
			// 创建预处理操作对象
			pstmt = conn.prepareStatement(executeSql);
			
			// 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}
			
			// 执行增删改操作,并获取影响行数
			row = pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			releaseResource(conn, pstmt, null);
		}
		
		// 返回影响行数
		return row;
		
	}
	
	/**
	 * 查询的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
	 */
	public static ResultSet select(String executeSql, Object ... params){
		
		// 定义数据库连接,预处理操作对象,结果集对象
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// 公共执行查询的处理代码
		try {
			// 获取数据库连接
			conn = getConnection();
			
			// 创建预处理操作对象
			pstmt = conn.prepareStatement(executeSql);
			
			// 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}
			
			// 执行查询操作,并获取结果集
			rs = pstmt.executeQuery();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			//最好不释放资源,因为rs要返回,关闭后,直接外层不可以使用
			releaseResource(conn, pstmt, rs);
		}
		
		// 返回查询结果集
		return rs;
		
	}
	
	/**
	 * 释放数据库操作对象资源
	 */
	public static void releaseResource(Connection conn, Statement stmt, ResultSet rs){
		try {
			// 手动释放
			if (null != rs) {
				rs.close();
			}
			
			if (null != stmt) {
				stmt.close();
			}

			if (null != conn) {
				conn.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

3、作业总结技巧 (JdbcUtil 页面跳转 Jstl)

这些只是我个人的思考,可能会比较冗余,我是为了多思考,记录当时的感受;

且以访问资源为主和jstl,后面的以Ajax为主;

3.1Jstl妙用 (基于 Jstl遍历数据添加元素)

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

animesList:为动漫list集合的数据,放在request域中;
categoriesList:为动漫的类型,放在session域中(主要是因为方便修改和添加的时候方便获取类型);
外层循环,遍历每条动漫数据,内层循环,查询动漫对应的类型名称;

<!--  
animesList:为动漫list集合的数据,放在request域中;
categoriesList:为动漫的类型,放在session域中(主要是因为方便修改和添加的时候方便获取类型)
外层循环,遍历每条动漫数据,内层循环,查询动漫对应的类型名称
-->
<c:forEach items=\"${animesList}\" var =\"anime\" varStatus=\"status\">
    <!-- 遍历动漫的cid -->
    <c:forEach items=\"${categoriesList}\" var =\"category\" varStatus=\"status\">
        <!-- 根据动漫的cid 与  类型的id 匹配对应的动漫类型 -->
        <c:if test=\"${ anime.cid eq category.id}\" var=\"flag\">
            ${category.name}
        </c:if>
    </c:forEach>
</c:forEach>

3.2 类型cid->类型名 修改数据时 外键信息对应

修改动漫数据,跳修改页面后显示数据,类型可以选择并且,选择了以前的类型selected=\"selected\"

<!-- 修改动漫数据,跳修改页面后显示数据,类型可以选择并且,选择了以前的类型selected=\"selected\" -->
<select name=\"cid\" id=\"categories\">
<!-- 动漫类型 将数据放进session中然后直接通过Jstl表达式遍历 -->
    <c:forEach items=\"${categoriesList}\" var =\"category\" varStatus=\"status\">
        <option value=\"${category.id }\" 
            <c:if test=\"${ upAnimes.cid eq category.id}\" var=\"flag\">
            	selected=\"selected\"
            </c:if>
        >${category.name }</option>
    </c:forEach>
</select>

3.2.response 返回弹窗,并跳转

直接在返回中写javaScript;

resp.getWriter().print(\"<script type=\'text/javascript\'>alert(\'删除成功!!!\'); location.href = \'animes\'</script>\");

3.3 getPartment(str) 再次理解

如果属性,没有参数就是空字符串“” ,如果没有属性,获取的就是null

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

3.4 模糊 sql拼接

like concat(\'\'%,?,\'%\') 方便模糊查询

sql拼接及 Object数组 数组动态添加参数的弊端(后面使用List集合添加数组,最后在转成数组)

//注意这种参数判断的思想
//条件查询动漫
public List<Animes> searchAnimes(Search search) throws SQLException{
    List<Animes> animesList = new ArrayList<>();

    String executeSql = \"select `id`,`cid`,`name`,`author`,`actor`,`produce`,`create_date` from animes\";
    //参数
    Object[] params = {};

    //如果有参数
    if(!\"\".equals(String.valueOf(search.getAnimeName())) || !\"\".equals(String.valueOf(search.getAnimeAuthor())) || !\"0\".equals(String.valueOf(search.getAnimeCategory()))) {
        executeSql = executeSql.concat(\" where\");
    }

    //如果有动漫名
    if(!\"\".equals(String.valueOf(search.getAnimeName()))) {
        executeSql = executeSql.concat(\" name like concat(\'%\',?,\'%\')\");
        Object[] params1 = {search.getAnimeName()};
        params = params1;
    }

    //如果有动漫名 和作者
    if(!\"\".equals(String.valueOf(search.getAnimeName())) && !\"\".equals(String.valueOf(search.getAnimeAuthor()))) {
        executeSql = executeSql.concat(\" and author like concat(\'%\',?,\'%\')\");
        Object[] params2 = {search.getAnimeName(),search.getAnimeAuthor()};
        params = params2;
    }else if(!\"\".equals(String.valueOf(search.getAnimeAuthor()))){
        //如果 作者
        executeSql = executeSql.concat(\" author like concat(\'%\',?,\'%\')\");
        Object[] params3 = {search.getAnimeAuthor()};
        params = params3;
    }

    //如果有 作者名 和 动漫名 和 类型
    if(!\"\".equals(String.valueOf(search.getAnimeName())) && !\"\".equals(String.valueOf(search.getAnimeAuthor())) && !\"0\".equals(String.valueOf(search.getAnimeCategory()))) {
        executeSql = executeSql.concat(\" and cid = ?\");
        Object[] params4 = {search.getAnimeName(),search.getAnimeAuthor(),search.getAnimeCategory()};
        params = params4;
    }else if(!\"\".equals(String.valueOf(search.getAnimeName())) && !\"0\".equals(String.valueOf(search.getAnimeCategory()))) {
        //动漫名 和 类型
        executeSql = executeSql.concat(\" and cid = ?\");
        Object[] params5 = {search.getAnimeName(),search.getAnimeCategory()};
        params = params5;
    }else if(!\"\".equals(String.valueOf(search.getAnimeAuthor())) && !\"0\".equals(String.valueOf(search.getAnimeCategory()))) {
        //作者 和 类型
        executeSql = executeSql.concat(\" and cid = ?\");
        Object[] params6 = {search.getAnimeAuthor(),search.getAnimeCategory()};
        params = params6;
    }else if(!\"0\".equals(String.valueOf(search.getAnimeCategory()))){
        //类型
        executeSql = executeSql.concat(\" cid = ?\");
        Object[] params7 = {search.getAnimeCategory()};
        params = params7;
    }

    System.out.println(\"searchAnimes 搜索的SQL==>\"+executeSql);

    ResultSet rs = JDBCUtil.select(executeSql, params);

    while(rs.next()) {
        Animes anime = new Animes();
        anime.setId(rs.getInt(\"id\"));
        anime.setCid(rs.getInt(\"cid\"));
        anime.setName(rs.getString(\"name\"));
        anime.setAuthor(rs.getString(\"author\"));
        anime.setActor(rs.getString(\"actor\"));
        anime.setProduce(rs.getString(\"produce\"));
        anime.setCreate_date(rs.getDate(\"create_date\"));
        animesList.add(anime);
    }
    System.out.println(\"----- AnimesImpl  遍历数据库中查询的数据 ----\");
    for (int i = 0; i < animesList.size(); i++) {
        System.out.println(animesList.get(i).toString());
    }
    System.out.println(\"----- AnimesImpl  遍历数据库中查询的数据结束 ---\");

    return animesList;

}

3.5 标记 搜索关键字

在数据查询的时候将关键字进行替换 replace(oldstr,new str);

//标记关键字 name
String markName = \"replace(`name`,\'\"+search.getAnimeName() +\"\',\\\"<span style=\'color:red\'>\"+search.getAnimeName()+\"</span>\\\") as \'name\'\";
//标记关键字 author
String markAuthor = \"replace(`author`,\'\"+search.getAnimeAuthor() +\"\',\\\"<span style=\'color:red\'>\"+search.getAnimeAuthor()+\"</span>\\\") as \'author\'\";

//执行的sql
String executeSql = \"select `id`,`cid`,\"+markName+\",\"+markAuthor+\",`actor`,`produce`,`create_date` from animes\";

3.6 分页查询

//分页查询所有的动漫数据
public List<Animes> pageSelectAllAnimes(PageUtil pageUtil) throws SQLException{
    List<Animes> animesList = new ArrayList<>();

    String executeSql = \"select `id`,`cid`,`name`,`author`,`actor`,`produce`,`create_date` from animes limit ?,?\";

    //参数
    Object[] params = {(pageUtil.getPageNum()-1)*pageUtil.getPageSize(),pageUtil.getPageSize()};

    ResultSet rs = JDBCUtil.select(executeSql, params);

    while(rs.next()) {
        Animes anime = new Animes();
        anime.setId(rs.getInt(\"id\"));
        anime.setCid(rs.getInt(\"cid\"));
        anime.setName(rs.getString(\"name\"));
        anime.setAuthor(rs.getString(\"author\"));
        anime.setActor(rs.getString(\"actor\"));
        anime.setProduce(rs.getString(\"produce\"));
        anime.setCreate_date(rs.getDate(\"create_date\"));
        animesList.add(anime);
    }
    System.out.println(\"----- AnimesImpl 打印测试  当前页=》\"+pageUtil.getPageNum()+\",页面大小=》\"+pageUtil.getPageSize());
    for (int i = 0; i < animesList.size(); i++) {
        System.out.println(animesList.get(i).toString());
    }
    System.out.println(\"-----------------------------------\");

    return animesList;
}

3.7 分页工具类

//分页工具类
public class PageUtil {

	//一共多少条数据
	private int dateCount;
	//每页显示的数据条数
	private int pageSize = 5;
	//当前页
	private int pageNum = 1;
	//最大页数
	private int maxPageNum;
	
	//构造方法,需要  数据量 和 页面大小
	public PageUtil(int dateCount) {
		this.dateCount = dateCount;
		this.maxPageNum = (this.dateCount%pageSize) == 0 ? (this.dateCount/pageSize) : (this.dateCount/pageSize) +1 ;
	}

	//获取当前页面
	public int getPageNum() {
		return pageNum;
	}
	
	//设置当前页面
	public void setPageNum(int pageNum) {
		this.pageNum = pageNum;
	}


	//获取最大页面数
	public int getMaxPageNum() {
		return this.maxPageNum;
	}

	//获取页面大小
	public int getPageSize() {
		return pageSize;
	}

	//设置页面大小
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
		//页面大小切换后应该重新切换页面数量
		this.maxPageNum = (this.dateCount%pageSize) == 0 ? (this.dateCount/pageSize) : (this.dateCount/pageSize) +1 ;
	}

	//获取数据总条数
	public int getDateCount() {
		return dateCount;
	}
	
}

3.8 获取select的值 change()事件动态获取pageSize 并拼接参数

select标签的change()事件, 切换选项时触发;

<!-- href拼接pageSize -->
<script type=\"text/javascript\" src=\"${pageContext.request.contextPath}/js/jquery-3.4.1.min.js\" ></script>
<script type=\"text/javascript\">
    $(function(){
        //获取页面大小
        let pageSize =  $(\"#pageSize\").val();
		
        //加载页面先拼接页面
        $(\".pagea\").each(function(){
            let oldhref = $(this).attr(\"href\").substr(0,30);
            let newhref = oldhref + pageSize;
            //alert(newhref); 
            $(this).attr(\"href\",newhref);
        });

        //修改pageSize
        //select标签的change()事件, 切换选项时触发
        $(\"#pageSize\").change(function(){
            pageSize =  $(\"#pageSize option:selected\").val();
            //alert(pageSize);
            //修改后的pageSize
            $(\".pagea\").each(function(){
                let oldhref = $(this).attr(\"href\").substr(0,30);
                let newhref = oldhref + pageSize;
                //alert(newhref); 
                $(this).attr(\"href\",newhref);
            });

            //根据新的pageSize跳转
            //alert(pageSize);
            //跳转的新页面
            //alert(\"pageSearch?pageNum=1&amp&pageSize=\"+pageSize);
            location.href = \"pageSearch?pageNum=1&amp&pageSize=\"+pageSize;
        });

    });

</script>

跳转页面的链接 首页,上一页,下一页,尾页

<!-- pageNum 当前页 -->
<a href=\"pageSearch?pageNum=1&pageSize=\" class=\"pagea\">首页</a>&nbsp;|&nbsp;
<c:if test=\"${pageUtil.pageNum ne 1}\" var=\"sexFlag\">
    <a href=\"pageSearch?pageNum=${pageUtil.pageNum -1 }&pageSize=\" class=\"pagea\">&lt;&lt;上一页</a>&nbsp;|&nbsp;
</c:if>
<c:if test=\"${pageUtil.pageNum ne pageUtil.maxPageNum}\" var=\"sexFlag\">
    <a href=\"pageSearch?pageNum=${pageUtil.pageNum +1 }&pageSize=\" class=\"pagea\">下一页&gt;&gt;</a>&nbsp;|&nbsp;
</c:if>
<a href=\"pageSearch?pageNum=${pageUtil.maxPageNum }&pageSize=\" class=\"pagea\">尾页</a>&nbsp;|&nbsp;

3.9 动态显示pageSize

<!-- 动态显示pageSize  
pageSizeList 为 PageSize 对象集合 PageSize 对象只有一个 String pageSize 页面大小属性
-->
<select name=\"pageSize\" id=\"pageSize\">
    <!--页面大小 pageSize -->
    <c:forEach items=\"${pageSizeList}\" var =\"pageSize\" varStatus=\"status\">
        <option value=\"${pageSize.pageSize}\" 
                <c:if test=\"${pageUtil.pageSize eq pageSize.pageSize}\">
        selected = \"selected\"
        </c:if>
    >${pageSize.pageSize}</option>
</c:forEach>
</select>

3.10 登录 AnimeServlet 第一次跳转到展示页面 需要准备一些数据

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //======从数据库获取动漫数据  不走条件查询======
    List<Animes> animesList = new ArrayList<>();
    AnimesImpl animesImpl = new AnimesImpl();
    //		try {
    //			animesList = animesImpl.selectAllAnimes();
    //		} catch (SQLException e) {
    //			e.printStackTrace();
    //		}


    //======从数据库获取动漫数据  走条件查询======
    //获取动漫的总条数
    int dateCount = 0;
    try {
        dateCount = animesImpl.selectAllAnimesCounts();
    } catch (SQLException e) {
        e.printStackTrace();
    }

    PageUtil pageUtil = new PageUtil(dateCount);
    //将分页对象放进session域中,初始化页面对象
    req.getSession().setAttribute(\"pageUtil\", pageUtil);
    try {
        animesList = animesImpl.pageSelectAllAnimes(pageUtil);
    } catch (SQLException e) {
        e.printStackTrace();
    }


    //将动漫集合放入request中
    req.setAttribute(\"animesList\", animesList);

    //======动漫类型======
    List<Category> categoriesList = new ArrayList<>();
    CategoryImpl categoryImpl = new CategoryImpl();

    try {
        categoriesList = categoryImpl.selectAllCategories();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    //将类型数据放进session中
    req.getSession().setAttribute(\"categoriesList\", categoriesList);

    //页面大小
    List<PageSize> pageSizeList = new ArrayList<PageSize>();
    pageSizeList.add(new PageSize(\"3\"));
    pageSizeList.add(new PageSize(\"5\"));
    pageSizeList.add(new PageSize(\"10\"));
    pageSizeList.add(new PageSize(\"15\"));
    //将pageSize放进session中
    req.getSession().setAttribute(\"pageSizeList\", pageSizeList);

    System.out.println(\"==AnimeServlet 动漫数据条数\"+dateCount+\"当前页\"+pageUtil.getPageNum()+\"最大页\"+pageUtil.getMaxPageNum()+\"===\");

    //转发到动漫列表页面
    req.getRequestDispatcher(\"web6Jdbc/animeListJson.jsp\").forward(req, resp);

}

3.11 分页Servlet->PageSelectAnimeServlet

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //第几页
    int pageNum = Integer.parseInt(req.getParameter(\"pageNum\")==null ? \"1\" :req.getParameter(\"pageNum\"));
    //页面大小
    int pageSize = Integer.parseInt(req.getParameter(\"pageSize\")==null ? \"5\" :req.getParameter(\"pageSize\"));

    System.out.println(\"PageSelectAnimeServlet 当前页=》\"+pageNum+\",页面大小=》\"+pageSize);


    AnimesImpl animesImpl = new AnimesImpl();
    PageUtil pageUtil = null;
    try {
        //现在每次实例化都先获取数据总数,后面考虑更好的方法 ??小问题
        pageUtil = new PageUtil(animesImpl.selectAllAnimesCounts());
    } catch (SQLException e1) {
        e1.printStackTrace();
    }
    pageUtil.setPageNum(pageNum);
    pageUtil.setPageSize(pageSize);

    //每次分页查询要将分页工具类重新更新
    req.getSession().setAttribute(\"pageUtil\", pageUtil);

    List<Animes> animesList = new ArrayList<Animes>();
    try {
        animesList = animesImpl.pageSelectAllAnimes(pageUtil);
        //将动漫集合放入request中
        req.setAttribute(\"animesList\", animesList);
    } catch (SQLException e) {
        e.printStackTrace();
    }

    //转发到动漫列表页面
    req.getRequestDispatcher(\"web6Jdbc/animeListJson.jsp\").forward(req, resp);

}

来源:https://www.cnblogs.com/xiaoqigui/p/16564935.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Javaweb06-JDBC

相关推荐

  • 暂无文章