关于JDBC小总结
Posted jascen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于JDBC小总结相关的知识,希望对你有一定的参考价值。
目录
JDBC
JDBC:Java数据库连接。官方定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
JDBC的入门
- 搭建开发环境
? 导入mysql-connector-java-5.1.7-bin.jar包到该项目的lib目录下,并Add As Library
- 编写程序,在程序中加载驱动数据库驱动
Class.forName("com.mysql.jdbc.Driver");
- 建立连接
Connection conn=DriverManager.getConnection ("jdbc:mysql://localhost:3306/jdbctest","root","123456");
- 定义SQL并创建用于向数据库发送SQL的Statement对象
String sql="select * from user";
Statement stmt = conn.createStatement();
- 执行SQL
ResultSet resultSet = stmt.executeQuery(sql);
while(resultSet.next())
int uid = resultSet.getInt("uid");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String name = resultSet.getString("name");
System.out.println(uid+" "+username+" "+password+" "+name);
- 断开与数据库的连接,并释放相关资源
resultSet.close();
stmt.close();
conn.close();
代码实现:
JDBCDemo1.java
import org.junit.Test;
import java.sql.*;
public class JDBCDemo1
@Test
public void demo1()
try
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获得连接
Connection conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123456");
//定义SQL并创建用于向数据库发送SQL的Statement对象
String sql = "select * from user";
Statement stmt = conn.createStatement();
//执行SQL
ResultSet resultSet = stmt.executeQuery(sql);
//遍历查询到的结果
while (resultSet.next())
int uid = resultSet.getInt("uid");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String name = resultSet.getString("name");
System.out.println(uid + " " + username + " " + password + " " + name);
//释放资源
resultSet.close();
stmt.close();
conn.close();
catch (Exception e)
e.printStackTrace();
JDBC对象详解
DriverManager:驱动管理类
作用:
①注册驱动
? 在com.mysql.jdbc.Driver类中存在静态代码块
static
try
java.sql.DriverManager.registerDriver(new Driver());
catch (SQLException E)
throw new RuntimeException("Can't register driver!");
编写代码: Class.forName("com.mysql.jdbc.Driver");
注册加载驱动
②获取数据库连接
方法:static Connection getConnection(String url, String user, String password)
- url:指定连接的路径 (“jdbc:mysql://ip地址(域名):端口号/数据库名称?编码方式”)
- 例:(“jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf-8”)
- user 用户名
- password 密码
Connection:连接对象
作用:
①创建执行SQL语句的对象
- Statement createStatement() 执行SQL语句,有SQL的注入漏洞存在
- PreparedStatement preparedStatement(String sql) 预编译SQL语句,解决SQL的注入漏洞
- CallableStatement preparedCall(String sql) 执行SQL中的存储过程
②进行事务管理
- setAutoCommit(boolean autoCommit) 调用该方法设置参数为false,即开启事务
- 在执行sql之前开启事务
- commit() 提交事务
- 当所有sql都执行完提交事务
- rollback() 回滚事务
- 在catch中回滚事务
Statement:执行SQL
作用:
①执行SQL语句
- boolean execute(String sql) 返回一个布尔值
- ResultSet executeQuery(String sql) 用于执行select语句,返回一个结果集
- int executeUpdate(String sql) 用于执行insert、update、delete语句,返回一个int值,表示影响的行数
②执行批处理操作
- addBatch 添加到批处理
- executeBatch 执行批处理
- clearBatch 清空批处理
ResultSet:结果集
作用:
select语句查询结果的封装,next()方法指向下一行,getObject()获取数据。
JDBC的工具类的抽取
为了简化JDBC的开发,对一些重复代码进行提取,并且添加配置文件("xxx.properties"),便于之后的维护更新
代码实现:
jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbctest?characterEncoding=utf-8
username=root
password=123456
JDBCUtils.java
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils
private static final String driverClass;
private static final String url;
private static final String username;
private static final String passsword;
//配置文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
static
//创建Properties集合类
Properties properties = new Properties();
//使用字节码文件获取当前类的类加载器以获取资源输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
try
//加载配置文件
properties.load(is);
catch (IOException e)
e.printStackTrace();
//获取配置文件中的数据
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
username = properties.getProperty("username");
passsword = properties.getProperty("password");
//注册加载驱动
public static void loadDriver() throws ClassNotFoundException
Class.forName(driverClass);
//获取数据库连接
public static Connection getConnection() throws Exception
loadDriver();
Connection conn = DriverManager.getConnection(url, username, passsword);
return conn;
//断开数据库连接,资源释放
public static void release(Connection conn, Statement stmt)
if (conn != null)
try
conn.close();
catch (SQLException e)
e.printStackTrace();
conn = null;
if (stmt != null)
try
stmt.close();
catch (SQLException e)
e.printStackTrace();
stmt = null;
//断开数据库连接,资源释放
public static void release(Connection conn, Statement stmt, ResultSet rs)
if (conn != null)
try
conn.close();
catch (SQLException e)
e.printStackTrace();
conn = null;
if (stmt != null)
try
stmt.close();
catch (SQLException e)
e.printStackTrace();
stmt = null;
if (rs != null)
try
rs.close();
catch (SQLException e)
e.printStackTrace();
rs = null;
JDBC的SQL注入漏洞
JDBCDemo2.java
import Utils.JDBCUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCDemo2
@Test
/**
* 测试SQL注入漏洞的方法
*/
public void demo1()
boolean flag = JDBCDemo2.login("aaa' or '1=1", "dsacqwed1");
if (flag == true)
System.out.println("登录成功!");
else
System.out.println("登录失败!");
public static boolean login(String username, String password)
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
boolean flag = false;
try
conn = JDBCUtils.getConnection();
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
// 执行SQL:
rs = stmt.executeQuery(sql);
// 判断结果集中是否有数据。
if (rs.next())
flag = true;
else
flag = false;
catch (Exception e)
e.printStackTrace();
finally
JDBCUtils.release(conn, stmt, rs);
return flag;
我们要执行的SQL语句为select * from user where username = ‘" + username + "‘ and password = ‘" + password + "‘
当我们输入用户名username为aaa‘ or ‘1=1
时,无论密码输入什么都能登录成功
产生原因:当我们输入用户名与SQL语句进行字符串拼接,输入的内容也作为了SQL语句的一部分,生成的SQL语句为select * from user where username = ‘ aaa‘ or ‘ 1=1 ‘ and password = ‘dsacqwed1‘
存在关键字or
select * from user where username = ' aaa' 执行
' 1=1 ' and password = 'dsacqwed1' 假
解决SQL注入漏洞问题
方法:使用PreparedStatement接口
Statement对象每执行一条SQL语句都会先将SQL语句发送给数据库,数据库先编译SQL,再执行。效率低,且可能造成数据库缓存区的溢出。
PreparedStatement会先将SQL语句发送给数据库预编译,PreparedStatement会引用着预编译后的结果,可以多次传入不同的参数来给PreparedStatement对象并执行。
- 减少SQL预编译次数,提高效率
- 提升了程序的可读性
- 没有了SQL注入漏洞的安全问题
解决注入漏洞问题:
编写SQL语句时,参数使用?占位
"select * from user where username = ? and password = ?";
再利用PreparedStatement对象的setXxx(占位符位置(从1开始),实际值)方法设置参数
/**
* 避免SQL注入漏洞的方法
*/
public static boolean login(String username,String password)
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
boolean flag = false;
try
conn = JDBCUtils.getConnection();
String sql = "select * from user where username = ? and password = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
rs = pstmt.executeQuery();
if(rs.next())
flag = true;
else
flag = false;
catch(Exception e)
e.printStackTrace();
finally
JDBCUtils.release(conn, pstmt, rs);
return flag;
JDBC的CURD操作
JDBCDemo3.java
import Utils.JDBCUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCDemo3
@Test
public void select()
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
conn = JDBCUtils.getConnection();
String sql = "select * from user where username=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "aaa");
rs = pstmt.executeQuery();
while (rs.next())
System.out.println(rs.getString("uid") + " " + rs.getString("username") + " " + rs.getString("password") + " " + rs.getString("name"));
catch (Exception e)
e.printStackTrace();
finally
JDBCUtils.release(conn, pstmt, rs);
@Test
public void delete()
Connection conn = null;
PreparedStatement pstmt = null;
try
conn = JDBCUtils.getConnection();
String sql = "delete from user where username=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "xxx");
int i = pstmt.executeUpdate();
if (i > 0)
System.out.println("删除成功!");
catch (Exception e)
e.printStackTrace();
finally
JDBCUtils.release(conn, pstmt);
@Test
public void update()
Connection conn = null;
PreparedStatement pstmt = null;
try
conn = JDBCUtils.getConnection();
String sql = "update user set username=? where name=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "aaa");
pstmt.setString(2, "Marry");
int i = pstmt.executeUpdate();
if (i > 0)
System.out.println("更改成功!");
catch (Exception e)
e.printStackTrace();
finally
JDBCUtils.release(conn, pstmt);
@Test
public void insert()
Connection conn = null;
PreparedStatement pstmt = null;
try
conn = JDBCUtils.getConnection();
String sql = "insert into user values(null,?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "xxx");
pstmt.setString(2, "666");
pstmt.setString(3, "小八");
int i = pstmt.executeUpdate();
if (i > 0)
System.out.println("添加成功!");
catch (Exception e)
e.printStackTrace();
finally
JDBCUtils.release(conn, pstmt);
数据库连接池技术
数据库连接池:数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;相当于一个容器,存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
c3p0技术
实现步骤:
导入相应jar包
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.12.jar
PS:不要忘记导入mysql-connector-java-5.1.7-bin 驱动包
定义配置文件
? 文件名只能为: c3p0.properties或者 c3p0-config.xml
3.创建数据库连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
?
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///jdbctest?characterEncoding=utf-8</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
定义c3p0工具类 JDBCUtils2.java
package Utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils2
//创建数据库连接池对象
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
//获取连接对象
public static Connection getConnection() throws SQLException
Connection conn = dataSource.getConnection();
return conn;
public static void release(Connection conn, Statement stmt)
if (conn != null)
try
conn.close();
catch (SQLException e)
e.printStackTrace();
conn = null;
if (stmt != null)
try
stmt.close();
catch (SQLException e)
e.printStackTrace();
stmt = null;
public static void release(Connection conn, Statement stmt, ResultSet rs)
if (conn != null)
try
conn.close();
catch (SQLException e)
e.printStackTrace();
conn = null;
if (stmt != null)
try
stmt.close();
catch (SQLException e)
e.printStackTrace();
stmt = null;
if (rs != null)
try
rs.close();
catch (SQLException e)
e.printStackTrace();
rs = null;
JDBCDemo4.java
package JDBCDemo;
import Utils.JDBCUtils2;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCDemo7
@Test
public void demo1()
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
conn = JDBCUtils2.getConnection();
String sql = "select * from user where uid=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 1);
rs = pstmt.executeQuery();
while (rs.next())
System.out.println(rs.getInt("uid") + " " + rs.getString("username"));
catch (SQLException e)
e.printStackTrace();
finally
JDBCUtils2.release(conn, pstmt, rs);
Druid技术
实现步骤
导入jar包 druid-1.0.9.jar
定义配置文件xxx.properties
加载配置文件
获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
获取连接
?
Connection conn=dataSource.getConnection();
定义Druid工具类 JDBCUtils3.java (提供静态代码块加载配置文件,初始化连接池对象)
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtils3
private static DataSource dataSource;
static
Properties properties = new Properties();
InputStream is = JDBCUtils3.class.getClassLoader().getResourceAsStream("druid.properties");
try
properties.load(is);
dataSource = DruidDataSourceFactory.createDataSource(properties);
catch (Exception e)
e.printStackTrace();
public static Connection getConnection() throws SQLException
Connection conn = dataSource.getConnection();
return conn;
public static void release(Connection conn, PreparedStatement pstmt)
if (conn != null)
try
conn.close();
catch (SQLException e)
e.printStackTrace();
conn = null;
if (pstmt != null)
try
pstmt.close();
catch (SQLException e)
e.printStackTrace();
pstmt = null;
public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs)
if (conn != null)
try
conn.close();
catch (SQLException e)
e.printStackTrace();
conn = null;
if (pstmt != null)
try
pstmt.close();
catch (SQLException e)
e.printStackTrace();
pstmt = null;
if (rs != null)
try
rs.close();
catch (SQLException e)
e.printStackTrace();
rs = null;
配置文件druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf-8
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
以上是关于关于JDBC小总结的主要内容,如果未能解决你的问题,请参考以下文章