中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JDBC(Java Data Base Connectivity)

發布時間:2020-08-03 11:28:07 來源:網絡 閱讀:418 作者:yayaAA 欄目:數據庫

1.JDBC快速入門

一、JDBC(Java Data Base Connectivity)

1數據庫驅動:

數據庫廠商為了方便開發人員從程序中操作數據庫而提供的一套jar,通過導入這個jar包就可以調用其中的方法操作數據庫,這樣的jar包就叫做數據庫驅動

2JDBC:

sun定義的一套標準,本質上是一大堆的操作數據庫的接口所有數據庫廠商為java設計的數據庫驅動都實現過這套接口,這樣一來,統一了不同數據庫驅動的方法,開發人員只需要學習JDBC就會使用任意數據庫驅動了

 

六個步驟實現JDBC:

//1.注冊數據庫驅動

--由于mysqlDriver類的實現中自己注冊了一次,而我們又注冊了一次,于是會導致MySql驅動被注冊兩次

--創建MySqlDriver對象時,導致了程序和具體的Mysql驅動綁死在了一起,在切換數據庫時需要改動java代碼

//DriverManager.registerDriver(new Driver());

Class.forName("com.mysql.jdbc.Driver");

//2.從客戶端發出一個和數據庫服務端的連接,url=哪臺主機哪個端口哪個數據庫

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "root");

//3.獲取傳輸器對象。連接=路;傳輸器=卡車,載數據。

Statement stat = conn.createStatement();

//4.利用傳輸器傳輸sql語句到數據庫中執行,獲取結果集對象

ResultSet rs = stat.executeQuery("select * from user");

//5.遍歷結果集獲取查詢結果

//有一個小游標一行一行的指向結果集,最后一行沒東西了返回false

//ResultSet用于代表Sql語句的執行結果。封裝執行結果采用的類似于表格的方式。ResultSet 對象維護了一個指向表格數據行的游標,初始的時候,游標在第一行之前,第一次調用ResultSet.next() 方法,游標指向第一行數據,再次調用ResultSet.next()方法,指向下一行,也就是第二行數據。

while(rs.next()){ String name = rs.getString("name");

System.out.println(name);

}

//6.關閉資源

rs.close();

stat.close();

conn.close();

 

2.JDBC細節

Connection對象,它是非常稀有的資源,用完后必須馬上釋放,如果Connection不能及時、正確的關閉,極易導致系統宕機。

為確保資源釋放代碼能運行,資源釋放代碼也一定要放在finally語句中。

 Connection conn = null;

     Statement stat = null;

     ResultSet rs = null;

     try{...... .......

      }catch (Exception e) {

           e.printStackTrace();

       }finally{

//6.關閉資源

    if(rs!=null){

        try {

            rs.close();

        } catch (SQLException e) {

            e.printStackTrace();

        }finally{

            rs = null;

        }

    }

    if(stat!=null){

        try {

            stat.close();

        } catch (SQLException e) {

            e.printStackTrace();

        }finally{

            stat = null;

        }

    }

    if(conn!=null){

        try {

            conn.close();

        } catch (SQLException e) {

            e.printStackTrace();

        }finally{

            conn = null;

        }

    }

  }


3.JDBC增刪改查

config.properties

driver=com.mysql.jdbc.Driver

url=jdbc:mysql:///day10

user=root

password=root

 

JDBCUtils.java

 public class JDBCUtils {

      private staticProperties prop = null;

          private JDBCUtils() {

            }

    static{

     try{

        prop = new Properties();

        prop.load(new                             FileReader(JDBCUtils.class.getClassLoader().getResource("config.properties").getPath()));

     }catch (Exception e) {

        e.printStackTrace();

        throw new RuntimeException(e);

     }

    }

    //連接

        public static Connection getConn() throws ClassNotFoundException, SQLException{

    // 1.注冊數據庫驅動

        Class.forName(prop.getProperty("driver"));

    // 2.獲取連接

        return DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("user"),     prop.getProperty("password"));

    //關閉

        public static void close(ResultSet rs, Statement stat,Connection conn)  {.......}

 

JDBCDemo2.java

@Test

    public void update() {

        Connection conn = null;

        Statement stat = null;

        try{

            conn = JDBCUtils.getConn();

            stat =  conn.createStatement();

            stat.executeUpdate("update user set password=999 where name='zhaoliu'");

        }catch (Exception e) {

            e.printStackTrace();

        }finally{

            JDBCUtils.close(null, stat, conn);

        }

    }

 

4.改造User案例

層與層耦合的概念,利用工廠類解耦,service如何用dao? DaoFactory.getFactory().getDao();

 public class DaoFactory {

    private static DaoFactory factory = new DaoFactory();

    private static Properties prop = null;

    static{   try{

    prop = new Properties();

    prop.load(new     FileReader(DaoFactory.class.getClassLoader().getResource("config.properties").getPath()));

    }catch (Exception e) { e.printStackTrace();

       throw new RuntimeException(e);  }  }

     

    private DaoFactory() {   }

     

    public static DaoFactory getFactory(){

        return factory; }

     

    public UserDao getDao(){

    try{

        String clazz = prop.getProperty("UserDao");

        return  (UserDao) Class.forName(clazz).newInstance();

    }catch (Exception e) {  e.printStackTrace();

        throw new RuntimeException(e); }  }  }

5.PreparedStatement防止sql注入

SQL注入***:

由于dao中執行的SQL語句是拼接出來的,其中有一部分內容是由用戶從客戶端傳入,所以當用戶傳入的數據中包含sql關鍵字時,就有可能通過這些關鍵字改變sql語句的語義,從而執行一些特殊的操作,這樣的***方式就叫做sql注入***

PreparedStatement:

利用預編譯的機制將sql語句的主干和參數分別傳輸給數據庫服務器,從而使數據庫分辨的出哪些是sql語句的主干哪些是參數,這樣一來即使參數中帶了sql的關鍵字,數據庫服務器也僅僅將他當作參數值使用,關鍵字不會起作用,從而從原理上防止了sql注入的問題

 

PreparedStatement主要有如下的三個優點:

1.可以防止sql注入

2.由于使用了預編譯機制,執行的效率要高于Statement

3.sql語句使用?形式替代參數,然后再用方法設置?的值,比起拼接字符串,代碼更加優雅.

6.大文本大二進制

數據庫中存儲的是大數據的路徑,大數據存在硬盤上,從數據庫讀大數據費時費力。

了解即可

*JDBC大數據

Text Blob

 

1.1設置Text類型

 PreparedStatement.setCharacterStream(index, reader, length);

 //注意length長度須設置,并且設置為int

 //當包過大時修改配置:[mysqld] max_allowed_packet=64M

1.2獲取Text類型

reader = resultSet. getCharacterStream(i);

2.1設置BLOB數據類型

PreparedStatement. setBinaryStream(i, inputStream, length);

2.1獲取BLOB類型

InputStream in  = resultSet.getBinaryStream(i);

InputStream in  = resultSet.getBlob(i).getBinaryStream();

 

public class BlobDemo1 {

@Test

public void findBlob(){

    Connection conn = null;

        PreparedStatement ps = null;

        ResultSet rs = null;


try{

conn = JDBCUtils.getConn();

ps = conn.prepareStatement("select * from blobdemo");

rs = ps.executeQuery();

 while(rs.next()){

    String name = rs.getString("name");

     InputStream in = rs.getBinaryStream("content");

     OutputStream out = new FileOutputStream(name);

    

    byte [] bs = new byte[1024];

    int i = 0;

    while((i=in.read(bs))!=-1){

    out.write(bs,0,i);

    }

    in.close();

    out.close();

    }

    }catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtils.close(rs, ps, conn);

    }

}

@Test

public void addBlob(){

Connection conn = null;

PreparedStatement ps = null;

ResultSet rs = null;

try{

    conn = JDBCUtils.getConn();

    ps = conn.prepareStatement("insert into blobdemo values (null,?,?)");

    ps.setString(1, "洛天依.mp3");

    File file = new File("1.mp3");

    ps.setBinaryStream(2, new FileInputStream(file),(int)file.length());

    ps.executeUpdate();

}catch (Exception e) {

    e.printStackTrace();

}finally{

    JDBCUtils.close(rs, ps, conn);

}

}

}

 

 

7.批處理機制

業務場景:當需要向數據庫發送一批SQL語句執行時,應避免向數據庫一條條的發送執行,而應采用JDBC的批處理機制,以提升執行效率。

實現批處理有兩種方式,第一種方式:

Statement.addBatch(sql) 執行批處理SQL語句

executeBatch()方法:執行批處理命令

clearBatch()方法:清除批處理命令

    Connection conn = null;

    Statement st = null;

    ResultSet rs = null;

    try {

    conn = JdbcUtil.getConnection();

    String sql1 = "insert into person(name,password,email,birthday)

    values('kkk','123','abc@sina.com','1978-08-08')";

    String sql2 = "update user set password='123456' where id=3";

    st = conn.createStatement();

    st.addBatch(sql1);  //SQL語句加入到批命令中

    st.addBatch(sql2);  //SQL語句加入到批命令中

    st.executeBatch();

    } finally{

    JdbcUtil.free(conn, st, rs);

    }


采用Statement.addBatch(sql)方式實現批處理:

優點:可以向數據庫發送多條不同的SQL語句。

缺點:

SQL語句沒有預編譯。

當向數據庫發送多條語句相同,但僅參數不同的SQL語句時,需重復寫上很多條SQL語句。

 

 

實現批處理的第二種方式:

PreparedStatement.addBatch()

conn = JdbcUtil.getConnection();

String sql = "insert into person(name,password,email,birthday) values(?,?,?,?)";

st = conn.prepareStatement(sql);

for(int i=0;i<50000;i++){

st.setString(1, "aaa" + i);

st.setString(2, "123" + i);

st.setString(3, "aaa" + i + "@sina.com");

st.setDate(4,new Date(1980, 10, 10));

 

st.addBatch();

if(i%1000==0){

st.executeBatch();

st.clearBatch();

}

}

st.executeBatch();



    采用PreparedStatement.addBatch()實現批處理

    優點:發送的是預編譯后的SQL語句,執行效率高。

    缺點:只能應用在SQL語句相同,但參數不同的批處理中。因此此種形式的批處理經常用于在同一個表中批量插入數據,或批量更新表的數據。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

洪洞县| 仙居县| 镇巴县| 土默特右旗| 邮箱| 彰化市| 涪陵区| 湖南省| 武城县| 托里县| 蒙阴县| 永寿县| 保亭| 辽阳县| 饶平县| 屏东县| 泰兴市| 远安县| 当阳市| 天全县| 涿州市| 紫云| 融水| 甘德县| 筠连县| 丹巴县| 灌阳县| 河源市| 丹江口市| 建平县| 久治县| 岑溪市| 安庆市| 和政县| 京山县| 新河县| 上犹县| 乌苏市| 萝北县| 遂平县| 鄯善县|