table of Contents
JDBC
JDBC: the Java Database Connectivity. All the official rules of the relational database defined set of operations, namely the interface. Each database vendor to achieve this interface, providing database driver jar package. We can use this set of interfaces (JDBC) programming, the code execution is the real driver jar package implementation class.
Getting the JDBC
- Setup the development environment
Introducing mysql-connector-java-5.1.7-bin.jar lib directory of the packet to the next item, and Add As Library
- Programming, database-driven driver is loaded in the program
Class.forName("com.mysql.jdbc.Driver");
- establish connection
Connection conn=DriverManager.getConnection ("jdbc:mysql://localhost:3306/jdbctest","root","123456");
- And create custom SQL Statement object for sending SQL to the database
String sql="select * from user";
Statement stmt = conn.createStatement();
- SQL execution
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);
}
- Disconnect from the database, and frees resources
resultSet.close();
stmt.close();
conn.close();
Code:
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 objects Detailed
DriverManager: Driver Management
effect:
① registration drive
The presence of a static class code block com.mysql.jdbc.Driver
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
Write code: Class.forName("com.mysql.jdbc.Driver");
Register loading drivers
② database connection
method:static Connection getConnection(String url, String user, String password)
- url: Specifies the path connection ( "jdbc: mysql: // ip address (domain name): port number / name database coding?")
- 例:(“jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf-8”)
- user username
- password password
Connection: connection object
effect:
① create objects to execute SQL statements
- Statement createStatement () to execute SQL statements with SQL injection vulnerability exists
- PreparedStatement preparedStatement (String sql) precompiled SQL statements, SQL injection vulnerability to solve
- CallableStatement preparedCall (String sql) Execute SQL stored procedure
② transaction management
- setAutoCommit (boolean autoCommit) call this method to set the parameter to false, open affairs
- Open transactions before executing sql
- commit () to commit the transaction
- When all are executing the sql commit the transaction
- rollback () rolls back the transaction
- Roll back the transaction in the catch
Statement: Execute SQL
effect:
① execute SQL statements
- boolean execute (String sql) returns a Boolean value
- ResultSet executeQuery (String sql) for the implementation of the select statement that returns a result set
- The number of rows int executeUpdate (String sql) used to perform insert, update, delete statement that returns an int value indicating the effect of
② batch operations
- addBatch added to the batch
- executeBatch batch execution
- clearBatch empty batch
ResultSet: result set
effect:
Package select statement query results, next () method to the next line, getObject () to obtain data.
JDBC-extraction tools
After maintenance updates JDBC To simplify development of a number of repeated extraction code, and adds the profile ( "xxx.properties"), to facilitate
Code:
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 injection vulnerabilities
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;
}
}
We want to execute a SQL statement is select * from user where username = '" + username + "' and password = '" + password + "'
when we enter a user name as the username aaa' or '1=1
, the password can log regardless of success
Reason: When we enter a user name and SQL statement string concatenation, as the content of the input is also part of the SQL statement, the generated SQL statementselect * from user where username = ' aaa' or ' 1=1 ' and password = 'dsacqwed1'
存在关键字or
select * from user where username = ' aaa' 执行
' 1=1 ' and password = 'dsacqwed1' 假
Solve the SQL injection vulnerabilities
Methods: Using the PreparedStatement Interface
Statement each object will first execute a SQL statement SQL statement sent to the database, SQL database to compile, and execute again. Inefficient, and may cause overflow database cache.
PreparedStatement will be sent to the database first pre-compiled SQL statement, PreparedStatement references the result of pre-compiled, you can be repeatedly passed different parameters and perform to the PreparedStatement object.
- Reduce the number of SQL pre-compiler, improve efficiency
- Enhance readability
- No security issues SQL injection vulnerabilities
Injection vulnerability to solve the problem:
When writing SQL statements, parameter? Placeholder
"select * from user where username = ? and password = ?";
Recycling PreparedStatement object setXxx (placeholders (starting from 1), the actual value) method of setting parameters
/**
* 避免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 operation of 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);
}
}
}
Database connection pool technology
Database connection pool: database connection pool is responsible for the distribution, management and release of database connections, which allows an application to reuse an existing database connection, rather than re-create a; the equivalent of a container, storage container database connection. When a good system initialization, the container is created, the container will apply for some of the connection object when the user to access the database to get a connection object from the container, after the user access to finished, the connection object will be returned to the container.
c3p0 technology
Implementation steps:
Introducing a respective jar package
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.12.jar
PS: Do not forget to import the mysql-connector-java-5.1.7-bin driver package
Custom profile
File name can only be: c3p0.properties or c3p0-config.xml
3. Create a database connection pool object
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 defined tools 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 technology
Implementation steps
Introducing jar package druid-1.0.9.jar
Custom profile xxx.properties
Load Profile
Database connection pool object
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Get connected
Connection conn=dataSource.getConnection();
Defined Druid tools JDBCUtils3.java (providing static code block loading configuration files, initialize the connection pool object)
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;
}
}
}
Profile 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