JDBC整理

数据库配置文件

创建 db.properties 资源文件,存放配置信息

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/javaweb?useSSL=true&useUnicode=true&characterEncoding=utf-8
username=root
password=123456

操作数据库公共类

建立 dao 包,然后创建 BaseDao

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class BaseDao {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    //静态代码块,类加载的时候初始化
    static {
        Properties properties = new Properties();
        //通过类加载器读取对应的资源
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
    }
    //获取数据库的连接
    public static Connection getConnection(){
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url,username,password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    //编写预编译查询公共方法
    public static ResultSet execute(Connection con, PreparedStatement pre, ResultSet rs, String sql, Object[] params) throws SQLException {
       rs=null;
       if(con!=null){
           pre = con.prepareStatement(sql);
           for (int i = 0; i < params.length; i++) {
               pre.setObject(i+1,params[i]);
           }
           rs = pre.executeQuery();
       }
       return rs;
    }

    //编写预编译增删改公共方法
    public static int execute(Connection con, PreparedStatement pre, String sql, Object[] params) throws SQLException {
        int updateRows = 0;
        if(con!=null){
            pre = con.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                pre.setObject(i+1,params[i]);
            }
            updateRows = pre.executeUpdate();
        }
        return updateRows;
    }

    //释放资源
    public static boolean closeResource(Connection con, PreparedStatement pre, ResultSet rs){
        boolean flag = true;
        if(con!=null){
            try{
                con.close();
                con = null; //GC回收
            }catch (SQLException e){
                e.printStackTrace();
                flag = false;
            }
        }
        if(pre!=null){
            try {
                pre.close();
                pre = null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag = false;
            }
        }
        if(rs!=null){
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag = false;
            }
        }
        return flag;
    }
}

字符编码过滤器

建立 filter 包,然后在包下建立CharacterEncodingFilter

import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() {}
}

在 web.xml 下注册编码过滤器,路径根据自己需要更改



    CharacterEncodingFilter
    com.qiu.filter.CharacterEncodingFilter


    CharacterEncodingFilter
    /*

建立实体对象

建立 pojo 包,然后根据数据库建立对应的实体类

以user表为例,建立 User 类,根据数据库字段建立对应私有属性,然后建立 get/set 方法,创建有参/无参构造方法

数据库操作实体类

建立 user 包,然后建立 UserDao 接口,面向接口编程

public interface UserDao {
    //得到要登录的用户信息
    public User getLoginUser(Connection con, String username, String password) throws SQLException;

    //修改当前用户密码
    public int updatePwd(Connection con, String username, String password)throws SQLException;
}

编写接口实现类 UserDaoImpl

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDaoImpl implements UserDao {
    //得到要登录的用户
    public User getLoginUser(Connection con, String username, String password) throws SQLException {
        PreparedStatement pre = null;
        ResultSet rs = null;
        User user = null;
        if(con!=null){
            String sql = "select * from user where username=? and password=?";
            Object[] params = {username,password};
            rs = BaseDao.execute(con, pre, rs, sql, params);
            if(rs.next()){
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
            }
            BaseDao.closeResource(null,pre,rs);
        }
        return user;
    }

    //修改当前用户密码
    public int updatePwd(Connection con, String username, String password) throws SQLException {
        PreparedStatement pre = null;
        int updateRows = 0;
        if(con!=null){
            String sql = "update user set password = ? where username = ?";
            Object[] params = {password,username};
            updateRows = BaseDao.execute(con, pre, sql, params);
            BaseDao.closeResource(null, pre, null);
        }
        return updateRows;
    }
}

业务层接口及实现类

建立 service 包,并在 service 包下建立 user

然后编写 UserService 接口

public interface UserService {
    //得到登录信息
    public User login(String username, String password);

    //根据用户ID 修改密码
    public boolean updatePwd(String username, String password);
}

编写接口实现类UserServiceImpl

public class UserServiceImpl implements UserService {
    //业务层都会调用dao层,所以我们要引入dao层
    private UserDao userDao;
    public UserServiceImpl(){
        userDao = new UserDaoImpl();
    }

    @Override
    public User login(String username, String password) {
        Connection con = null;
        User user = null;
        con = BaseDao.getConnection();
        //通过业务层调用对应的具体的数据库操作
        try {
            user = userDao.getLoginUser(con,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            BaseDao.closeResource(con,null,null);
        }
        return user;
    }

    @Override
    public boolean updatePwd(String username, String password){
        Connection con = null;
        boolean flag = false;
        //根据用户ID 修改密码
        try{
            con = BaseDao.getConnection();
            if(userDao.updatePwd(con, username, password)>0){
                flag=true;
            }
        }catch (SQLException e){
            e.printStackTrace();
            try {
                con.rollback();//数据库回滚操作
            } catch (SQLException ex) { ex.printStackTrace(); }
        }finally {
            BaseDao.closeResource(con,null,null);
        }
        return flag;
    }
}

控制层实现类

建立 servlet 包,然后建立 user

在user包下建立 LoginServlet 类来处理登录请求

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //和数据库中的账号密码进行对比,调用业务层
        UserService userService = new UserServiceImpl();
        User user = userService.login(username, password);

        if(user!=null){
            //将用户信息放到Session中
            req.getSession().setAttribute(Constants.USER_SESSION,user);
            //跳转到主页
            resp.sendRedirect(req.getContextPath()+"/main/success.jsp");
        }else{
            //转发回登录页面,顺带提示它,用户名或者密码错误
            req.setAttribute(Constants.MESSAGE,"用户名或者密码错误");
            req.getRequestDispatcher("/login/login.jsp").forward(req,resp);
        }
    }

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

注册 LoginServlet



    login
    com.qiu.servlet.user.LoginServlet


    login
    /login.do

在user包下建立 UserServlet 类来处理修改密码请求

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //从Session里面拿到username
        Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
        String newpassword = req.getParameter("newpassword");
        boolean flag = true;
        if(obj!=null && !StringUtils.isNullOrEmpty(newpassword)){
            UserService userService = new UserServiceImpl();
            flag = userService.updatePwd(((User)obj).getUsername(),newpassword);
            if(flag){
                req.setAttribute(Constants.MESSAGE,"密码修改成功,请退出重新登录");
                req.getSession().removeAttribute(Constants.USER_SESSION);
            }else{
                req.setAttribute(Constants.MESSAGE,"密码修改失败");
            }
        }else{
            req.setAttribute(Constants.MESSAGE,"新密码存在问题");
        }
        req.getRequestDispatcher("/main/updatePwd.jsp").forward(req,resp);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

注册 UserServlet



    UserServlet
    com.qiu.servlet.user.UserServlet


    UserServlet
    /main/user.do


编写常用工具类

建立 util 包,然后建立常用变量工具类 Constants

以后的常量放在工具类下

public class Constants {
    public final static String USER_SESSION = "userSession";
    public final static String MESSAGE = "message";
}

编写注销功能

思想:移除Session,然后重定向到登录页面

在servlet包中的user包内建立LogoutServlet类

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除用户的Constants.USER_SESSION
        req.getSession().removeAttribute(Constants.USER_SESSION);
        resp.sendRedirect(req.getContextPath()+"/login/login.jsp");//返回登录页面
    }

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

注册Servlet



    logout
    com.qiu.servlet.user.LogoutServlet


    logout
    /logout.do

在jsp下面应用logout.do,以a标签为例

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

">退出

登录拦截优化

思想:请求页面时,判断是否存在Session

在 filter 包下建立登录过滤器 SysFilter

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        //过滤器,从Session中获取用户
        User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
        if(user==null){ //已被移除或者注销了,或者未登录
            response.sendRedirect(request.getContextPath()+"/login/login.jsp");
        }else {
            chain.doFilter(req, resp);
        }
    }

    @Override
    public void destroy() {}
}

注册过滤器



    SysFilter
    com.qiu.filter.SysFilter


    SysFilter
    /main/*

UserServlet优化细节

  • 验证密码使用ajax及时动态优化
  • 实现Servlet复用
  • 使用前引入fastjson依赖
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

//实现Servlet复用
public class UserServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if(method!=null && method.equals("savepwd")){
            this.updataPwd(req,resp);
        }else if(method!=null && method.equals("pwdmodify")){
            this.pwdModify(req,resp);
        }
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    //修改密码
    public void updataPwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //从Session里面拿到username
        Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
        String newpassword = req.getParameter("newpassword");
        boolean flag;
        if(obj!=null && !StringUtils.isNullOrEmpty(newpassword)){
            UserService userService = new UserServiceImpl();
            flag = userService.updatePwd(((User)obj).getUsername(),newpassword);
            if(flag){
                req.setAttribute(Constants.MESSAGE,"密码修改成功,请退出重新登录");
                req.getSession().removeAttribute(Constants.USER_SESSION);
            }else{
                req.setAttribute(Constants.MESSAGE,"密码修改失败");
            }
        }else{
            req.setAttribute(Constants.MESSAGE,"新密码存在问题");
        }
        req.getRequestDispatcher("/main/updatePwd.jsp").forward(req,resp);
    }

    //验证旧密码,session中有用户的密码
    public void pwdModify(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
        String oldpassword = req.getParameter("oldpassword");

        //万能的Map:结果集
        Map resultMap = new HashMap();
        if(obj==null){//session失效过期了
            resultMap.put("result","sessionError");
        }else if(StringUtils.isNullOrEmpty(oldpassword)){   //输入的密码为空
            resultMap.put("result","error");
        }else{
            String userPassword = ((User)obj).getPassword();
            if(oldpassword.equals(userPassword)){
                resultMap.put("result","true");
            }else{
                resultMap.put("result","false");
            }
        }
        resp.setContentType("application/json");
        PrintWriter writer = resp.getWriter();
        //JSONArray 阿里巴巴的JSON工具类,转换格式
        writer.write(JSONArray.toJSONString(resultMap));
        writer.flush();
        writer.checkError();
    }
}

updatePwd.jsp 文件,根据环境做不同的修改

<%@ page contentType="text/html;charset=UTF-8" %>


    
    修改密码
    
    
    


修改密码
提交
${message}

补充内容

  • 设置欢迎页和 Session 过期时间


    /login/login.jsp



    30

  • fastjson 依赖


    com.alibaba
    fastjson
    1.2.62

  • 分包情况:pojo 包、 dao 包、 user包、 service 包、 servlet 包、 filter 包、 util

你可能感兴趣的:(JDBC整理)