一.快速入門
*在數(shù)據(jù)庫中建立好表
*在程序中導入數(shù)據(jù)庫驅(qū)動包
1.注冊數(shù)據(jù)庫驅(qū)動
DriverManager.registerDriver(new Driver());//缺點一:觀察mysqlDriver源碼發(fā)現(xiàn)此方法導致了數(shù)據(jù)庫驅(qū)動被注冊了兩次排拷。缺點二:整個程序域mysql數(shù)據(jù)庫驅(qū)動綁定增加了耦合性
Class.forName(“com.mysql.jdbc.Driver”);
2.獲取連接
DriverManager.getConnection(url, user, password);
~url的寫法:
Oracle寫法:jdbc:oracle:thin:@localhost:1521:sid
SqlServer—jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sid
MySql—jdbc:mysql://localhost:3306/sid
~url可以接的參數(shù)
user伞矩、password
useUnicode=true&characterEncoding=UTF-8
3.獲取傳輸器
createStatement():創(chuàng)建向數(shù)據(jù)庫發(fā)送sql的statement對象蜕径。
prepareStatement(sql) :創(chuàng)建向數(shù)據(jù)庫發(fā)送預編譯sql的PrepareSatement對象它匕。
4.利用傳輸器執(zhí)行sql語句獲取結果集
executeQuery(String sql) :用于向數(shù)據(jù)發(fā)送查詢語句。
executeUpdate(String sql):用于向數(shù)據(jù)庫發(fā)送insert紧唱、update或delete語句
execute(String sql):用于向數(shù)據(jù)庫發(fā)送任意sql語句
5.遍歷結果集取出結構
ResultSet以表的樣式在內(nèi)存中保存了查詢結果存炮,其中還維護了一個游標,最開始的時候游標在第一行之前夺姑,每調(diào)用一次next()方法就試圖下移一行墩邀,如果移動成功返回true;
ResultSet還提供了很多個Get方法盏浙,用來獲取查詢結果中的不同類型的數(shù)據(jù)
除了next方法眉睹,還有以下方法可以用來遍歷結果集:
next():移動到下一行
Previous():移動到前一行
absolute(int row):移動到指定行
beforeFirst():移動resultSet的最前面荔茬。
afterLast() :移動到resultSet的最后面。
6.釋放資源
conn是一個有限的資源竹海,用完立即要釋放表
stat占用內(nèi)存慕蔚,所以使用完后也要釋放
rs占用內(nèi)存,所以使用完后也要釋放
釋放時后創(chuàng)建的先釋放
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally{
rs = null;
}
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
} finally{
stat = null;
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
} finally{
conn = null;
}
}
?二.PreparedStatement
1.Sql注入:
由于jdbc程序在執(zhí)行的過程中sql語句在拼裝時使用了由頁面?zhèn)魅雲(yún)?shù)站削,如果用戶惡意傳入一些sql中的特殊關鍵字坊萝,會導致sql語句意義發(fā)生變化孵稽,這種攻擊方式就叫做sql注入许起,參考用戶注冊登錄案例。
2.PreparedStatement
PreparedStatement是Statement的孩子菩鲜,不同的是园细,PreparedStatement使用預編譯機制,在創(chuàng)建PreparedStatement對象時就需要將sql語句傳入接校,傳入的過程中參數(shù)要用?替代猛频,這個過程回導致傳入的sql被進行預編譯,然后再調(diào)用PreparedStatement的setXXX將參數(shù)設置上去蛛勉,由于sql語句已經(jīng)經(jīng)過了預編譯鹿寻,再傳入特殊值也不會起作用了。
3.
PreparedStatement使用了預編譯機制诽凌,sql語句在執(zhí)行的過程中效率比Statement要高毡熏。
四、大數(shù)據(jù)
1.mysql數(shù)據(jù)庫也可以直至在數(shù)據(jù)庫中保存大文本和大二進制數(shù)據(jù)侣诵,
Text
TINYTEXT(255)痢法、TEXT(64k)、MEDIUMTEXT(16M)和LONGTEXT(4G)
Blob
TINYBLOB杜顺、BLOB财搁、MEDIUMBLOB和LONGBLOB
2.JDBC去操作大文本:
~插入大文本:
ps = conn.prepareStatement("insert into Demo2Text values(null,?,?)");
ps.setString(1, "鋼鐵是怎樣練成");
File file = new File("1.txt");
ps.setCharacterStream(2, new FileReader(file), (int) file.length());
//1.Exception in thread "main" java.lang.AbstractMethodError: com.mysql.jdbc.PreparedStatement.setCharacterStream(ILjava/io/Reader;J)V
//ps.setCharacterStream(2, new FileReader(file), file.length());第三個參數(shù)是long型的是從1.6才開始支持的,驅(qū)動里還沒有開始支持躬络。
//解決方案:ps.setCharacterStream(2, new FileReader(file), (int)file.length());
//2.Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
//文件大小過大尖奔,導致PreparedStatement中數(shù)據(jù)多大占用內(nèi)存,內(nèi)存溢出
//-Xms256M-Xmx256M
//3.com.mysql.jdbc.PacketTooBigException: Packet for query is too large (10886466 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
//數(shù)據(jù)庫連接傳輸用的包不夠大穷当,傳輸大文本時報此錯誤
//在my.ini中配置max_allowed_packet指定包的大小
~查詢大文本:
Reader rd = rs.getCharacterStream("content");
3.JDBC操作大二進制
~插入:
ps = conn.prepareStatement("insert into Demo3Blob values(null,?,?)");
ps.setString(1, "夢想的力量");
File file = new File("1.mp3");
ps.setBinaryStream(2, new FileInputStream(file), (int) file.length());
~查詢
InputStream in = rs.getBinaryStream("content");