一直在想着寫點特別點的東西,讓有興趣學編程的人確實能學到點干貨,今天就來隨意寫寫。
大家在網上查找資料看到最多的demo估計就是登錄功能的演示了,為何大家偏愛拿登錄來做demo呢?因為行業應用類程序的核心就是為了讓用戶能與數據進行交互,對於一個高級DBA來說的話,他與數據的交互可以直接與數據庫進行打交道,而對於小白用戶來說的話就需要非常友好的UI與數據進行交互,那么就需要各種編程語言工具來實現這個過程了。而我們開發一個應用類軟件,主要要對需求業務充分了解之后才能進行開發,比如開發一個財務類軟件,如果你不懂財務,談何開發。而登錄功能是大家接觸最多,也不用解釋業務的功能,因此作為demo講解自然是最合適的。下面就以Java的學習進行講解登錄demo,從最開始的helloword模式一直演化到SSM框架模式,演示過程中穿插講解各個學習階段涉及到的基礎知識點。
這里編程工具采用eclipse,首先建立一個普通的java工程,寫我們的第一個程序
package com.xdw; /** * @author xiadewang *2018年1月14日 */ public class LoginTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("歡迎您登錄"); } }
很簡單,是不是就是helloword? main方法是程序的入口方法。
好下面對上面的程序一步步擴展,想到登錄就是對用戶名和密碼進行判斷,那么修改代碼如下:
public static void main(String[] args) { // TODO Auto-generated method stub // System.out.println("歡迎您登錄"); String username = "xdw",password="123456"; if(username=="xdw" && password=="123456") { System.out.println("xdw用戶登錄成功"); }else { System.out.println("登錄失敗"); } }
這里就引入到了java基礎知識的變量的聲明、定義與賦值,變量類型,注釋,比較運算符,if..else邏輯語句。這些基礎就不再啰嗦了
這樣改寫之后,發現只對用戶xdw進行了登錄的判斷,如果每次更換一個用戶名或者密碼,就都要改動上面整個的代碼,那么這個時候就該函數(Java里面又叫方法)出場了。
將用戶名和密碼作為方法的形參,將判斷結果作為返回值。代碼如下
package com.xdw; /** * @author xiadewang *2018年1月13日 */ public class LoginTest { public static void main(String[] args) { // TODO Auto-generated method stub // System.out.println("歡迎您登錄"); /* String username = "xdw",password="123456"; if(username=="xdw" && password=="123456") { System.out.println("xdw用戶登錄成功"); }else { System.out.println("登錄失敗"); }*/ LoginTest login=new LoginTest(); if(login.checkLogin("xdw","123")) { System.out.println("登錄成功"); }else { System.out.println("登錄失敗"); } if(login.checkLogin("xxx","1234")) { System.out.println("登錄成功"); }else { System.out.println("登錄失敗"); } } public boolean checkLogin(String username,String password) { if(username=="xdw" && password=="123") { return true; } else { return false; } } }
上面把最開始main函數里面的邏輯判斷封裝到了checkLogin函數之中,由於這里沒有UI界面,我們就把print打印看做是實際業務處理,那面checkLogin方法就是做的純粹邏輯處理,
具體的業務我們還是放在main方法中做,那么就將checkLogin方法的返回值設置為boolean,而不是void。此時有點邏輯與業務分離的味道了。。
順便啰嗦下方法如何定義,首先是修飾符(public或者private和protected,這個知識點主要就是了解它們的作用域,還不清楚的同學趕緊去復習下),然后是返回類型(如果是void,則在函數體中不需要return,其他則需要retrun。),接下來是函數名稱(命名規范一般是首字母小寫,駝峰命名),下面就是形參(命名規范也是首字母小寫,駝峰命名)。
那么此時方法定義好了,我們該如何在main中調用它呢?首先main方法是static的,而我們現在定義的方法是非static的,在同一個類中,static的方法里面是不能直接調用該類中的其他非static的方法的,需要先new一個該類的對象出來,然后通過該對象進行方法的調用,如代碼中所示。還有一個辦法就是將checkLogin方法改成staic的方法,則在main中就不用new了,直接調用該方法。看下面的代碼
package com.xdw; /** * @author xiadewang *2018年1月13日 */ public class LoginTest { public static void main(String[] args) { // TODO Auto-generated method stub // System.out.println("歡迎您登錄"); /* String username = "xdw",password="123456"; if(username=="xdw" && password=="123456") { System.out.println("xdw用戶登錄成功"); }else { System.out.println("登錄失敗"); }*/ if(checkLogin()) { System.out.println("游客登錄"); } LoginTest login=new LoginTest(); if(login.checkLogin("xdw","123")) { System.out.println("登錄成功"); }else { System.out.println("登錄失敗"); } if(login.checkLogin("xxx","1234")) { System.out.println("登錄成功"); }else { System.out.println("登錄失敗"); } } public boolean checkLogin(String username,String password) { if(username=="xdw" && password=="123") { return true; } else { return false; } } public static boolean checkLogin() { return true; } }
大家可以看到在main中直接調用了checkLogin(),這個函數沒有傳遞用戶名和密碼,就相當於游客模式登錄,同時這里又引入了一個知識點重載。什么是重載?重載的兩個要素就是函數名相同,參數不同(參數不同是指的參數個數不一樣,或者參數的類型不一樣,不是說的參數名稱不同,形參的名稱是可以隨意命名的)。重載的作用是什么呢?完全可以給上面的checkLogin方法重新取個別的名字啊。是滴,取別的名字一點問題也沒有,重載的主要作用是增加程序的可讀性,我們在閱讀API文檔的時候好多時候通過函數的名稱就大概知道它是干什么用的。我們在調用的時候,就不需要記那么多的方法名稱,而是知道了方法的功能就可以直接的給他傳遞不同的參數,編譯器會明確的知道我們調用了哪一個方法。
寫到這里,我們所有的用戶數據都是自己在代碼中寫死的虛構出來的數據,實際業務中,用戶數據肯定不可能寫在代碼中,那么這個時候就輪到數據庫出場了。實際開發中,用戶數據都是存儲在數據庫之中,此時判斷用戶登錄的簡單邏輯如下,我們傳遞用戶名和密碼參數給checkLogin方法,然后該方法中去查詢數據庫,看該用戶名和密碼是否匹配,如果匹配則代表登錄成功,反之失敗。java中如何連接數據庫進行操作呢?這時就需要JDBC了,這里以mysql為例,簡單講解下jdbc的操作流程。
我們在之前的代碼中加入下面的一個方法checkLoginByJdbc,此時就不能再用checkLogin這個名字了,因為形參相同。
package com.xdw; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author xiadewang *2018年1月13日 */ public class LoginTest { private Connection connection=null; private ResultSet resultSet=null; public static void main(String[] args) { // TODO Auto-generated method stub // System.out.println("歡迎您登錄"); /* String username = "xdw",password="123456"; if(username=="xdw" && password=="123456") { System.out.println("xdw用戶登錄成功"); }else { System.out.println("登錄失敗"); }*/ if(checkLogin()) { System.out.println("游客登錄"); } LoginTest login=new LoginTest(); if(login.checkLogin("xdw","123")) { System.out.println("登錄成功"); }else { System.out.println("登錄失敗"); } if(login.checkLogin("xxx","1234")) { System.out.println("登錄成功"); }else { System.out.println("登錄失敗"); } if(login.checkLoginByJdbc("xdw","123456")) { System.out.println("xdw通過jdbc登錄成功"); }else { System.out.println("登錄失敗"); } } public boolean checkLogin(String username,String password) { if(username=="xdw" && password=="123") { return true; } else { return false; } } public static boolean checkLogin() { return true; } public boolean checkLoginByJdbc(String username,String password) { try { //通過反射獲取數據庫連接驅動 Class.forName("com.mysql.jdbc.Driver"); try { //獲取數據庫連接對象 connection=DriverManager.getConnection("jdbc:mysql://127.0.0.1/jsplogintest","root","root"); //構建sql語句,?代表需要綁定的參數 String sql="select * from user where username=? and password=?"; //獲取PreparedStatement對象 PreparedStatement preparedStatement=connection.prepareStatement(sql); //綁定參數 preparedStatement.setString(1, username); preparedStatement.setString(2, password); //執行sql語句,這里是查詢語句,所以調用executeQuery返回結果集 resultSet=preparedStatement.executeQuery(); //獲取結果集之后數據庫的操作就結束了,后面是要根據結果集來處理我們的業務邏輯 if(resultSet.next()) { //結果集不為空,則可以表示用戶存在,即登錄成功 resultSet.close(); connection.close(); return true; } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } }
數據表結構如下

jdbc的操作流程上面注釋也寫的比較清楚了,以后就是照葫蘆畫瓢了,jdbc操作很簡單,重要的技能還是要對sql玩的牛才行。
這里代碼的復用性太差,沒寫一個方法的時候,都去寫一堆的jdbc的連接與關閉操作顯然不現實,於是我們需要把它們封裝到一個工具類當中,如下面的DBHelper
package com.xdw; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * @author xiadewang *2018年1月13日 */ public class DBHelper { public static final String url = "jdbc:mysql://127.0.0.1/jsplogintest"; public static final String name = "com.mysql.jdbc.Driver"; public static final String user = "root"; public static final String password = "root"; public Connection conn = null; public PreparedStatement pst = null; public DBHelper(String sql) { try { Class.forName(name);//指定連接類型 conn = DriverManager.getConnection(url, user, password);//獲取連接 pst = conn.prepareStatement(sql);//准備執行語句 } catch (Exception e) { e.printStackTrace(); } } public void close() { try { this.conn.close(); this.pst.close(); } catch (SQLException e) { e.printStackTrace(); } } }
然后改寫checkLoginByJdbc方法,如下
public boolean checkLoginByJdbc(String username, String password) { try { String sql = "select * from user where username= ? and password= ?";// SQL語句 DBHelper db1 = new DBHelper(sql);// 創建DBHelper對象 db1.pst.setString(1, username); db1.pst.setString(2, password); ResultSet ret = db1.pst.executeQuery();// 執行語句,得到結果集 if(ret.next()) { return true; } ret.close(); db1.close();// 關閉連接 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; }
第一階段先就到這里吧,至此我們都是用面向過程的方法去實現該功能的,直接想實現登錄功能,就在處理業務的主入口main中去開始編碼了,下面引入接口的概念,從設計層面上去講下如何實現登錄功能,即面向接口編程。
