dao工厂和预防sql注入

Java基础

浏览数:106

2019-8-23

AD:资源代下载服务

1、配置文件 dao.properties

UserDao=cn.itcast.dao.impl.UserDaoJdbcImpl

2、DaoFactory(工厂一般要做成单例的,这样工厂的对象在内存里只有一个。目的是希望所有dao由一个dao来生产)

package cn.itcast.factory;

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

public class DaoFactory {
    private Properties prop = new Properties();

    private DaoFactory() {
        InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");
        try {
            prop.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static DaoFactory instance = new DaoFactory();

    public static DaoFactory getInstance() {
        return instance;
    }

    /*如果将来产生多个dao,就不能写死(泛型)
     *比如当调用createDao方法时,会传一个,UserDao的接口,
     * 然后根据名称解读配置文件dao.properties加载UserDao的实现类,new出对象返回
     */
    public <T> T createDao(Class<T> clazz) {

        String name = clazz.getSimpleName();//得到接口名称
        String className = prop.getProperty(name);
        try {
           T dao = (T) Class.forName(className).newInstance();
           return dao;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

3、自定义dao异常,dao层在写的时候,如果出问题了,抛出RunTimeException异常不太好,一般来说我们会自定义一个异常,好处就是到时候出问题看异常的类名就可以快速定位。

package cn.itcast.exception;

//运行时异常(抛出异常时希望上层处理就是编译时异常)
public class DaoException extends RuntimeException {
    public DaoException() {
        super();
    }

    public DaoException(String message) {
        super(message);
    }

    public DaoException(String message, Throwable cause) {
        super(message, cause);
    }

    public DaoException(Throwable cause) {
        super(cause);
    }
}

4、自定义异常后,在UserDaoImpl里就要将异常RunTimeException转为DaoException

package cn.itcast.dao.impl;

import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

//2
public class UserDaoJdbcImpl implements UserDao {
    public void add(User user) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "insert into users(id,username,password,email,birthday,nickname) values('" + user.getId() + "','" + user.getUsername() + "','" + user.getPassword() + "','" + user.getEmail() + "','" + user.getBirthday().toLocaleString() + "','" + user.getNickname() + "')";
            int num = st.executeUpdate(sql);
            if (num < 1) {
                throw new RuntimeException("注册用户失败");
            }
        } catch (Exception e) {
            throw new DaoException(e);//gosling  thinking in java  spring
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }

    public User find(String username, String password) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "select * from users where username='" + username + "' and password ='" + password + "'";
            rs = st.executeQuery(sql);
            if (rs.next()) {
                User user = new User();
                user.setId(rs.getString("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setEmail(rs.getString("email"));
                user.setBirthday(rs.getDate("birthday"));
                user.setNickname(rs.getString("nickname"));
                return user;
            }
            return null;
        } catch (Exception e) {
            throw new DaoException(e);
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }

    //查找注册的用户是否在数据库中存在
    public boolean find(String username) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "select * from users where username='" + username + "'";
            rs = st.executeQuery(sql);
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception e) {
            throw new DaoException(e);
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }
}

5、防范sql注入攻击UserDaoJdbcImpl(代码注释很全)

package cn.itcast.dao.impl;

import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;

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

//2
public class UserDaoJdbcImpl implements UserDao {
    public void add(User user) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into users(id,username,password,email,birthday,nickname) values(?,?,?,?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1,user.getId());
            ps.setString(2,user.getUsername());
            ps.setString(3,user.getPassword());
            ps.setString(4,user.getEmail());
            ps.setDate(5,new java.sql.Date(user.getBirthday().getTime()));
            ps.setString(6,user.getNickname());

            int num = ps.executeUpdate();
            if (num < 1) {
                throw new RuntimeException("注册用户失败");
            }
        } catch (Exception e) {
            throw new DaoException(e);//gosling  thinking in java  spring
        } finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }

    /*
     * Statement和PreparedStatement的区别
     * PreparedStatement是Statement的孩子
     * PreparedStatement可以防止sql注入的问题
     * PreparedStatement会对sql语句进行预编译,减轻服务器的压力
     */
    public User find(String username, String password) {

        Connection conn = null;
        PreparedStatement ps = null;//PreparedStatement预防sql注入
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select * from users where username=? and password =?";
            ps = conn.prepareStatement(sql);//预编译这条sql语句
            ps.setString(1,username);//数据库会对登录时拿到的内容进行转义
            ps.setString(2,password);

            rs = ps.executeQuery();
            if (rs.next()) {
                User user = new User();
                user.setId(rs.getString("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setEmail(rs.getString("email"));
                user.setBirthday(rs.getDate("birthday"));
                user.setNickname(rs.getString("nickname"));
                return user;
            }
            return null;
        } catch (Exception e) {
            throw new DaoException(e);
        } finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }

    //查找注册的用户是否在数据库中存在
    public boolean find(String username) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select * from users where username=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,username);
            rs = ps.executeQuery();
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception e) {
            throw new DaoException(e);
        } finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }
}

源代码:https://github.com/yvettee36/Jdbc_User

作者:小小蒜头