阿里druid连接池,SpringJDBC模块,JDBC自定义工具类,JdbcTemplate

Posted 梦见明日

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿里druid连接池,SpringJDBC模块,JDBC自定义工具类,JdbcTemplate相关的知识,希望对你有一定的参考价值。


(本文代码实现共需导入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表见下图:

点击原文链接,可下载本文用到的所有jar包

以上是关于阿里druid连接池,SpringJDBC模块,JDBC自定义工具类,JdbcTemplate的主要内容,如果未能解决你的问题,请参考以下文章

有人熟悉阿里的 druid 的连接池么

为啥修改阿里druid连接池监控登录密码后登陆不成功

数据库连接池

阿里druid连接池有没有自动关闭事务提交的功能

常见的数据库连接池

阿里巴巴连接池Druid简单使用