一、建立單例模式的緣由java
節省系統資源、保持數據的一致性。mysql
例子:windows中只能打開一個任務管理器、線程池、數據庫鏈接池、網站計數器等,都被設計成單例模式。sql
二、單例模式的特色數據庫
(1)只有一個實例對象;windows
(2)由單例類自行建立;服務器
(3)對外提供一個訪問該單例的全局訪問點。(經常使用static方法)app
三、如何構建單例模式ide
(1)懶漢式函數
package cn.function.designmodel; public class SingletonTest { // 靜態變量,原子操做 private static volatile SingletonTest singletonTest = null; // 用於外部測試是不是單例 public String name = "我是單例1"; // 經過構造私有的構造方法,防止被外部實例化 private SingletonTest() { }; // 對外提供一個實例化的方法,生成單例 public static SingletonTest getInstance() { if (singletonTest == null) { singletonTest = new SingletonTest(); } return singletonTest; } }
(2)餓漢式測試
一旦加載類,就建立一個單例
package cn.function.designmodel; /** * 餓漢式 * * @author ycXie * */ public class Singleton2 { // 定義一個常量,引用自身實例 private static final Singleton2 SINGLETON2 = new Singleton2(); public String name = "單例"; // 將構造函數定義爲私有類型,防止外部實例化 private Singleton2() { }; // 經過構建一個public的全局訪問點,獲得該單例 public static Singleton2 getInstance() { return SINGLETON2; } }
測試:
package cn.function.designmodel; public class MainTest { public static void main(String[] args) { SingletonTest singletonTest = SingletonTest.getInstance(); SingletonTest singletonTest2 = SingletonTest.getInstance(); singletonTest.name = "單例1"; singletonTest2.name = "單例2"; System.out.println(singletonTest.name); System.out.println(singletonTest2.name); Singleton2 singleton2 = Singleton2.getInstance(); Singleton2 singleton22 = Singleton2.getInstance(); singleton2.name = "單例3"; singleton22.name = "單例4"; System.out.println(singleton2.name); System.out.println(singleton22.name); } }
結果:
單例2
單例2
單例4
單例4
確實爲單例。
四、單例模式的應用實例
數據庫鏈接:
一、DBhelper
package cn.function.designmodel.singleton; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * 單例模式的數據庫鏈接 * * @author ycXie * */ public class DBhelperSingleton { private static volatile DBhelperSingleton dBhelperSingleton = null; public String url; public String name; public Connection conn; public PreparedStatement pst; private DBhelperSingleton(String sql, String url, String name, String username, String password) throws ClassNotFoundException, SQLException { this.url = url; this.name = name; Class.forName(name); conn = DriverManager.getConnection(url, username, password); pst = conn.prepareStatement(sql); }; public static DBhelperSingleton getInstance(String sql, String url, String name, String username, String password) throws ClassNotFoundException, SQLException { if (dBhelperSingleton == null) { dBhelperSingleton = new DBhelperSingleton(sql, url, name, username, password); } return dBhelperSingleton; } public void close() { try { if (conn != null) { conn.close(); } if (pst != null) { pst.close(); } } catch (Exception e) { // TODO: handle exception } } }
二、調用
package cn.function.designmodel.singleton; import java.sql.ResultSet; import java.sql.SQLException; import cn.rigid.hoistmnteg.model.User; public class MainTest { public static void main(String[] args) { SingletonTest singletonTest = SingletonTest.getInstance(); SingletonTest singletonTest2 = SingletonTest.getInstance(); singletonTest.name = "單例1"; singletonTest2.name = "單例2"; System.out.println(singletonTest.name); System.out.println(singletonTest2.name); Singleton2 singleton2 = Singleton2.getInstance(); Singleton2 singleton22 = Singleton2.getInstance(); singleton2.name = "單例3"; singleton22.name = "單例4"; System.out.println(singleton2.name); System.out.println(singleton22.name); String sql = "select * from user"; String url = "jdbc:mysql://localhost:3306/hoistmnt"; String name = "com.mysql.jdbc.Driver"; String username = "root"; String password = "root"; ResultSet rst; User user = new User(); try { DBhelperSingleton dBhelperSingleton = DBhelperSingleton.getInstance(sql, url, name, username, password); DBhelperSingleton dBhelperSingleton2 = DBhelperSingleton.getInstance(sql, "我要改了", name, username, password); rst = dBhelperSingleton.pst.executeQuery(); // 能夠發現url沒有改變,說明是單例模式 System.out.println(dBhelperSingleton.url); System.out.println(dBhelperSingleton2.url); while (rst.next()) { user.setName(rst.getString("username")); user.setScore(rst.getInt("id")); System.out.println(user); } rst.close(); dBhelperSingleton.close(); } catch (ClassNotFoundException | SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
結果:
單例2 單例2 單例4 單例4 Tue Oct 29 14:34:10 CST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
jdbc:mysql://localhost:3306/hoistmnt jdbc:mysql://localhost:3306/hoistmnt User [uid=null, name=zhangsan, email=null, phone=null, status=null, timeSend=null, score=1] User [uid=null, name=lisi, email=null, phone=null, status=null, timeSend=null, score=2] User [uid=null, name=wangwu, email=null, phone=null, status=null, timeSend=null, score=8]
警告及緣由:原文連接:https://blog.csdn.net/u010429286/article/details/77750177
在JDBC鏈接Mysql數據庫的過程當中出現了以下的警告信息: WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.是Mysql數據庫的SSL鏈接問題,提示警告不建議使用沒有帶服務器身份驗證的SSL鏈接,是在MYSQL5.5.45+, 5.6.26+ and 5.7.6+版本中才有的這個問題。解決辦法在警告中已經說明了:1.在數據庫鏈接的url中添加useSSL=false;2.url中添加useSSL=true,而且提供服務器的驗證證書。若是隻是作一個測試的話,不必搞證書那麼麻煩啦,在鏈接後添加一個useSSL=false便可,例如:jdbc:mysql://localhost:3306/test?useSSL=false在使用Java進行JDBC鏈接的時候,能夠在Properties對象中設置useSSL的值爲false,可是和寫在連接中是同樣的。好比 Properties properties = new Properties(); properties.setProperty("user", "root"); properties.setProperty("password", "milos23); properties.setProperty("useSSL", "false"); properties.setProperty("autoReconnect", "true"); try (Connection conn = DriverManager.getConnection(connectionUrl, properties)) { ... } catch (SQLException e) { ..