JDBC高级应用

回到首页☞

这也是思想的变化,对于反复使用的东西,大家发现了一些规律,就会把它模块化,减少重复操作,提高利用率,减少耦合度,使用更加灵活。

1 DAO模式与Java Bean

DAO --数据库操作对象,Database Access Object 是JDBC下常用的模式,保存数据时它将Java Bean的属性拆分成正确的SQL语句,并保存到数据库中;读取数据时将数据从数据库中读取出来,并通过setter方法设置到Java Bean中。

这里就不一一举例了,很简单创建VO,然后和dao.java去操作数据库,返回java数据结构VO。
jsp或者servlet直接调用dao中方法即可。

这个后续框架会进一步延伸,例如mybatis,dao没有实现类,直接定义接口和xml文件即可。他采用了动态代理,工厂模式等实现了jdbc功能。

2 事务实例:转账

CRUD根据API要求操作即可,但是有个概念却是db操作的核心,事务,也是任何开发人员都会面对的头痛问题,因为各种业务分支或者未知异常,以及各种第三方接口的嵌入,怎么保持事务的原子性,完整性才是至关重要的。

所谓事务很好理解,就是一组操作是一个单元,要不全部成功,要不全部失败。A账户转钱给B账户,A钱扣除,B钱收到增加之后整体才算完成。如果A钱扣除,断网或者程序异常,B账户没有增加响应钱,放到银行系统将是灾难。
想想http协议的三次招手,四次挥手就明白了,就是为了确保传输的可靠性,虽然不是事务。

事务有两个结果:提交–Commit和回滚–Rollback。

  public static void insert(String sql) throws SQLException {
    //获取connection对象
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
      connection = JdbcUtils.getConnection();
      connection.setAutoCommit(false);
      String sqlStr = "INSERT INTO t_emp ( dept_no, ename, hiredate, sal )\n" +
          "VALUES\n" +
          "\t( 2, 'Jack', now( ), ? )";
      statement = connection.prepareStatement(sqlStr);
      for (int i = 0; i < 10; i++) {
        statement.setDouble(1, 5000 * i);
        statement.addBatch();
      }
      statement.executeBatch();

      statement.close();
      connection.close();
      connection.commit();
    } catch (ClassNotFoundException e) {
      connection.rollback();
      e.printStackTrace();
    } catch (SQLException e) {
      connection.rollback();
      e.printStackTrace();
    }
  }

我们看到JDBC操作是非常简单的

  • connection.setAutoCommit(false);
  • connection.commit();
  • connection.rollback();

3 存取二进制数据

除了能存储文本、数字、日期等数据,数据库还可以存储二进制数据。
可以把InputStream流数据作为参数设置到blob中,实事上没有这么干的。存文件可以用附件平台或者s3.
用户数据库存存二进制文件没多少意义。

4 数据源 -连接池

jdbc编程中,每次操作一次数据库,都会经过下面过程:

  • 创建Connection
  • 创建Statement对象
  • 获取ResultSet对象
  • 销毁ResultSet对象
  • 销毁Statement对象
  • 断开Connection
    即每操作一次数据库,都会创建连接、断开连接。

在实际应用中,创建与断开Connection都会消耗一定的时间、IO资源,在大量的并发访问时尤其明显。为了避免频繁的创建、断开数据库连接,工程师们提出了数据源技术-Data Source,也称作连接池–DBCP,Datebase Connection Pool。

要操作数据库时,程序并不是直接创建Connection,而是向连接池“申请”一个Connection。如果连接池中有空闲的Connection,则返回该Connection,否则创建新的Connection。使用完毕Servlet会释放该Connection。连接池会将该Connection回收并且交给其他的线程使用。

数据源一般实现自javax.sql.DataSource接口。Spring、Struts、Hibernate等框架都有自己的数据源实现,Tomcat中也内置了数据源支持。Tomcat使用Jakarta-Commons Database Connection Pool作为数据源实现,使用时只需要按照tomcat文档配置即可。

存量系统有些数据源确实配置了在了tomcat,这是违规的,因为账号密码连接串暴露了,使用数据源必须加密,不能存储可见

<Context cookie="true">

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
	<Resource 
	name="jdbc/databaseWeb" 
	auth="Container"
	type = "javax.sql.DataSource"
	maxActive="100"
	maxIdle="30"
	maxWait="10000"
	username="dev"
	password="hcgk*2020"
	driverClassName="com.mysql.jdbc.Driver"
	url="jdbc:mysql://localhost:3306/dev?serverTimezone=GMT%2B8"
	/>
	
</Context>

数据源可以配置在tomcat/conf/server.xml中,也可以配置在tomcat/conf/context.xml中。需要MYSQL驱动放到Tomcat全局lib里下面,而不能放在本web应用下面。

然后要在web程序的web.xml中配置数据源引用,这样才能在Web程序中使用该数据源。

    <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/databaseWeb</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
  public static Connection getConn() throws ClassNotFoundException, SQLException {
    Connection connections = null;
    try {
      // 实例化一个InitialContext
      Context initContext = new InitialContext();

      // 获取所有的资源
      Context envContext = (Context) initContext.lookup("java:/comp/env");

      DataSource ds = (DataSource) envContext.lookup("jdbc/databaseWeb");
      // 获取JNDI数据源
      connections = ds.getConnection();
    } catch (NamingException e) {
      e.printStackTrace();
    }

    //返回连接对象
    return connections;
  }

回到首页☞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值