乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      JDBC常見(jiàn)面試題(修訂版)

       鷹兔牛熊眼 2019-08-16

      JDBC常見(jiàn)面試題

      JDBC操作數(shù)據(jù)庫(kù)的步驟 ?

      JDBC操作數(shù)據(jù)庫(kù)的步驟 ?

      1. 注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)。

      2. 建立數(shù)據(jù)庫(kù)連接。

      3. 創(chuàng)建一個(gè)Statement。

      4. 執(zhí)行SQL語(yǔ)句。

      5. 處理結(jié)果集。

      6. 關(guān)閉數(shù)據(jù)庫(kù)連接

      代碼如下:

      Connection connection = null;
      Statement statement = null;
      ResultSet resultSet = null;

      try {

          /*
          * 加載驅(qū)動(dòng)有兩種方式
          *
          * 1:會(huì)導(dǎo)致驅(qū)動(dòng)會(huì)注冊(cè)兩次,過(guò)度依賴于mysql的api,脫離的mysql的開(kāi)發(fā)包,程序則無(wú)法編譯
          * 2:驅(qū)動(dòng)只會(huì)加載一次,不需要依賴具體的驅(qū)動(dòng),靈活性高
          *
          * 我們一般都是使用第二種方式
          * */


          //1.
          //DriverManager.registerDriver(new com.mysql.jdbc.Driver());

          //2.
          Class.forName('com.mysql.jdbc.Driver');

          //獲取與數(shù)據(jù)庫(kù)連接的對(duì)象-Connetcion
          connection = DriverManager.getConnection('jdbc:mysql://localhost:3306/zhongfucheng''root''root');

          //獲取執(zhí)行sql語(yǔ)句的statement對(duì)象
          statement = connection.createStatement();

          //執(zhí)行sql語(yǔ)句,拿到結(jié)果集
          resultSet = statement.executeQuery('SELECT * FROM users');

          //遍歷結(jié)果集,得到數(shù)據(jù)
          while (resultSet.next()) {

              System.out.println(resultSet.getString(1));

              System.out.println(resultSet.getString(2));
          }

      catch (SQLException e) {
          e.printStackTrace();
      catch (ClassNotFoundException e) {
          e.printStackTrace();
      finally {

          /*
          * 關(guān)閉資源,后調(diào)用的先關(guān)閉
          *
          * 關(guān)閉之前,要判斷對(duì)象是否存在
          * */


          if (resultSet != null) {
              try {
                  resultSet.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }

          }
          if (statement != null) {
              try {
                  statement.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }

          }
          if (connection != null) {
              try {
                  connection.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }

          }

      }

      JDBC中的Statement 和PreparedStatement,CallableStatement的區(qū)別?

      JDBC中的Statement 和PreparedStatement的區(qū)別?

      區(qū)別:

      • PreparedStatement是預(yù)編譯的SQL語(yǔ)句,效率高于Statement。

      • PreparedStatement支持?操作符,相對(duì)于Statement更加靈活。

      • PreparedStatement可以防止SQL注入,安全性高于Statement。

      • CallableStatement適用于執(zhí)行存儲(chǔ)過(guò)程。

      JDBC中大數(shù)據(jù)量的分頁(yè)解決方法?

      JDBC中大數(shù)據(jù)量的分頁(yè)解決方法?

      最好的辦法是利用sql語(yǔ)句進(jìn)行分頁(yè),這樣每次查詢出的結(jié)果集中就只包含某頁(yè)的數(shù)據(jù)內(nèi)容。

      mysql語(yǔ)法:

      SELECT *
      FROM 表名
      LIMIT [START], length;

      oracle語(yǔ)法:

      SELECT *FROM (
          SELECT 列名,列名,ROWNUM rn
          FROM 表名
          WHERE ROWNUM<=(currentPage*lineSize)) temp

      WHERE temp.rn>(currentPage-1)*lineSize;

      說(shuō)說(shuō)數(shù)據(jù)庫(kù)連接池工作原理和實(shí)現(xiàn)方案?

      說(shuō)說(shuō)數(shù)據(jù)庫(kù)連接池工作原理和實(shí)現(xiàn)方案?

      工作原理:

      • JAVA EE服務(wù)器啟動(dòng)時(shí)會(huì)建立一定數(shù)量的池連接,并一直維持不少于此數(shù)目的池連接??蛻舳顺绦蛐枰B接時(shí),池驅(qū)動(dòng)程序會(huì)返回一個(gè)未使用的池連接并將其表記為忙。如果當(dāng)前沒(méi)有空閑連接,池驅(qū)動(dòng)程序就新建一定數(shù)量的連接,新建連接的數(shù)量有配置參數(shù)決定。當(dāng)使用的池連接調(diào)用完成后,池驅(qū)動(dòng)程序?qū)⒋诉B接表記為空閑,其他調(diào)用就可以使用這個(gè)連接。

      實(shí)現(xiàn)方案:連接池使用集合來(lái)進(jìn)行裝載,返回的Connection是原始Connection的代理,代理Connection的close方法,當(dāng)調(diào)用close方法時(shí),不是真正關(guān)連接,而是把它代理的Connection對(duì)象放回到連接池中,等待下一次重復(fù)利用。

      具體代碼:

      @Override
      public Connection getConnection() throws SQLException {

          if (list.size() > 0) {
              final Connection connection = list.removeFirst();

              //看看池的大小
              System.out.println(list.size());

              //返回一個(gè)動(dòng)態(tài)代理對(duì)象
              return (Connection) Proxy.newProxyInstance(Demo1.class.getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() {

                  @Override
                  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                      //如果不是調(diào)用close方法,就按照正常的來(lái)調(diào)用
                      if (!method.getName().equals('close')) {
                          method.invoke(connection, args);
                      } else {

                          //進(jìn)到這里來(lái),說(shuō)明調(diào)用的是close方法
                          list.add(connection);

                          //再看看池的大小
                          System.out.println(list.size());

                      }
                      return null;
                  }

              });
          }
          return null;
      }

      Java中如何進(jìn)行事務(wù)的處理?

      Java中如何進(jìn)行事務(wù)的處理?

      1. 事務(wù)是作為單個(gè)邏輯工作單元執(zhí)行的一系列操作。

      2. 一個(gè)邏輯工作單元必須有四個(gè)屬性,稱為原子性、一致性、隔離性和持久性 (ACID) 屬性,只有這樣才能成為一個(gè)事務(wù)

      Connection類中提供了4個(gè)事務(wù)處理方法:

      • setAutoCommit(Boolean autoCommit):設(shè)置是否自動(dòng)提交事務(wù),默認(rèn)為自動(dòng)提交,即為true,通過(guò)設(shè)置false禁止自動(dòng)提交事務(wù);

      • commit():提交事務(wù);

      • rollback():回滾事務(wù).

      • savepoint:保存點(diǎn)

        • 注意:savepoint不會(huì)結(jié)束當(dāng)前事務(wù),普通提交和回滾都會(huì)結(jié)束當(dāng)前事務(wù)的

      修改JDBC代碼質(zhì)量

      下述程序是一段簡(jiǎn)單的基于JDBC的數(shù)據(jù)庫(kù)訪問(wèn)代碼,實(shí)現(xiàn)了以下功能:從數(shù)據(jù)庫(kù)中查詢product表中的所有記錄,然后打印輸出到控制臺(tái).該代碼質(zhì)量較低,如沒(méi)有正確處理異常,連接字符串以”魔數(shù)”的形式直接存在于代碼中等,請(qǐng)用你的思路重新編寫(xiě)程序,完成相同的功能,提高代碼質(zhì)量.

      原來(lái)的代碼:

      public void printProducts(){
          Connection c = null;
          Statements s = null;
          ResultSet r = null;
          try{

      c=DriverManager.getConnection('jdbc:oracle:thin:@127.0.0.1:1521:sid','username','password');
              s=c.createStatement();
              r=s.executeQuery('select id, name, price from product');
              System.out.println('Id\tName\tPrice');
              while(r.next()){
                  int x = r.getInt('id');
                  String y = r.getString('name');
                  float z = r.getFloat('price');
                  System.out.println(x + '\t' + y + '\t' + z);
              }
          } catch(Exception e){

          }
      }

      修改后的代碼:

      class Constant{
          public static final String URL='jdbc:oracle:thin:@127.0.0.1:1521:sid';
          public static final String USERNAME='username';
          public static final String PASSWORD='password';
      }

      class DAOException extends Exception{
          public DAOException(){
              super();
          }
          public DAOException(String msg){
              super(msg);
          }
      }

      public class Test{

          public void printProducts() throws DAOException{
              Connection c = null;
              Statement s = null;
              ResultSet r = null;
              try{
                  c = DriverManager.getConnection(Constant.URL,Constant.USERNAME,Constant.PASSWORD);
                  s = c.createStatement();
                  r = s.executeQuery('select id,name,price from product');
                  System.out.println('Id\tName\tPrice');
                  while(r.next()){
                      int x = r.getInt('id');
                      String y = r.getString('name');
                      float z = r.getFloat('price');
                      System.out.println(x + '\t' + y + '\t' + z);
                  }
              } catch (SQLException e){
                  throw new DAOException('數(shù)據(jù)庫(kù)異常');
              } finally {
                  try{
                      r.close();
                      s.close();
                      c.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
          }
      }

      修改點(diǎn):

      • url、password等信息不應(yīng)該直接使用字符串“寫(xiě)死”,可以使用常量代替

      • catch中應(yīng)該回滾事務(wù),拋出RuntimeException也是回滾事務(wù)的一種方法

      • 關(guān)閉資源

      寫(xiě)出一段JDBC連接本機(jī)MySQL數(shù)據(jù)庫(kù)的代碼

      寫(xiě)出一段JDBC連接本機(jī)MySQL數(shù)據(jù)庫(kù)的代碼

      Class.forName('com.mysql.jdbc.Driver');
      String url='jdbc:mysql://localhost/test';
      Stirng user='root';
      String password='root';
      Connection conn = DriverManager.getConnection(url,user,password);

      JDBC是如何實(shí)現(xiàn)Java程序和JDBC驅(qū)動(dòng)的松耦合的?

      JDBC是如何實(shí)現(xiàn)Java程序和JDBC驅(qū)動(dòng)的松耦合的?

      通過(guò)制定接口,數(shù)據(jù)庫(kù)廠商來(lái)實(shí)現(xiàn)。我們只要通過(guò)接口調(diào)用即可。隨便看一個(gè)簡(jiǎn)單的JDBC示例,你會(huì)發(fā)現(xiàn)所有操作都是通過(guò)JDBC接口完成的,而驅(qū)動(dòng)只有在通過(guò)Class.forName反射機(jī)制來(lái)加載的時(shí)候才會(huì)出現(xiàn)。

      execute,executeQuery,executeUpdate的區(qū)別是什么?

      execute,executeQuery,executeUpdate的區(qū)別是什么?

      • Statement的execute(String query)方法用來(lái)執(zhí)行任意的SQL查詢,如果查詢的結(jié)果是一個(gè)ResultSet,這個(gè)方法就返回true。如果結(jié)果不是ResultSet,比如insert或者update查詢,它就會(huì)返回false。我們可以通過(guò)它的getResultSet方法來(lái)獲取ResultSet,或者通過(guò)getUpdateCount()方法來(lái)獲取更新的記錄條數(shù)。

      • Statement的executeQuery(String query)接口用來(lái)執(zhí)行select查詢,并且返回ResultSet。即使查詢不到記錄返回的ResultSet也不會(huì)為null。我們通常使用executeQuery來(lái)執(zhí)行查詢語(yǔ)句,這樣的話如果傳進(jìn)來(lái)的是insert或者update語(yǔ)句的話,它會(huì)拋出錯(cuò)誤信息為 “executeQuery method can not be used for update”的java.util.SQLException。

      • Statement的executeUpdate(String query)方法用來(lái)執(zhí)行insert或者update/delete(DML)語(yǔ)句,或者 什么也不返回DDL語(yǔ)句。返回值是int類型,如果是DML語(yǔ)句的話,它就是更新的條數(shù),如果是DDL的話,就返回0。

      • 只有當(dāng)你不確定是什么語(yǔ)句的時(shí)候才應(yīng)該使用execute()方法,否則應(yīng)該使用executeQuery或者executeUpdate方法。

      PreparedStatement的缺點(diǎn)是什么,怎么解決這個(gè)問(wèn)題?

      PreparedStatement的缺點(diǎn)是什么,怎么解決這個(gè)問(wèn)題?

      PreparedStatement的一個(gè)缺點(diǎn)是,我們不能直接用它來(lái)執(zhí)行in條件語(yǔ)句;需要執(zhí)行IN條件語(yǔ)句的話,下面有一些解決方案:

      • 分別進(jìn)行單條查詢——這樣做性能很差,不推薦。

      • 使用存儲(chǔ)過(guò)程——這取決于數(shù)據(jù)庫(kù)的實(shí)現(xiàn),不是所有數(shù)據(jù)庫(kù)都支持。

      • 動(dòng)態(tài)生成PreparedStatement——這是個(gè)好辦法,但是不能享受PreparedStatement的緩存帶來(lái)的好處了。

      • 在PreparedStatement查詢中使用NULL值——如果你知道輸入變量的最大個(gè)數(shù)的話,這是個(gè)不錯(cuò)的辦法,擴(kuò)展一下還可以支持無(wú)限參數(shù)。

      JDBC的臟讀是什么?哪種數(shù)據(jù)庫(kù)隔離級(jí)別能防止臟讀?

      JDBC的臟讀是什么?哪種數(shù)據(jù)庫(kù)隔離級(jí)別能防止臟讀?

      臟讀:一個(gè)事務(wù)讀取到另外一個(gè)事務(wù)未提交的數(shù)據(jù)

      例子:A向B轉(zhuǎn)賬,A執(zhí)行了轉(zhuǎn)賬語(yǔ)句,但A還沒(méi)有提交事務(wù),B讀取數(shù)據(jù),發(fā)現(xiàn)自己賬戶錢變多了!B跟A說(shuō),我已經(jīng)收到錢了。A回滾事務(wù)【rollback】,等B再查看賬戶的錢時(shí),發(fā)現(xiàn)錢并沒(méi)有多。

      下面的三種個(gè)隔離級(jí)別都可以防止:

      • Serializable【TRANSACTION_SERIALIZABLE】

      • Repeatable read【TRANSACTION_REPEATABLE_READ】

      • Read committed【TRANSACTION_READ_COMMITTED】

      什么是幻讀,哪種隔離級(jí)別可以防止幻讀?

      什么是幻讀,哪種隔離級(jí)別可以防止幻讀?

      是指在一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù),導(dǎo)致前后讀取不一致。

      只有TRANSACTION_SERIALIZABLE隔離級(jí)別才能防止產(chǎn)生幻讀。

      JDBC的DriverManager是用來(lái)做什么的?

      JDBC的DriverManager是用來(lái)做什么的?

      • JDBC的DriverManager是一個(gè)工廠類,我們通過(guò)它來(lái)創(chuàng)建數(shù)據(jù)庫(kù)連接。

      • 當(dāng)JDBC的Driver類被加載進(jìn)來(lái)時(shí),它會(huì)自己注冊(cè)到DriverManager類里面

      • 然后我們會(huì)把數(shù)據(jù)庫(kù)配置信息傳成DriverManager.getConnection()方法,DriverManager會(huì)使用注冊(cè)到它里面的驅(qū)動(dòng)來(lái)獲取數(shù)據(jù)庫(kù)連接,并返回給調(diào)用的程序。

      JDBC的ResultSet是什么?  ##

      JDBC的ResultSet是什么?

      • **在查詢數(shù)據(jù)庫(kù)后會(huì)返回一個(gè)ResultSet,它就像是查詢結(jié)果集的一張數(shù)據(jù)表。 **

      • ResultSet對(duì)象維護(hù)了一個(gè)游標(biāo),指向當(dāng)前的數(shù)據(jù)行。開(kāi)始的時(shí)候這個(gè)游標(biāo)指向的是第一行。如果調(diào)用了ResultSet的next()方法游標(biāo)會(huì)下移一行,如果沒(méi)有更多的數(shù)據(jù)了,next()方法會(huì)返回false??梢栽趂or循環(huán)中用它來(lái)遍歷數(shù)據(jù)集。

      • 默認(rèn)的ResultSet是不能更新的,游標(biāo)也只能往下移。也就是說(shuō)你只能從第一行到最后一行遍歷一遍。不過(guò)也可以創(chuàng)建可以回滾或者可更新的ResultSet

      • 當(dāng)生成ResultSet的Statement對(duì)象要關(guān)閉或者重新執(zhí)行或是獲取下一個(gè)ResultSet的時(shí)候,ResultSet對(duì)象也會(huì)自動(dòng)關(guān)閉。

      • 可以通過(guò)ResultSet的getter方法,傳入列名或者從1開(kāi)始的序號(hào)來(lái)獲取列數(shù)據(jù)。

      有哪些不同的ResultSet?

      有哪些不同的ResultSet?

      根據(jù)創(chuàng)建Statement時(shí)輸入?yún)?shù)的不同,會(huì)對(duì)應(yīng)不同類型的ResultSet。如果你看下Connection的方法,你會(huì)發(fā)現(xiàn)createStatement和prepareStatement方法重載了,以支持不同的ResultSet和并發(fā)類型。

      一共有三種ResultSet對(duì)象。

      • ResultSet.TYPE_FORWARD_ONLY:這是默認(rèn)的類型,它的游標(biāo)只能往下移。

      • ResultSet.TYPE_SCROLL_INSENSITIVE:游標(biāo)可以上下移動(dòng),一旦它創(chuàng)建后,數(shù)據(jù)庫(kù)里的數(shù)據(jù)再發(fā)生修改,對(duì)它來(lái)說(shuō)是透明的。

      • ResultSet.TYPE_SCROLL_SENSITIVE:游標(biāo)可以上下移動(dòng),如果生成后數(shù)據(jù)庫(kù)還發(fā)生了修改操作,它是能夠感知到的。

      ResultSet有兩種并發(fā)類型。

      • ResultSet.CONCUR_READ_ONLY:ResultSet是只讀的,這是默認(rèn)類型。

      • ResultSet.CONCUR_UPDATABLE:我們可以使用ResultSet的更新方法來(lái)更新里面的數(shù)據(jù)。

      JDBC的DataSource是什么,有什么好處

      JDBC的DataSource是什么,有什么好處

      DataSource即數(shù)據(jù)源,它是定義在javax.sql中的一個(gè)接口,跟DriverManager相比,它的功能要更強(qiáng)大。我們可以用它來(lái)創(chuàng)建數(shù)據(jù)庫(kù)連接,當(dāng)然驅(qū)動(dòng)的實(shí)現(xiàn)類會(huì)實(shí)際去完成這個(gè)工作。除了能創(chuàng)建連接外,它還提供了如下的特性:

      • 緩存PreparedStatement以便更快的執(zhí)行

      • 可以設(shè)置連接超時(shí)時(shí)間

      • 提供日志記錄的功能

      • ResultSet大小的最大閾值設(shè)置

      • 通過(guò)JNDI的支持,可以為servlet容器提供連接池的功能

      如何通過(guò)JDBC的DataSource和Apache Tomcat的JNDI來(lái)創(chuàng)建連接池?

      如何通過(guò)JDBC的DataSource和Apache Tomcat的JNDI來(lái)創(chuàng)建連接池?

      Tomcat服務(wù)器也給我們提供了連接池,內(nèi)部其實(shí)就是DBCP

      步驟:

      1. 在META-INF目錄下配置context.xml文件【文件內(nèi)容可以在tomcat默認(rèn)頁(yè)面的 JNDI Resources下Configure Tomcat's Resource Factory找到】

      2. 導(dǎo)入Mysql或oracle開(kāi)發(fā)包到tomcat的lib目錄下

      3. 初始化JNDI->獲取JNDI容器->檢索以XXX為名字在JNDI容器存放的連接池

      context.xml文件的配置:

      <Context>

        <Resource name='jdbc/EmployeeDB'
                  auth='Container'
                  type='javax.sql.DataSource'

                  username='root'
                  password='root'
                  driverClassName='com.mysql.jdbc.Driver'
                  url='jdbc:mysql://localhost:3306/zhongfucheng'
                  maxActive='8'
                  maxIdle='4'/>
      </Context>
      try {

          //初始化JNDI容器
          Context initCtx = new InitialContext();

          //獲取到JNDI容器
          Context envCtx = (Context) initCtx.lookup('java:comp/env');

          //掃描以jdbc/EmployeeDB名字綁定在JNDI容器下的連接池
          DataSource ds = (DataSource)
                  envCtx.lookup('jdbc/EmployeeDB');

          Connection conn = ds.getConnection();
          System.out.println(conn);


      Apache的DBCP是什么?

      Apache的DBCP是什么

      如果用DataSource來(lái)獲取連接的話,通常獲取連接的代碼和驅(qū)動(dòng)特定的DataSource是緊耦合的。另外,除了選擇DataSource的實(shí)現(xiàn)類,剩下的代碼基本都是一樣的。

      Apache的DBCP就是用來(lái)解決這些問(wèn)題的,它提供的DataSource實(shí)現(xiàn)成為了應(yīng)用程序和不同JDBC驅(qū)動(dòng)間的一個(gè)抽象層。Apache的DBCP庫(kù)依賴commons-pool庫(kù),所以要確保它們都在部署路徑下。

      使用DBCP數(shù)據(jù)源的步驟:

      1. 導(dǎo)入兩個(gè)jar包【Commons-dbcp.jar和Commons-pool.jar】

      2. 讀取配置文件

      3. 獲取BasicDataSourceFactory對(duì)象

      4. 創(chuàng)建DataSource對(duì)象

      private static DataSource dataSource = null;

      static {
          try {
              //讀取配置文件
              InputStream inputStream = Demo3.class.getClassLoader().getResourceAsStream('dbcpconfig.properties');
              Properties properties = new Properties();
              properties.load(inputStream);

              //獲取工廠對(duì)象
              BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory();
              dataSource = basicDataSourceFactory.createDataSource(properties);

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

      public static Connection getConnection() throws SQLException {
          return dataSource.getConnection();

      }

      //這里釋放資源不是把數(shù)據(jù)庫(kù)的物理連接釋放了,是把連接歸還給連接池【連接池的Connection內(nèi)部自己做好了】
      public static void release(Connection conn, Statement st, ResultSet rs) {

          if (rs != null) {
              try {
                  rs.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }
              rs = null;
          }
          if (st != null) {
              try {
                  st.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }

          }
          if (conn != null) {
              try {
                  conn.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }

          }


      }

      常見(jiàn)的JDBC異常有哪些?

      常見(jiàn)的JDBC異常有哪些?

      有以下這些:

      • java.sql.SQLException——這是JDBC異常的基類。

      • java.sql.BatchUpdateException——當(dāng)批處理操作執(zhí)行失敗的時(shí)候可能會(huì)拋出這個(gè)異常。這取決于具體的JDBC驅(qū)動(dòng)的實(shí)現(xiàn),它也可能直接拋出基類異常java.sql.SQLException。

      • java.sql.SQLWarning——SQL操作出現(xiàn)的警告信息。

      • java.sql.DataTruncation——字段值由于某些非正常原因被截?cái)嗔耍ú皇且驗(yàn)槌^(guò)對(duì)應(yīng)字段類型的長(zhǎng)度限制)。

      JDBC中存在哪些不同類型的鎖?

      JDBC中存在哪些不同類型的鎖?

      從廣義上講,有兩種鎖機(jī)制來(lái)防止多個(gè)用戶同時(shí)操作引起的數(shù)據(jù)損壞。

      • 樂(lè)觀鎖——只有當(dāng)更新數(shù)據(jù)的時(shí)候才會(huì)鎖定記錄。

      • 悲觀鎖——從查詢到更新和提交整個(gè)過(guò)程都會(huì)對(duì)數(shù)據(jù)記錄進(jìn)行加鎖。

      java.util.Date和java.sql.Date有什么區(qū)別?

      java.util.Date和java.sql.Date有什么區(qū)別?

      java.util.Date包含日期和時(shí)間,而java.sql.Date只包含日期信息,而沒(méi)有具體的時(shí)間信息。如果你想把時(shí)間信息存儲(chǔ)在數(shù)據(jù)庫(kù)里,可以考慮使用Timestamp或者DateTime字段

      SQLWarning是什么,在程序中如何獲取SQLWarning?

      SQLWarning是什么,在程序中如何獲取SQLWarning?

      SQLWarning是SQLException的子類,通過(guò)Connection, Statement, Result的getWarnings方法都可以獲取到它。 SQLWarning不會(huì)中斷查詢語(yǔ)句的執(zhí)行,只是用來(lái)提示用戶存在相關(guān)的警告信息。

      如果java.sql.SQLException: No suitable driver found該怎么辦?

      如果java.sql.SQLException: No suitable driver found該怎么辦?

      如果你的SQL URL串格式不正確的話,就會(huì)拋出這樣的異常。不管是使用DriverManager還是JNDI數(shù)據(jù)源來(lái)創(chuàng)建連接都有可能拋出這種異常。它的異常??雌饋?lái)會(huì)像下面這樣。

      org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class 'com.mysql.jdbc.Driverfor connect URL ''jdbc:mysql://localhost:3306/UserDB'
          at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452)
          at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
          at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
      java.sql.SQLExceptionNo suitable driver found for 'jdbc:mysql://localhost:3306/UserDB
          at java.sql.DriverManager.getConnection(DriverManager.java:604)
          at java.sql.DriverManager.getConnection(DriverManager.java:221)
          at com.journaldev.jdbc.DBConnection.getConnection(DBConnection.java:24)
          at com.journaldev.jdbc.DBConnectionTest.main(DBConnectionTest.java:15)
      Exception in thread 'mainjava.lang.NullPointerException
          at com.journaldev.jdbc.DBConnectionTest.main(DBConnectionTest.java:16)

      解決這類問(wèn)題的方法就是,檢查下日志文件,像上面的這個(gè)日志中,URL串是'jdbc:mysql://localhost:3306/UserDB,只要把它改成jdbc:mysql://localhost:3306/UserDB就好了。

      JDBC的RowSet是什么,有哪些不同的RowSet?

      JDBC的RowSet是什么,有哪些不同的RowSet?

      RowSet用于存儲(chǔ)查詢的數(shù)據(jù)結(jié)果,和ResultSet相比,它更具靈活性。RowSet繼承自ResultSet,因此ResultSet能干的,它們也能,而ResultSet做不到的,它們還是可以。RowSet接口定義在javax.sql包里。

      RowSet提供的額外的特性有:

      • 提供了Java Bean的功能,可以通過(guò)settter和getter方法來(lái)設(shè)置和獲取屬性。RowSet使用了JavaBean的事件驅(qū)動(dòng)模型,它可以給注冊(cè)的組件發(fā)送事件通知,比如游標(biāo)的移動(dòng),行的增刪改,以及RowSet內(nèi)容的修改等。

      • RowSet對(duì)象默認(rèn)是可滾動(dòng),可更新的,因此如果數(shù)據(jù)庫(kù)系統(tǒng)不支持ResultSet實(shí)現(xiàn)類似的功能,可以使用RowSet來(lái)實(shí)現(xiàn)。

      RowSet分為兩大類:

      • A. 連接型RowSet——這類對(duì)象與數(shù)據(jù)庫(kù)進(jìn)行連接,和ResultSet很類似。JDBC接口只提供了一種連接型RowSet,javax.sql.rowset.JdbcRowSet,它的標(biāo)準(zhǔn)實(shí)現(xiàn)是com.sun.rowset.JdbcRowSetImpl。

      • B. 離線型RowSet——這類對(duì)象不需要和數(shù)據(jù)庫(kù)進(jìn)行連接,因此它們更輕量級(jí),更容易序列化。它們適用于在網(wǎng)絡(luò)間傳遞數(shù)據(jù)。

        • CachedRowSet——可以通過(guò)他們獲取連接,執(zhí)行查詢并讀取ResultSet的數(shù)據(jù)到RowSet里。我們可以在離線時(shí)對(duì)數(shù)據(jù)進(jìn)行維護(hù)和更新,然后重新連接到數(shù)據(jù)庫(kù)里,并回寫(xiě)改動(dòng)的數(shù)據(jù)。

        • WebRowSet繼承自CachedRowSet——他可以讀寫(xiě)XML文檔。

        • JoinRowSet繼承自WebRowSet——它不用連接數(shù)據(jù)庫(kù)就可以執(zhí)行SQL的join操作。

        • FilteredRowSet繼承自WebRowSet——我們可以用它來(lái)設(shè)置過(guò)濾規(guī)則,這樣只有選中的數(shù)據(jù)才可見(jiàn)。

        • 有四種不同的離線型RowSet的實(shí)現(xiàn)。

       什么是JDBC的最佳實(shí)踐?

       什么是JDBC的最佳實(shí)踐?

      • 數(shù)據(jù)庫(kù)資源是非常昂貴的,用完了應(yīng)該盡快關(guān)閉它。Connection, Statement, ResultSet等JDBC對(duì)象都有close方法,調(diào)用它就好了。

      • 養(yǎng)成在代碼中顯式關(guān)閉掉ResultSet,Statement,Connection的習(xí)慣,如果你用的是連接池的話,連接用完后會(huì)放回池里,但是沒(méi)有關(guān)閉的ResultSet和Statement就會(huì)造成資源泄漏了。

      • 在finally塊中關(guān)閉資源,保證即便出了異常也能正常關(guān)閉。

      • 大量類似的查詢應(yīng)當(dāng)使用批處理完成。

      • 盡量使用PreparedStatement而不是Statement,以避免SQL注入,同時(shí)還能通過(guò)預(yù)編譯和緩存機(jī)制提升執(zhí)行的效率。

      • 如果你要將大量數(shù)據(jù)讀入到ResultSet中,應(yīng)該合理的設(shè)置fetchSize以便提升性能

      • 你用的數(shù)據(jù)庫(kù)可能沒(méi)有支持所有的隔離級(jí)別,用之前先仔細(xì)確認(rèn)下。

      • 數(shù)據(jù)庫(kù)隔離級(jí)別越高性能越差,確保你的數(shù)據(jù)庫(kù)連接設(shè)置的隔離級(jí)別是最優(yōu)的。

      • 如果在WEB程序中創(chuàng)建數(shù)據(jù)庫(kù)連接,最好通過(guò)JNDI使用JDBC的數(shù)據(jù)源,這樣可以對(duì)連接進(jìn)行重用。

      • 如果你需要長(zhǎng)時(shí)間對(duì)ResultSet進(jìn)行操作的話,盡量使用離線的RowSet。

      ————  e n d ————

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多