(三)JDBC学习笔记——抽取JDBC工具类、解决SQL注入、事务管理

一、抽取JDBC工具类

在上一章中,在dao层的StudentDaoImpl.java文件中,查询全部数据、根据id查询数据、增删改数据等方法对于数据库的连接和释放存在大量的重复代码,因此可以将其中的部分代码抽出来,写到一个工具类中,需要连接释放数据库时直接调用这个工具类即可。

1.创建配置文件

首先在项目根目录下创建config.properties配置文件。配置文件中存放连接数据库所需要的信息。
在这里插入图片描述
要使用里面的配置信息,使用java类加载器得到文件字节流,然后使用Properties类加载流对象信息,使用getXXX()即可拿到配置信息。

2.创建JDBCUtils工具类

在项目目录中新建一个utils的目录,专门存放各类工具类,新建JDBCUtils工具类。创建静态代码块,实现加载配置文件、注册驱动等功能。静态代码块在类创建时只执行一次,在静态代码块里将config.properties里的数据读取并赋值给静态变量,然后通过静态方法进行数据库连接和释放。

public class JDBCUtils {
    //1.私有构造方法
    private JDBCUtils(){}
    //2.声明所需配置变量
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;

    private static Connection con;
    //3.提供静态代码块。功能:读取配置文件,注册驱动。
    static {
        try {
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");
            Properties prop = new Properties();
            prop.load(is);
            driverClass = prop.getProperty("driverClass");
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            password = prop.getProperty("password");

            //注册驱动,可不写
            Class.forName(driverClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //4.提供获取数据库连接的方法
    public static Connection getConnection(){
        try {
            con = DriverManager.getConnection(url, username, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return con;
    }
    //5.提供释放资源的方法
    //用于增删改
    public static void close(Connection con, Statement stat, ResultSet rs){
        if(con != null){
            try {
                con.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    //用于查
    public static void close(Connection con, Statement stat){
        if(con != null){
            try {
                con.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(stat != null) {
            try {
                stat.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

这样,原有dao层的连接、释放数据库功能便被抽象出来:

Connection connection = JDBCUtils.getConnection();
JDBCUtils.close(connection, statement, resultSet);

二、解决SQL注入

JDBC里的PreparedStatement可以解决SQL注入的问题。首先在执行SQL语句之前,预编译SQL语句,此时明确了SQL语句的格式,剩下的都将被当做参数。参数使用"?"作为占位符。

  • 为参数赋值的方法:setXxx(参数1,参数2);
    • 参数1:?的位置编号(编号从1开始)
    • 参数2:?的实际参数
  • 执行sql语句的方法
    • 执行insert、update、delete语句:int executeUpdate();
    • 执行select语句:ResultSet executeQuery();
PreparedStatement pstm = null;
ResultSet rs = null;
String sql = "SELECT * FROM user WHERE loginname=? AND password=?";
        pstm = conn.prepareStatement(sql);
        //3.设置参数
        pstm.setString(1,loginName);
        pstm.setString(2,password);
        System.out.println(sql);
        //4.执行sql语句,获取结果集
        rs = pstm.executeQuery();

三、事务管理

在service层进行数据库连接,开启事务及事务的提交和回滚,将connection对象传入dao层进行数据IO。

public void batchAdd(List<User> users) {
    //获取数据库连接
    Connection connection = JDBCUtils.getConnection();
    try {
        //开启事务
        connection.setAutoCommit(false);
        for (User user : users) {
            //1.创建ID,并把UUID中的-替换
            String uid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
            //2.给user的uid赋值
            user.setUid(uid);
            //3.生成员工编号
            user.setUcode(uid);

            //模拟异常
            //int n = 1 / 0;

            //4.保存
            userDao.save(connection,user);
        }
        //提交事务
        connection.commit();
    }catch (Exception e){
        try {
            //回滚事务
            connection.rollback();
        }catch (Exception ex){
            ex.printStackTrace();
        }
        e.printStackTrace();
    }finally {
        JDBCUtils.close(connection,null,null);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值