1. 程式人生 > 實用技巧 >JDBC Template

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/85118329
15 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(); } }

} }}