本文將以DLA讀取RDS中的資料為前提,介紹如何在DLA應用中,通過Java、PHP、C#調用PreparedStatement介面處理SQL請求。
背景資訊
DLA中支援調用PreparedStatement介面,與手動編寫SQL相比,調用PreparedStatement介面有以下優勢:
PreparedStatement介面自動做敏感字元的轉義,防止SQL Injection攻擊。
PreparedStatement介面動態執行SQL,Prepare一次之後,後續執行時只需替換參數即可。
PreparedStatement可以以OOP(Object Oriented Programming)的方式編寫SQL。調用PreparedStatement介面後,將通過
PreparedSteatement.setXxx()
的方式來設定參數。
前提條件
DLA中正式調用PreparedStatement介面之前,您可以參見文檔讀寫RDS MySQL資料,在DLA中建立RDS Schema和表。
本樣本在DLA中建立type_test表:
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 ''
)
以下樣本通過MySQL命令列工具串連DLA(也可以通過MySQL用戶端或者直接在DMS中查詢type_test表資料),然後讀取type_test表資料。
> select * from type_test\G;
*************************** 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)
說明
select * from type_test\G;
中\G
參數可使資料縱向顯示。
Java
DLA相容MySQL協議,可以使用MySQL的JDBC驅動串連DLA。DLA串連成功後,即可通過Java調用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` = ?";
//串連DLA
try (Connection dlaConn = DriverManager.getConnection(
"jdbc:mysql://101*******-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
$mysqli = new mysqli("fakee.cn-hangzhou.datalakeanalytics.aliyuncs.com:10000", "your-username", "your-password", "yourdb");
$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)
}
}
C#
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.