zoukankan      html  css  js  c++  java
  • JDBC(二)

      三层架构的一些基本报结构如下:

         domain包:下面是一些实体bean,属性为private,提供属性相对应的set和get方法。一般对应于数据库中的一张数据表,属性对应于数据表中的列。

          dao包,数据访问层的接口,控制实体bean的CRUD操作和其他的一些业务逻辑,存储的都是接口。

          dao.impl包,数据访问层接口的实现。

          service包,业务逻辑层,调用数据访问层。

          JDBC属于数据访问层的技术,JDBC的CRUD出现异常时不能仅是try,catch,否则上层的业务逻辑层不知道已经出现了错误,所以在CRUD出错时还需要向上抛出异常。

         JDBC的SQLException是编译时异常,必须要进行处理,而且和JDBC进行了耦合,Hibernate抛出的就不是SQLException。所以向上抛出的不应是SQLException,而应该是运行时异常(RuntimeException)。

    public static void updateObject(String sql, String[] params) throws DaoRuntimeException {
      Connection conn = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
       conn = DBConnectionManager.getConnection();   
       pstmt = conn.prepareStatement(sql);
       
       for (int i = 0; params != null && i < params.length; i++) {
        pstmt.setString(i + 1, params[i]);
       }
       rs = pstmt.executeUpdate();
       
      } catch (Exception e) {
       logger.info("Execute sql : " + sql + " fail!!!");
       throw new DaoRuntimeException(e.getMessage(),e);
      } finally {
       DBConnectionManager.free(conn, pstmt, rs);
      }
       

         事务的四个特性ACID:

         原子性:automicity,操作要么全执行,要么全部执行,不能执行一部分。

         一致性:consistency,数据库数据完整性约束。

         隔离性:isolcation,一个事务对另一个事务不会产生影响。

         持久性:durablity,事务的结果可以被持久的保留下来。

         JDBC对事务的主要操作:

         connection.setAutoCommit(false)//打开事务

      //多条CRUD操作

         connection.commit()//提交事务

         connection.rollback()//回滚事务

         还可以回滚至特定的保存点,

         SavePoint sp = conection.setSavePoint();

         connection.rollback(sp);

      

         事务的操作如果跨越了多个数据源,还需要用到JTA,使用支持JTA的容器如weblogic,websphere提供的JNDI服务去完成。

         

         脏读:一个事务读到了另一个事务未提交的数据。

         不可重复读:一个事务重复读取的操作读到的数据不一致,是其他的事务修改了所读取的数据所导致的。

         幻读:一个事务读到了另一个事务已提交的数据。

         数据库的隔离级别又分为:读未提交,读已提交,可重复读,可串行化

         读未提交可能产生:脏读,不可重复读,幻读

         读已提交可能产生:不可重复读,幻读

         可重复读可能产生:幻读,可以用快照技术实现,存储读取的数据。

         可串行化不会有脏读,不可重复读,幻读

         不同数据库的隔离级别是不同的,MySQL默认的是可重复读。隔离级别越高,占用资源越多,数据正确性越高。

         connection.setTransactionIsocation(Connection.TRANSACTION_REPEATABLE_READ)。不设置时就是用数据库默认的隔离级别。

         

         JDBC调用存储过程。

         一个简单的存储过程如下:

         demiliter |

         drop  procedure if exists addUser |

         create procedure addUser(in pname varchar(40),in birthday date,out pid int)

             begin

             insert into user(name,birthday) values (pname,birthday);

                    select last_insert_id into pid;

             end |

         demilter;

         

         String sql = "{ call addUser(?,?,?)}";

         CallableStatement cs = conn.prepareCall(sql);

         cs.registerOutParameter(3,Type.Integer);

         cs.setString(1,"new user");

         cs.setDate(2,new java.sql.Date(System.currentTimeMills()));

         cs.executeUpdate();

         int id = cs.get(3);

         批量处理,大量的SQL语句时需要注意:

         PreparedStatement.executeBatch();,下面是执行1000条SQL的例子。还需要考虑到一次发送的SQL语句集合包的大小,不能一次发送的数量太大,会导致内存溢出。

         大量的插入语句insert into () values()()()效率很高。  

    public static void updateObject(String sql, String[] params) throws DaoRuntimeException {
      Connection conn = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
       conn = DBConnectionManager.getConnection();   
       pstmt = conn.prepareStatement(sql);
          
    for(int round =0;round <1000;round ++){
    for (int i = 0; params != null && i < params.length; i++) { pstmt.setString(i + 1, params[i]); }
    psmt.addBatch();//statment对应的是psmt.addBatch(String sql)
    } rs = psmt.executeBatch();//rs
    = pstmt.executeUpdate(); } catch (Exception e) { logger.info("Execute sql : " + sql + " fail!!!"); throw new DaoRuntimeException(e.getMessage(),e); } finally { DBConnectionManager.free(conn, pstmt, rs); }

         可滚动的结果集,ResultSet即可以实现rs.next(),也可以实现rs.privious()向前滚动,绝对定位rs.absolute(4)到第4条记录。

         st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

         可滚动结果集可用于MySQL的分页,从第100条记录开始取50条记录

         rs.absolute(100);

         int i=0;

         while(rs,next() && i<50){

                rs.getObject("name");

         }

         MySQL的语法也直接就可以支持分页select id,name from user limit 100.50;

         

         

         

  • 相关阅读:
    世界企业家:创业者需知的8条创业逻辑
    比尔·盖茨的“机会”观——不追求机会,才会有机会
    我爱思佳(帮别人名字作诗)
    唐艺铭(帮别人名字作诗)
    我爱思佳(帮别人名字再作诗)
    优秀是一种习惯:智者五句话足以改变你的人生
    别了,我的情人
    李丽萍(帮别人名字作诗)
    Know GCS AND GES structure size in shared pool
    测试Exadata单个cell失败
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/4063857.html
Copyright © 2011-2022 走看看