Java连接Mysql数据库(JDBC)
文章目錄
- 導(dǎo)入包
- con、stmt、rs 三者存在一定的關(guān)系
- getInt和getString
- input.nextInt();簡單使用講解
- ResultSet和Statement
- PreparedStatement的用法
- JDBC連接代碼
- 更多樣例
導(dǎo)入包
import java.sql.Connection; import java.sql.DriverManager; import java.sql.statement; import java.sql.ResultSet; import java.util.Scanner;import java sql.*;con、stmt、rs 三者存在一定的關(guān)系
(1)連接數(shù)據(jù)庫后 實(shí)例化con
(2)創(chuàng)建stmt=con.createstatement();
(3)然后執(zhí)行rs=stmt.excuteQuery()執(zhí)行sql語句,產(chǎn)生單個(gè)結(jié)果集;
getInt和getString
ResultSet rs = null; String sql="SELECT flow_id,Type,id_card,exam_card,student_name,location,grade FROM examstudent";rs = st.executeQuery(sql); //rs:數(shù)據(jù)集 rs.getInt(int index); rs.getInt(String columName); //你可以通過索引或者列名來獲得查詢結(jié)果集中的某一列的值。//舉例 while(rs.next) {rs.getInt(1)//等價(jià)于rs.getInt("flowid");rs.getString(5)//等價(jià)于rs.getInt("student_name"); }input.nextInt();簡單使用講解
完整的寫法是 先導(dǎo)入 輸入流 類 Scanner
import java.util.Scanner;
然后使用輸入流 , 按照你的問題中的 寫法和名稱, 應(yīng)該這樣使用 Scanner 這個(gè)類
Scanner input = new Scanner(System.in); // 創(chuàng)建輸入流對(duì)象 input int userNum = input.nextInt(); // 使用輸入流對(duì)象 調(diào)用nextInt() 方法輸入一個(gè)整數(shù)到userNum中其意思是 使用 Scanner 類中的 nextInt() 方法 輸入一個(gè)整數(shù), 該方法只是接受一個(gè) 整型的數(shù)據(jù),如果輸入的是非整數(shù)數(shù)據(jù), 將會(huì) 拋出 InputMismatchException異常,其實(shí)就是專門為在命令式界面中 提供的一種輸入類, Scanner 類位于 java.util 包中, 其中還有更多常用的其他方法。
例如:
等等, 如果輸入錯(cuò)誤的話, 或者輸入的東西和你 調(diào)用的方法不匹配, 都會(huì)拋出 InputMismatchException 異常
ResultSet和Statement
ResultSet:
查詢數(shù)據(jù)庫時(shí),返回的是一個(gè)二維的結(jié)果集,我們需要用到ResultSet來遍歷結(jié)果集,獲取每一行的數(shù)據(jù)。
boolean next() 將光標(biāo)從當(dāng)前位置向前移一行。 String getString(int columnIndex) 以java編程語言中String的形式獲取此ResultSet對(duì)象的當(dāng)前行中指定列的值 String getString(String columnLabel) 以java編程語言中String的形式獲取此ResultSet對(duì)象的當(dāng)前行中指定列的值 while(rs.next()) {int id = rs.getInt(1);// 獲取第一個(gè)列的值 編號(hào)idString bookName = rs.getString(2);// 獲取第二個(gè)列的值 圖書名稱 bookNameString author = rs.getString(3);// 獲取第三列的值 圖書作者 authorfloat price = rs.getFloat(4);// 獲取第四列的值 圖書價(jià)格 priceSystem.out.println("id="+id+" bookName="+bookName+" author="+author+" price="+price);System.out.println("................................................");Statement :
(1)建立了到特定數(shù)據(jù)庫的連接之后,就可用該連接發(fā)送 SQL 語句。
(2)Statement 接口提供了三種執(zhí)行 SQL 語句的方法:executeQuery、executeUpdate 和execute
1.方法 executeQuery 用于產(chǎn)生單個(gè)結(jié)果集的語句,例如 SELECT 語句
2.方法 executeUpdate 用于執(zhí)行 INSERT、UPDATE 或 DELETE 語句以及 SQLDDL(數(shù)據(jù)定義語言)語句,例如 CREATE TABLE 和 DROP TABLE。 INSERT、UPDATE 或
DELETE語句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一個(gè)整數(shù),指示受影響的行數(shù)(即更新計(jì)數(shù))。
對(duì)于CREATE TABLE 或 DROP TABLE 等不操作行的語句,executeUpdate 的返回值總為零。
3.方法 execute用于執(zhí)行返回多個(gè)結(jié)果集、多個(gè)更新計(jì)數(shù)或二者組合的語句。
PreparedStatement的用法
java.sql.statement要求開發(fā)者付出大量的時(shí)間和精力。
在使用statement獲取jdbc訪問時(shí)所具有的一個(gè)共通的問題是輸入適當(dāng)格式的日期和時(shí)間戳:2002-02-05 20:56 或者 02/05/02 8:56 pm。
通過使用java.sql.preparedstatement,可以自動(dòng)解決這個(gè)問題。
一個(gè)preparedstatement是從java.sql.connection對(duì)象和所提供的sql字符串得到的,sql字符串中包含問號(hào)(?),這些問號(hào)標(biāo)明變量的位置,然后提供變量的值,最后執(zhí)行語句,例如:
使用preparedstatement的另一個(gè)優(yōu)點(diǎn)是字符串不是動(dòng)態(tài)創(chuàng)建的。
下面是一個(gè)動(dòng)態(tài)創(chuàng)建字符串的例子:
這允許jvm(java virtual machine)和驅(qū)動(dòng)/數(shù)據(jù)庫緩存語句和字符串并提高性能。
preparedstatement也提供數(shù)據(jù)庫無關(guān)性。當(dāng)顯示聲明的sql越少,那么潛在的sql語句的數(shù)據(jù)庫依賴性就越小。
由于preparedstatement具備很多優(yōu)點(diǎn),開發(fā)者可能通常都使用它,只有在完全是因?yàn)樾阅茉蚧蛘呤窃谝恍衧ql語句中沒有變量的時(shí)候才使用通常的statement。
為什么要始終使用PreparedStatement代替Statement?為什么要始終使用PreparedStatement代替Statement?
在JDBC應(yīng)用中,應(yīng)該始終以PreparedStatement代替Statement.也就是說,在任何時(shí)候都不要使用Statement。
基于以下的原因:
一.、代碼的可讀性和可維護(hù)性.
雖然用PreparedStatement來代替Statement會(huì)使代碼多出幾行,但這樣的代碼無論從可讀性還是可維護(hù)性上來說.都比直接用Statement的代碼高很多檔次:
對(duì)于第一種方法.別說其他人去讀你的代碼,就是你自己過一段時(shí)間再去讀,都會(huì)覺得傷心。
二、PreparedStatement盡最大可能提高性能
每一種數(shù)據(jù)庫都會(huì)盡最大努力對(duì)預(yù)編譯語句提供最大的性能優(yōu)化.因?yàn)轭A(yù)編譯語句有可能被重復(fù)調(diào)用.
所以語句在被DB的編譯器編譯后的執(zhí)行代碼被緩存下來,那么下次調(diào)用時(shí)只要是相同的預(yù)編譯語句就不需要編譯,只要將參數(shù)直接傳入編譯過的語句執(zhí)行代碼中(相當(dāng)于一個(gè)涵數(shù))就會(huì)得到執(zhí)行.這并不是說只有一個(gè)Connection中多次執(zhí)行的預(yù)編譯語句被緩存,而是對(duì)于整個(gè)DB中,只要預(yù)編譯的語句語法和緩存中匹配.那么在任何時(shí)候就可以不需要再次編譯而可以直接執(zhí)行。
而statement的語句中,即使是相同一操作,而由于每次操作的數(shù)據(jù)不同所以使整個(gè)語句相匹配的機(jī)會(huì)極小,幾乎不太可能匹配.比如:
insert into tb_name (col1,col2) values (‘11’,‘22’);
insert into tb_name (col1,col2) values (‘11’,‘23’);
即使是相同操作但因?yàn)閿?shù)據(jù)內(nèi)容不一樣,所以整個(gè)個(gè)語句本身不能匹配,沒有緩存語句的意義。事實(shí)是沒有數(shù)據(jù)庫會(huì)對(duì)普通語句編譯后的執(zhí)行代碼緩存.
當(dāng)然并不是所以預(yù)編譯語句都一定會(huì)被緩存,數(shù)據(jù)庫本身會(huì)用一種策略,比如使用頻度等因素來決定什么時(shí)候不再緩存已有的預(yù)編譯結(jié)果,以保存有更多的空間存儲(chǔ)新的預(yù)編譯語句。
三、最重要的一點(diǎn)是極大地提高了安全性.
常見的SQL注入:
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";如果我們把[’ or ‘1’ = '1]作為passwd變量傳入進(jìn)來。
select * from tb_name = '隨意' and passwd = '' or '1' = '1';因?yàn)椤?’='1’肯定成立,所以可以任何通過驗(yàn)證.
更有甚者:
把[';drop table tb_name;]作為varpasswd傳入進(jìn)來,有
有些數(shù)據(jù)庫是不會(huì)讓你成功。.
而如果你使用預(yù)編譯語句.你傳入的任何內(nèi)容就不會(huì)和原來的語句發(fā)生任何匹配的關(guān)系.只要全使用預(yù)編譯語句,你就用不著對(duì)傳入的數(shù)據(jù)做任何過慮.而如果使用普通的statement,有可能要對(duì)drop,;等做費(fèi)盡心機(jī)的判斷和過慮。
JDBC連接代碼
import java.io.FileInputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;public class JDBCUtil {static String driverClass=null;static String url=null;static String name=null;static String password=null;static {try{//1.創(chuàng)建一個(gè)屬性對(duì)象Properties properties=new Properties();InputStream is=JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");//導(dǎo)入輸入流properties.load(is);//讀取屬性driverClass= properties.getProperty("driverClass");url= properties.getProperty("url");name= properties.getProperty("name");password= properties.getProperty("password");} catch(Exception e) {e.printStackTrace();}}public static Connection getConn() {Connection conn=null;try {Class.forName(driverClass);//1.注冊(cè)驅(qū)動(dòng) DriverManager.registerDriver(new com.mysql.jdbc.Driver());// 2.建立連接 參數(shù)一:協(xié)議+訪問的數(shù)據(jù)庫 參數(shù)二: 用戶名 參數(shù)三:密碼//conn=DriverManager.getConnection("jdbc:mysql://localhost/test?useSSL=false","root","1234");conn=DriverManager.getConnection(url,name,password);} catch(Exception e) {e.printStackTrace();}return conn;} // 釋放資源public static void release(Connection conn,Statement st,ResultSet rs) {closeRs(rs);closeSt(st);closeConn(conn);}private static void closeRs(ResultSet rs) {try {if(rs!=null) {rs.close();}} catch (SQLException e) {e.printStackTrace();}finally {rs=null;}}private static void closeSt(Statement st) {try {if(st!=null) {st.close();}} catch (SQLException e) {e.printStackTrace();}finally {st=null;}}private static void closeConn(Connection conn) {try {if(conn!=null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}finally {conn=null;}}}更多樣例
class DBConnection{// 驅(qū)動(dòng)類名String driver="com.mysql.jdbc.Driver"; // URL格式,最后為數(shù)據(jù)庫名String url="jdbc:mysql://localhost:3306/javaTest?useUnicode=true&characterEncoding=UTF8"; //JavaTest為你的數(shù)據(jù)庫名稱String user="root";String password="123456";Connection coon=null;public DBConnection(){try{ // 加載驅(qū)動(dòng)程序Class.forName(driver);coon=(Connection)DriverManager.getConnection(url,user,password);if(!coon.isClosed()){System.out.println("成功連接數(shù)據(jù)庫!");}}catch (Exception e){e.printStackTrace();}}public void close(){try{this.coon.close();}catch(Exception e){e.printStackTrace();}} // 增加數(shù)據(jù)public void add(String name,int age,String gender){ // String sql="insert into usrInfo(username,gender,age) values(?,?,?)"; //向usrInfo表中插入數(shù)據(jù)String sql="insert into usrInfo(age,gender,username) values('"+age+"','"+gender+"','"+name+"')";try{PreparedStatement preStmt=(PreparedStatement)this.coon.prepareStatement(sql); // preStmt.setString(1, name); // preStmt.setInt(3, age); // preStmt.setString(2, gender); //和上面的注釋的一塊組成另外一種插入方法preStmt.executeUpdate();System.out.println("插入數(shù)據(jù)成功!");preStmt.close();}catch(Exception e){e.printStackTrace();}}// 查詢public void select(){String sql="select * from usrInfo"; //查詢usrInfo表中的信息try{Statement stmt=(Statement)this.coon.createStatement();ResultSet rs=(ResultSet)stmt.executeQuery(sql); //得到的是結(jié)果的集合System.out.println("--------------------------------");System.out.println("姓名"+"\t"+"年齡"+"\t"+"性別");System.out.println("--------------------------------");while(rs.next()){String name=rs.getString("username");int age=rs.getInt("age");String gender=rs.getString("gender");System.out.println(name+"\t"+age+"\t"+gender);}stmt.close();}catch(Exception e){e.printStackTrace();}}// 更改數(shù)據(jù)public void update(String name,int age){String sql="update usrInfo set age=? where username=?"; //推薦使用這種方式,下面的那種注釋方式不知道為啥有時(shí)候不好使 // String sql="update usrInfo set age="+age+" where username='"+name+"'";try{PreparedStatement prestmt=(PreparedStatement)this.coon.prepareStatement(sql);prestmt.setInt(1, age);prestmt.setString(2,name);prestmt.executeUpdate();// Statement stmt=(Statement)this.coon.createStatement(); // stmt.executeUpdate(sql);System.out.println("更改數(shù)據(jù)成功!");prestmt.close();}catch(Exception e){e.printStackTrace();}}// 刪除數(shù)據(jù)public void del(String name){String sql="delete from usrInfo where username=?";try{PreparedStatement prestmt=(PreparedStatement)this.coon.prepareStatement(sql);prestmt.setString(1, name);prestmt.executeUpdate();System.out.println("刪除數(shù)據(jù)成功!");prestmt.close();}catch(Exception e){e.printStackTrace();}} }在主類中對(duì)其創(chuàng)建實(shí)例,實(shí)例中構(gòu)造方法完成數(shù)據(jù)庫的連接操作,實(shí)例調(diào)用增刪改查方法進(jìn)行對(duì)數(shù)據(jù)庫信息的操作
public class mysqlTest {public static void main(String args[]){Scanner in=new Scanner(System.in);DBConnection db=new DBConnection();// 插入數(shù)據(jù)System.out.println("輸入姓名,年齡,性別:");String name=in.next();int age=in.nextInt();String gender=in.next();db.add(name, age, gender);// 查詢數(shù)據(jù)db.select();// 修改數(shù)據(jù) // String name=in.next(); // int age=in.nextInt(); // db.update(name, age);// 刪除數(shù)據(jù) // String name=in.next(); // db.del(name); // // db.close();}}總結(jié)
以上是生活随笔為你收集整理的Java连接Mysql数据库(JDBC)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吴中城市生活广场是商品房吗
- 下一篇: 乌鲁木齐阳光城银河财智中心是毛坯房还是精