阿里druid连接池,Spring框架简单JDBC模块,JDBC自定义工具类,preparedStatement,JdbcTemplate以及其对象一系列sql语句执行方法

本文介绍了为何PreparedStatement替代Statement以解决SQL注入问题,并展示了基础的JDBC操作,接着引入了Druid连接池和Spring的JdbcTemplate,提供了使用这些工具的代码示例,强调了它们在提升效率和安全性方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(本文代码实现共需导入mysqlJDBC jar包,阿里巴巴druid jar包,Spring框架jar包,junit-4.12.jar包,hamcrest-core-1.3.jar包文末可下载(待审核后))

首先说下Statement被它的儿子Preparedstatement取代的原因:

            即sql注入问题,如:

Statement所需的sql语句:

            例:

String sql = "select * from user where username = '"+username+"' and password = '"+password+"' ";

             问题存在:因St的sql语句中要传的参数是使用字符串拼接而成,若上式是登录操作,用户可以不论数据库中的数据,通过在password中构造恒等式例如: 142018728 or 1 = 1 来使得整个sql语句变为恒等式,或者直接在username结尾添加 -- 或# 来达到注释后面所有语句来实现只要 username 在数据库中存在即可登录;

 

Preparesdstatement则很好的解决了这个问题,不但运行效率提升,最重要的是解决了sql注入问题 如下例:
           

            //2.定义sql
            String sql = "select * from user where username = ? and password = ?";
            //3.获取执行sql的对象
            pstmt = conn.prepareStatement(sql);
            //给?赋值
            pstmt.setString(1,username);
            pstmt.setString(2,password);
            //4.执行查询,不需要传递sql
            rs = pstmt.executeQuery();

所有statement存在的问题全部被它儿子preparestatement解决了;


此为最最最基础的JDBC,没写工具类且没使用连接池的代码实现:

import java.sql.*;

/**
 * account表 添加一条记录 insert 语句
 */
public class JDBCDemo2 {
    public static void main(String[] args) {
        PreparedStatement stmt = null;
        Connection conn = null;
        try {
            //1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2. 定义sql
            String sql = "insert into account values(?,?,?)";
            //String sql = "insert into account values(null,'王五',3000)";
            //3.获取Connection对象
            //若连接本地数据库,下式中localhost:3306 可以省略,除非你把地球人都知道的数据库端口号3306改了;db3换为你本地一个数据库名
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
            //4.获取执行sql的对象 prepareStatement
            stmt = conn.prepareStatement(sql);
            stmt.setString(1,null);
            stmt.setString(2,"王五");
            stmt.setInt(3,3000);
            //5.执行sql
            int count = stmt.executeUpdate();//影响的行数
            //6.处理结果
            System.out.println(count);
            if(count > 0){
                System.out.println("添加成功!");
            }else{
                System.out.println("添加失败!");
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //stmt.close();
            //7. 释放资源
            //避免空指针异常
            if(stmt != null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

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

 

JDBC工具类实现(使用阿里的druid连接池以及Spring框架后):



import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * Druid连接池的工具类
 */
public class JDBCUtils {

    //1.定义成员变量 DataSource
    private static DataSource ds ;

    static{
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            //2.获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 释放资源
     */
    public static void close(Statement stmt,Connection conn){
       /* if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();//归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }*/

       close(null,stmt,conn);
    }


    public static void close(ResultSet rs , Statement stmt, Connection conn){


        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();//归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取连接池方法
     */

    public static DataSource getDataSource(){
        return  ds;
    }

}

使用导入所有所需jar包并使用工具类后可写出各个测试类

import domain.Emp;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class bg {
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    @Test//此测试用于查询语句(无返回条数数量限制)
    public void test5() {
        String sql = "select * from emp";
        List<Map<String, Object>> list = template.queryForList(sql);

        for (Map<String, Object> stringObjectMap : list) {
            System.out.println(stringObjectMap);
        }
    }


    @Test//此测试用于查询语句(无返回条数数量限制),重要,此测试语法开发中最常用
    public void ui() {
        String sql = "select * from emp";
        List<Emp> query = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
        for (Emp emp : query) {
            System.out.println(emp);
        }

    }

    @Test//此测试用于查询语句(无返回条数数量限制)
    public void hj() {
        String sql = "select * from emp";
        List<Map<String, Object>> list = template.queryForList(sql);
        for (Map<String, Object> stringObjectMap : list) {
            System.out.println(stringObjectMap);
        }
    }
    @Test//此方法只能获取一条记录,用于查询语句
    public void op(){
        String sql = "Select * from emp where id = 1005";
        Map<String, Object> map = template.queryForMap(sql);
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            System.out.println(entry);
        }
    }
    @Test//同上
    public void io(){
        String sql = "Select count(id) from emp";
        Long a = template.queryForObject(sql, long.class);
        System.out.println(a);
    }
    @Test//此测试用于添加表数据
    public void hk(){
        String sql = "insert into emp(id,ename,job_id,dept_id)value(?,?,?,?);";
        int update = template.update(sql, 1045, "斯派克", 4, 10);
        System.out.println(update);
    }
    @Test//此测试用于删除表数据
    public void ty(){
        String sql = "delete from emp where id = ?";
        int update = template.update(sql, 1045);
        System.out.println(update);
    }
}

上述代码中emp表见下图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值