JDBC Template
query(new BeanPropertyRowMapper<T>(T.class));
-----------------------------------------------------------
JDBC連線mysql資料庫,執行更新sql指令的一般順序如下(密碼和sql語句略去)
1 package cn.gao.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.Statement; 6 7 public class JdbcDemo1 {8 public static void main(String[] args) throws Exception { 9 // 1,匯入驅動jar包(mysql-connector-java-5.1.49-bin.jar),新增libs目錄,拷貝jar到libs目錄下 10 11 // 2,註冊驅動(反射) 12 Class.forName("com.mysql.jdbc.Driver"); 13 // 3,獲取資料庫連線物件 Connection,不適用引數useSSL=false,會有警告,詳看一下連結 14 // https://blog.csdn.net/qq_41785135/article/details/8511832915 String url="jdbc:mysql://localhost:3306/mydata?useSSL=false"; 16 String username="root"; 17 String password="xxx"; 18 Connection conn = DriverManager.getConnection(url,username,password); 19 // 4,定義sql語句 20 String sql="update xxx set xxx='xxx' where xxx=xxx";21 // 5,獲取執行sql語句的物件 Statement 22 Statement statement = conn.createStatement(); 23 // 6,執行sql,接收返回結果 24 int count = statement.executeUpdate(sql); 25 // 7,處理結果 26 System.out.println(count); 27 // 8,釋放資源 28 statement.close(); 29 conn.close(); 30 31 } 32 }
執行Insert語句如下
1 package cn.gao.jdbc; 2 3 import java.sql.*; 4 5 /** 6 * 增加記錄 statement.executeUpdate(sql); 7 */ 8 public class JdbcDemo2 { 9 public static void main(String[] args) { 10 Connection connection=null; 11 Statement statement=null; 12 try { 13 Class.forName("com.mysql.jdbc.Driver"); 14 String url="jdbc:mysql://localhost:3306/mydata?useSSL=false"; 15 String username="root"; 16 String password="xxx"; 17 connection = DriverManager.getConnection(url, username, password); 18 statement = connection.createStatement(); 19 String sql="INSERT INTO xxx VALUES('xxx','xxx','xxx。')"; 20 int count = statement.executeUpdate(sql); 21 if (count>=1){ 22 System.out.println("插入成功,受影響的行數:"+count); 23 } 24 else 25 { 26 System.out.println("插入失敗"); 27 } 28 } catch (Exception e) { 29 e.printStackTrace(); 30 } 31 finally { 32 if(statement!=null){ 33 try { 34 statement.close(); 35 } catch (SQLException throwables) { 36 throwables.printStackTrace(); 37 } 38 } 39 if(connection!=null){ 40 try { 41 connection.close(); 42 } catch (SQLException throwables) { 43 throwables.printStackTrace(); 44 } 45 } 46 47 48 } 49 } 50 }
刪除語句也類似,都是載入驅動,獲取連線、定義sql,執行sql,關閉連線等等
這樣就發現重複語句太多,且會遇到SQL注入問題(拼接sql過程中,通過輸入邏輯語句造成某條語句發生邏輯變化),解決辦法是執行sql是的物件使用PreparedStatement,sql字串不直接拼接,通過傳參的形式處理。
於是,將重複的欄位抽取出來,封裝成一個工具類(載入驅動、獲取連線只需要建立一個工具類的物件即可)
1 package cn.gao.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.SQLException; 6 import java.sql.Statement; 7 8 public class JdbcUtil { 9 Connection connection = null; 10 Statement statement = null; 11 12 /** 13 * 初始化方法 14 */ 15 public void init() { 16 try { 17 Class.forName("com.mysql.jdbc.Driver"); 18 String url = "jdbc:mysql://localhost:3306/mydata?useSSL=false"; 19 String username = "root"; 20 String password = "xxx"; 21 connection = DriverManager.getConnection(url, username, password); 22 statement = connection.createStatement(); 23 } catch (Exception e) { 24 e.printStackTrace(); 25 } 26 System.out.println("初始化成功"); 27 } 28 29 /** 30 * 關閉資源方法 31 */ 32 public void close() { 33 if (statement != null) try { 34 statement.close(); 35 } catch (SQLException throwables) { 36 throwables.printStackTrace(); 37 } 38 if (connection != null) try { 39 connection.close(); 40 } catch (SQLException throwables) { 41 throwables.printStackTrace(); 42 } 43 System.out.println("關閉資源成功"); 44 } 45 }
工具測試類如下
1 package cn.gao.jdbc; 2 3 /** 4 * 用JdbcUtil封裝載入驅動和關閉資源,避免每次重複寫載入驅動,獲取連線和statement和關閉資源的操作。 5 */ 6 public class JdbcDemo5 { 7 public static void main(String[] args) { 8 JdbcUtil jdbcUtil = new JdbcUtil(); /*呼叫JdbcUtil的初始化init()方法*/ 9 jdbcUtil.init(); 10 String sql = "update xxx set xxx='xxx' where errcode=7"; 11 try { 12 int count = jdbcUtil.statement.executeUpdate(sql); 13 if (count > 0) 14 System.out.println("更新成功,受影響的行數:" + count); 15 else System.out.println("更新失敗!"); 16 } catch (Exception throwables) { 17 throwables.printStackTrace(); 18 } 19 /*呼叫JdbcUtil的關閉close()方法*/ 20 jdbcUtil.close(); 21 } 22 }
這樣就節省了許多重複的工作。
或者工具類也可以如下定義(從jdbc.properties配置檔案載入資料庫url,使用者名稱,密碼,驅動)
1 package cn.gao.jdbc; 2 3 import java.io.FileReader; 4 import java.io.IOException; 5 import java.net.URL; 6 import java.sql.*; 7 import java.util.Properties; 8 9 public class JdbcUtil1 { 10 11 private static String driver; 12 private static String url; 13 private static String username; 14 private static String password; 15 16 static { 17 ClassLoader loader = JdbcUtil1.class.getClassLoader(); 18 URL resource = loader.getResource("jdbc.properties"); 19 String path = resource.getPath(); 20 Properties prop = new Properties(); 21 try { 22 prop.load(new FileReader(path)); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 driver = prop.getProperty("driver"); 27 url = prop.getProperty("url"); 28 username = prop.getProperty("username"); 29 password = prop.getProperty("password"); 30 try { 31 Class.forName(driver); 32 } catch (ClassNotFoundException e) { 33 e.printStackTrace(); 34 } 35 } 36 37 public static Connection getConnection() { 38 try { 39 return DriverManager.getConnection(url, username, password); 40 } catch (SQLException throwables) { 41 throwables.printStackTrace(); 42 } 43 return null; 44 } 45 46 public static void close(Statement stat, Connection conn) { 47 if (stat != null) { 48 try { 49 stat.close(); 50 } catch (SQLException throwables) { 51 throwables.printStackTrace(); 52 } 53 } 54 if (conn != null) { 55 try { 56 conn.close(); 57 } catch (SQLException throwables) { 58 throwables.printStackTrace(); 59 } 60 } 61 } 62 63 public static void close(ResultSet rs, Statement stat, Connection conn) { 64 if (rs != null) { 65 try { 66 rs.close(); 67 } catch (SQLException throwables) { 68 throwables.printStackTrace(); 69 } 70 } 71 if (stat != null) { 72 try { 73 stat.close(); 74 } catch (SQLException throwables) { 75 throwables.printStackTrace(); 76 } 77 } 78 if (conn != null) { 79 try { 80 conn.close(); 81 } catch (SQLException throwables) { 82 throwables.printStackTrace(); 83 } 84 } 85 } 86 }
測試類如下:
1 package cn.gao.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.ResultSet; 5 import java.sql.SQLException; 6 import java.sql.Statement; 7 8 public class JdbcDemo7 { 9 public static void main(String[] args) { 10 Connection connection = null; 11 Statement statement =null; 12 ResultSet resultSet =null; 13 try { 14 connection = JdbcUtil1.getConnection(); 15 statement = connection.createStatement(); 16 String sql = "select * from xxx"; 17 resultSet = statement.executeQuery(sql); 18 while (resultSet.next()) { 19 String errcode = resultSet.getString("errcode"); 20 String meaning = resultSet.getString("meaning"); 21 String description = resultSet.getString("description"); 22 System.out.println("errcode:" + errcode + ",meaning:" + meaning + ",description:" + description); 23 } 24 25 } catch (SQLException throwables) { 26 throwables.printStackTrace(); 27 } 28 finally { 29 JdbcUtil1.close(resultSet, statement, connection); 30 } 31 32 33 } 34 }
Druid連線池的匯入
1 package cn.gao.datasource; 2 3 import com.alibaba.druid.pool.DruidDataSourceFactory; 4 5 import javax.sql.DataSource; 6 import java.io.InputStream; 7 import java.sql.Connection; 8 import java.sql.PreparedStatement; 9 import java.util.Properties; 10 11 /** 12 * Druid連線池Demo 13 */ 14 15 public class DruidDemo { 16 public static void main(String[] args) throws Exception { 17 Properties prop = new Properties(); 18 InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); 19 prop.load(is); 20 DataSource dataSource = DruidDataSourceFactory.createDataSource(prop); 21 String sql="select * from xxxx"; 22 Connection connection = dataSource.getConnection(); 23 PreparedStatement preparedStatement = connection.prepareStatement(sql); 24 boolean execute = preparedStatement.execute(); 25 System.out.println(execute); 26 preparedStatement.close(); 27 connection.close(); 28 29 } 30 }
# druid.properties檔案的配置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mydata?useSSL=false
username=root
password=xxxx
# 初始化連線數量
initialSize=5
# 最大連線數
maxActive=10
# 最大超時時間
maxWait=3000
Druid連線池也是需要每次從獲取連線和關閉資源,因此創造一個DruidUtils工具類,將獲取資料來源、連線和關閉資源的方法都封裝到工具類中
1 package cn.gao.datasource; 2 3 import com.alibaba.druid.pool.DruidDataSourceFactory; 4 5 import javax.sql.DataSource; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.sql.*; 9 import java.util.Properties; 10 11 public class DruidUtils { 12 //定義DataSource物件 13 private static DataSource ds; 14 static { 15 try { 16 //定義Properties物件 17 Properties prop = new Properties(); 18 //定義位元組輸入流物件,並從druid.properties檔案讀取資料 19 InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); 20 //Properties物件load位元組輸入流物件 21 prop.load(is); 22 //使用DruidDataSourceFactory工廠建立DataSource 23 ds = DruidDataSourceFactory.createDataSource(prop); 24 } catch (IOException e) { 25 e.printStackTrace(); 26 } catch (Exception e) { 27 e.printStackTrace(); 28 } 29 30 } 31 32 /** 33 * 34 * @return 資料來源(DataSource)物件 35 */ 36 public static DataSource getDataSource(){ 37 return ds; 38 } 39 40 /** 41 * 42 * @return 連線(Connection)物件 43 * @throws SQLException 44 */ 45 public static Connection getConnection() throws SQLException { 46 return ds.getConnection(); 47 } 48 49 /** 50 * 51 * @param preparedStatement PreparedStatement物件 52 * @param connection Connection物件 53 */ 54 public static void close(PreparedStatement preparedStatement, Connection connection) { 55 // if(preparedStatement!=null){ 56 // try { 57 // preparedStatement.close(); 58 // } catch (SQLException throwables) { 59 // throwables.printStackTrace(); 60 // } 61 // } 62 // if(connection!=null){ 63 // try { 64 // connection.close(); 65 // } catch (SQLException throwables) { 66 // throwables.printStackTrace(); 67 // } 68 // } 69 close(null, preparedStatement, connection); 70 71 } 72 73 /** 74 * 75 * @param resultSet 結果集物件 76 * @param preparedStatement PreparedStatement物件 77 * @param connection Connection物件 78 */ 79 public static void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) { 80 if (resultSet != null) { 81 try { 82 resultSet.close(); 83 } catch (SQLException throwables) { 84 throwables.printStackTrace(); 85 } 86 87 if (preparedStatement != null) { 88 try { 89 preparedStatement.close(); 90 } catch (SQLException throwables) { 91 throwables.printStackTrace(); 92 } 93 } 94 if (connection != null) { 95 try { 96 connection.close(); 97 } catch (SQLException throwables) { 98 throwables.printStackTrace(); 99 } 100 } 101 102 } 103 } 104 }
實際的類中,只需要獲取連線和執行sql
1 package cn.gao.datasource; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.SQLException; 6 7 public class DruidUtilsDemo { 8 public static void main(String[] args) { 9 Connection connection = null; 10 PreparedStatement preparedStatement = null; 11 try { 12 //獲取連線 13 connection = DruidUtils.getConnection(); 14 //定義SQL 15 String sql = "insert into myerrorcode values(?,?,?)"; 16 //獲取執行Sql物件 17 preparedStatement = connection.prepareStatement(sql); 18 preparedStatement.setString(1, "xxx"); 19 preparedStatement.setString(2, "xxx"); 20 preparedStatement.setString(3, "xxx"); 21 //執行sql 22 int count = preparedStatement.executeUpdate(); 23 System.out.println(count); 24 } catch (SQLException throwables) { 25 throwables.printStackTrace(); 26 } finally { 27 //關閉資源 28 DruidUtils.close(preparedStatement, connection); 29 } 30 } 31 }
由於上面的jdbc連線是每次獲取連線,每次獲取連線仍然是有些麻煩,因此使用JdbcTemplate來解決,JdbcTemplate需要一個DataSource,正好DruidUtils中有這個方法,傳遞到JdbcTemplate物件中。然後定義和執行Sql即可,也無需關閉資源,JdbcTemplate會自己釋放。
1 package cn.gao.jdbctemplate; 2 3 import cn.gao.datasource.DruidUtils; 4 import org.springframework.jdbc.core.JdbcTemplate; 5 6 import javax.sql.DataSource; 7 8 public class JdbcTemplateDemo1 { 9 public static void main(String[] args) { 10 //使用工具類獲取DataSource物件 11 DataSource dataSource = DruidUtils.getDataSource(); 12 //建立JdbcTemplate物件,傳遞DataSource物件引數 13 JdbcTemplate template = new JdbcTemplate(dataSource); 14 //定義Sql語句 15 String sql = "UPDATE xxx SET xxx=? WHERE xxx=?"; 16 //執行Sql語句,獲取列印執行結果 17 int count = template.update(sql, "xxxxxxxx", "xxxx"); 18 System.out.println(count); 19 } 20 }
這樣程式碼就比較簡單了。
package cn.gao.jdbc;
import java.sql.*;
/*** 增加記錄 statement.executeUpdate(sql);*/public class JdbcDemo2 { public static void main(String[] args) { Connection connection=null; Statement statement=null; try { Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql://localhost:3306/mydata?useSSL=false"; String username="root"; String password="GAO@2020"; connection = DriverManager.getConnection(url, username, password); statement = connection.createStatement(); String sql="INSERT INTO myerrorcode VALUES('8','NET_DVR_NETWORK_SEND_ERROR','向裝置傳送失敗。')"; int count = statement.executeUpdate(sql); if (count>=1){ System.out.println("插入成功,受影響的行數:"+count); } else { System.out.println("插入失敗"); } } catch (Exception e) { e.printStackTrace(); } finally { if(statement!=null){ try { statement.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if(connection!=null){ try { connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } }
} }}