我着重強調幾點:
1、默認Statement和PreparedStatement,每次只能執行一條sql,對應mysql可以通過增加url參數&allowMultiQueries=true解決。
2、mysql的註釋,可以用#、"-- ",多行註釋/* */。若使用"-- ",注意後面要有一個空格
3、mysql的驅動已經修改爲com.mysql.cj.jdbc.Driver,英文意思是之前的已過期,新驅動會自動通過DriverManage類自動裝載,不需要人工操作。
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
自動裝載驅動是在java.sql.DriverManager.loadInitialDrivers(),DriverManage的static代碼塊中,會檢測jar包中的META-INF/services/java.sql.Driver路徑,就是不需要我們寫Class.forName()。
4、着重強調sql注入的危害性,drop表,查詢全表數據等,一定要使用PreparedStatement,或mybatis的#{},其他情況一定要校驗字符串中是否包含特色字符,譬如;、' 、 -- 、#等。要理解這些符號的使用場景
5、今天還驗證了like ?也可以通過PreparedStatement預編譯設置參數
代碼:
測試主類App.java
package com.nding.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nding.common.DBUtil;
/**
* Hello world!
*
*/
public class App
{
private static Logger logger = LoggerFactory.getLogger(App.class);
public static void main( String[] args )
{
System.out.println( "Hello World!" );
testLikeSql();
}
public static void testLikeSql() {
// 默認jdbc.url不能執行兩條sql,需要拼接參數allowMultiQueries=true
String name = "%\';delete from student where id=4 or \'\'= \' ";
name = "%\';-- \' ";
Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
conn = DBUtil.getConnection();
// 模擬sql注入
String sql ="SELECT * FROM `student` where name like \'" + name + "%\';";
System.out.println("sql: " + sql);
try {
psmt = conn.prepareStatement(sql);
// psmt.setString(1, "k%");
rs = psmt.executeQuery();
System.out.println("id" + " " + "name"
+ " " + "deptNo");
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name")
+ " " + rs.getInt("deptNo"));
}
} catch (SQLException e) {
logger.error("execute sql fail, sql: " + sql, e);
} finally {
DBUtil.closeResource(rs, psmt, conn);
DBUtil.close();
}
}
}
數據庫工具類DBUtil.java
package com.nding.common;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.util.IOUtils;
public class DBUtil {
private static Logger logger = LoggerFactory.getLogger(DBUtil.class);
private static Properties dbProps = new Properties();
private static ThreadLocal<Connection> local = new ThreadLocal<Connection>();
static {
String className = null;
try (InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");){
dbProps.load(is);
className = dbProps.getProperty("driver");
Class.forName(className);
} catch (ClassNotFoundException e) {
logger.error("sql driver class: {} not found", className);
} catch (IOException e1) {
logger.error("load jdbc.properties fail", e1);
}
}
public static Connection getConnection() {
Connection conn = local.get();
if (conn == null) {
try {
conn = DriverManager.getConnection(dbProps.getProperty("url"), dbProps.getProperty("username"),
dbProps.getProperty("password"));
} catch (SQLException e) {
logger.error("getConnection fail, db config: " + JSON.toJSONString(dbProps), e);
}
local.set(conn);
}
return conn;
}
public static void close() {
Connection conn = local.get();
if (conn != null) {
local.remove();
conn = null;
}
}
public static void closeResource(ResultSet rs, Statement stmt, Connection conn) {
closeAutoCloseableResource(rs);
closeAutoCloseableResource(stmt);
closeAutoCloseableResource(conn);
}
private static void closeAutoCloseableResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
// ignore
}
}
}
}
配置文件jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowMultiQueries=true
username=root
password=123456
maven項目的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nding</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version> <!-- 6.0.6 -->
</dependency>
</dependencies>
<build>
<finalName>test</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.txt</include>
</includes>
</resource>
</resources>
</build>
</project>