教程:使用PreparedStatement訪問DLA
大家都知道PreparedStatement相比手動拼寫SQL有很多好處,比如:
- 它會自動做敏感字元的轉義,防止SQL Injection攻擊。
- 它可以幫助我們動態執行SQL,Prepare一次之後,後續執行只需要替換引數就可以了。
- 它可以幫助以OOP的方式來寫SQL相關相關程式碼,因為我們是通過 PrepareSteatement.setXxx()的方式而不是字串拼接的方式來設定引數。
等等,PreparedStatement的好處還有很多,更多可以參考這篇《JDBC Statement vs PreparedStatement – SQL Injection Example》, 上面說的很詳細。
今天我們Data Lake Analytics也引入了對PreparedStatement的支援, 今天給大家演示一下,如何用 PreparedStatement 來訪問 DLA.
準備工作
為了準備演示的環境,大家可能要先熟悉一下怎麼在DLA上面建立資料庫,建立表,在雲棲社群上面通過關鍵字 DLA
可以搜尋到很多文章,比如建立訪問RDS的DLA庫可以看這篇文章: 教程:使用Data Lake Analytics讀/寫RDS資料 .
我們在這篇教程裡面要演示的表的結構是這樣的:
CREATE EXTERNAL TABLE `type_test` (
`id` bigint(20) NULL DEFAULT NULL COMMENT ``,
`tinyint_col` tinyint(4) NULL DEFAULT NULL COMMENT ``,
`int_col` int(11) NULL DEFAULT NULL COMMENT ``,
`char_col` char(10) NULL DEFAULT `NULL` COMMENT ``,
`varchar_col` varchar(10) NULL DEFAULT `NULL` COMMENT ``,
`float_col` double NULL DEFAULT NULL COMMENT ``,
`double_col` double NULL DEFAULT NULL COMMENT ``,
`decimal_col` decimal(20, 4) NULL DEFAULT NULL COMMENT ``,
`time_col` time(3) NULL DEFAULT `NULL` COMMENT ``,
`datetime_col` datetime(6) NULL DEFAULT NULL COMMENT ``,
`timestamp_col` timestamp(6) NOT NULL COMMENT ``,
`string_col` varchar(100) NULL DEFAULT `NULL` COMMENT ``,
`date_col` date NULL DEFAULT `NULL` COMMENT ``,
`smallint_col` smallint(6) NULL DEFAULT NULL COMMENT ``,
`mediumint_col` int NULL DEFAULT NULL COMMENT ``,
`bigint_col` bigint(20) NULL DEFAULT NULL COMMENT ``
)
COMMENT ``
裡面的資料是這樣的:
> select * from type_testG;
*************************** 1. row ***************************
id: 1
tinyint_col: 2
int_col: 3
char_col: hello1
varchar_col: 5
float_col: 6.01
double_col: 7.02
decimal_col: 8.0300
time_col: 01:02:01.000
datetime_col: 1986-10-01 01:02:03.000000
timestamp_col: 2018-11-29 14:04:28.305523
string_col: hello
date_col: 2018-09-07
smallint_col: NULL
mediumint_col: NULL
bigint_col: 2
*************************** 2. row ***************************
id: 1111111
tinyint_col: 127
int_col: 4
char_col: hello2
varchar_col: 5555555555
float_col: 9996.01
double_col: 7777777.02
decimal_col: 888888888.0300
time_col: 01:02:02.000
datetime_col: 1986-10-01 01:02:03.000000
timestamp_col: 2018-11-29 14:36:05.486738
string_col: hello
date_col: 2018-09-08
smallint_col: NULL
mediumint_col: NULL
bigint_col: 1111112
*************************** 3. row ***************************
id: 3
tinyint_col: 127
int_col: 5
char_col: hello3
varchar_col: 5555555555
float_col: 9997.01
double_col: 7777777.02
decimal_col: 888888888.0300
time_col: 01:02:03.000
datetime_col: 1986-10-01 01:02:03.000000
timestamp_col: 2018-11-20 10:31:40.112000
string_col: hello
date_col: 2018-09-09
smallint_col: 3
mediumint_col: NULL
bigint_col: 4
3 rows in set (0.00 sec)
Java
因為我們相容MySQL協議,我們使用MySQL的JDBC驅動來訪問DLA。值得注意的是 MySQL JDBC驅動支援客戶端 PrepareStatement (也是很厲害啊), 要使用服務端的PreparedStatement的功能,需要在JDBC連線串的末尾加上 useServerPrepStmts=true
的引數,如下:
import java.sql.*;
public class DLAPrepStmtMain {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String sql = "select * from type_test where `key` = ?";
try (Connection dlaConn = DriverManager.getConnection(
"jdbc:mysql://1013022312866336-fake.cn-hangzhou.datalakeanalytics.aliyuncs.com:10000/yourdb?useServerPrepStmts=true",
"your-username",
"your-password");
PreparedStatement stmt = dlaConn.prepareStatement(sql)) {
stmt.setString(1, "key01");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
System.out.print(rs.getString(i + 1) + ", ");
}
System.out.println();
}
}
}
}
執行會發現,控制檯會正確列印出結果:
1, 2, 3, hello1, 5, 6.01, 7.02, 8.03, 01:02:01, 1986-10-01 01:02:03.0, 2018-11-29 14:04:28.305, hello, 2018-09-07, null, null, 2,
Php
PHP不愧是世界上最好的語言,寫起PreparedStatement起來也是非常的簡潔:
<?php
$mysqli = new mysqli("fakee.cn-hangzhou.datalakeanalytics.aliyuncs.com:10000",
"democ", "demo", "demo");
$stmt = $mysqli->stmt_init();
// 開始prepare
$stmt->prepare("select * from type_test where id = ?");
$id = 1;
// 繫結引數
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
var_dump($result->fetch_all());
?>
執行結果:
array(1) {
[0]=>
array(16) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
string(6) "hello1"
[4]=>
string(1) "5"
[5]=>
float(6.01)
[6]=>
float(7.02)
[7]=>
float(8.03)
[8]=>
string(8) "01:02:01"
[9]=>
string(19) "1986-10-01 01:02:03"
[10]=>
string(19) "2018-11-29 14:04:28"
[11]=>
string(5) "hello"
[12]=>
string(10) "2018-09-07"
[13]=>
NULL
[14]=>
NULL
[15]=>
int(2)
}
}
CSharp
C#不愧是比Java更好的語言,寫起來也是虎虎生風:
public static void Main()
{
string connStr = "server=your-endpoint.cn-hangzhou.datalakeanalytics.aliyuncs.com;UID=your-username;database=yourdb;port=10000;password=your-password;SslMode=none";
MySqlConnection conn = new MySqlConnection(connStr);
try
{
Console.WriteLine("Connecting to MySQL...");
conn.Open();
string sql = "select * from type_test where id = @var1";
MySqlCommand cmd = new MySqlCommand(sql, conn);
// 開始prepare
cmd.Prepare();
// 繫結引數
cmd.Parameters.AddWithValue("@var1", 1);
MySqlDataReader res = cmd.ExecuteReader();
while (res.Read())
{
for (int i = 0; i < res.FieldCount; i++)
{
Console.Write(res[i] + ",");
}
}
while (res.NextResult())
{
}
res.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
conn.Close();
Console.WriteLine("Done.");
}
}
結果如下:
Connecting to MySQL...
1,2,3,hello1,5,6.01,7.02,8.03,01:02:01,10/01/1986 01:02:03,11/29/2018 14:04:28,hello,09/07/2018 00:00:00,,,2,Done.
總結
隨著DLA對於各種語言PreparedStatement的支援,大家可以用PreparedStatement替換原先手動拼SQL的程式碼,讓你的程式碼更OOP,更安全!
相關文章
- JDBC教程之PreparedStatementJDBC
- 使用PreparedStatement實現CRUD操作
- JDBC使用PreparedStatement的好處JDBC
- java preparedStatementJava
- MySQL PreparedStatementMySql
- 使用PreparedStatement為佔位符?賦值賦值
- Gitlab怎麼使用訪問令牌訪問Gitlab
- 教程:如何通過DLA實現資料檔案格式轉換
- java-Statement、PreparedStatement、PreparedStatement + 批處理 的區別Java
- 使用預處理PreparedStatement執行Sql語句SQL
- 使用 session 訪問計數Session
- 使用nodejs 訪問mongodbNodeJSMongoDB
- 蘋果裝置訪問 Windows 檔案共享教程蘋果Windows
- Xamarin SQLite教程資料庫訪問與生成SQLite資料庫
- kubernetes使用http rest api訪問叢集之使用postman工具訪問 apiserverHTTPRESTAPIPostmanServer
- Python使用SQLAlchemy訪問MemFireDBPythonSQL
- [譯]使用Laravel訪問前端CookieLaravel前端Cookie
- 使用別名訪問MSSQL ExpressSQLExpress
- 9000埠使用ip不能訪問
- Spring Boot 2.x基礎教程:使用JdbcTemplate訪問MySQL資料庫Spring BootJDBCMySql資料庫
- MongoDB最簡單的入門教程之二 使用nodejs訪問MongoDBMongoDBNodeJS
- iOS12家長控制模式使用教程 蘋果訪問限制有什麼用?iOS模式蘋果
- 使用ADO訪問Oracle問題彙總Oracle
- win10快速訪問設定教程 win10系統快速訪問設定方法Win10
- Struts2教程之三Action訪問方式
- 使用Fluentd + Elasticsearch收集訪問日誌Elasticsearch
- SecureCRT訪問HPUX無法使用viSecurecrtUX
- 如何使用RestTemplate訪問restful服務REST
- Oracle使用utl_http訪問webserviceOracleHTTPWeb
- 使用主機命名方法訪問oracleOracle
- 使用 useRequestEvent Hook 訪問請求事件Hook事件
- 內網IP地址實現HTTPS加密訪問教程內網HTTP加密
- 群暉 / 貓盤等私有 NAS 使用網穿雲進行內網穿透訪問教程內網穿透
- win10系統怎麼訪問桌面desktop_win10快速訪問desktop的教程Win10
- Laravel 使用筆記之一 訪問器Laravel筆記
- 使用nginx控制ElasticSearch訪問許可權NginxElasticsearch訪問許可權
- Lumen 使用 throttle 限制介面訪問頻率
- jmeter 使用 ssh 方式訪問資料庫JMeter資料庫