JDBC

ODBC(Open Database Connectivity,开放的数据库连接)
JDBC(Java Database Connectivity,Java数据库连接)

JDBC以Java类库来取代数据库厂商的专有API,客户端只需要调用JDBC API,而由JDBC的实现层(即JDBC驱动程序)去处理与数据库的通信,从而让我们的应用程序不再受限于具体的数据库产品。

JDBC驱动程序可以分为4类,分别是:
●JDBC-ODBC桥
●部分本地API,部分Java驱动程序
●JDBC网络纯Java驱动程序

●本地协议纯Java驱动程序




















Bea公司的WebLogic和IBM的Websphere







Oracle Thin JDBC Driver  效率最高


JDBC API包含在JDK中,被分为两个包:java.sql和javax.sql。java.sql包定义了访问数据库的接口和类
JDBC访问数据库统一步骤:
1.调用Class类的forName()方法;       
    Class.forname("com.mircrosoft.jdbc.sqlserver.SQLServerDriver");
2.调用DriverManager类的getConnection()方法;
    Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1443;databasename=pubs","username","password");
3.调用Connection对象的createStatement()方法;
    Statement stmt = conn.createStatement();
4.调用Statement对象的executeQuery()方法得到ResultSet对象。
    ResultSet rs = stmt.executeQuery("select * from jobs*");
加载并注册数据库驱动
1.Driver接口
    com.microsoft.jdbc.sqlserver.SQLServerDriver
    com.jdbc.driver.OracleDriver
    com.mysql.jdbc.Driver
2.加载与注册JDBC驱动
   加载JDBC驱动是调用Class类的静态方法forName(),向其传递要加载的JDBC驱动的类名。在运行时,类加载器从CLASSPATH环境变量中定位和加载JDBC驱动类。
    DriverManager类是驱动程序管理器,负责管理驱动程序,这个类中所有的方法都是静态的。在DriverManager类中提供了registerDriver()方法来注册驱动程序类的实例。Driver接口的驱动程序类包含了静态代码块,会调用DriverManager.registerDriver()方法来注册自身的一个实例。
建立数据库的连接
调用DriverManager类的getConnection()方法建立到数据库的连接,返回一个Connection对象。
JDBC URL的语法:jdbc:subprotocol:subname
                协议:子协议(标识一个数据库驱动程序):
SQL Server2000--jdbc:mircrosoft:sqlserver://localhost:1433;databasename=pubs
Oracle--jdbc:oracle:thin:@localhost:1521:ORCL
MySQL--jdbc:mysql://localhost:3306/databasename
JDBC-ODBC--sun.jdbc.odbc.JdbcOdbcDriver  jdbc:odbc:datasource_name
访问数据库
1.Statement
调用Connection对象的createStatement()方法创建一个Statement对象,用于执行静态的SQL语句,返回执行的结果。
2.ResultSet
调用Statement对象的executeQuery()方法创建ResultSet对象,以逻辑表格的形式封装了执行数据库操作的结果集。ResultSet对象维护了一个指向当前数据行的游标,可通过ResultSet对象的next()方法移动游标到下一行。
3.PreparedStatement
PreparedStatement接口从Statement接口继承而来,它的对象表示一条预编译过的SQL语句;通过调用Connection对象的preparedStatement()方法来得到PreparedStatement对象;PreparedStatement对象所代表的SQL语句中的参数用问号(?)来表示,调用PreparedStatement对象的setXXX()方法来设置这些参数;setXXX()方法有两个参数,第一个参数要设置的是参数的索引(从1开始),第二个参数要设置的是参数的值。
4.CallableStatement
用来执行存储过程;CallableStatement接口从PreparedStatement接口继承而来,通过调用Connection对象的prepareCall()方法来得到CallableStatement对象。在执行存储过程之前,凡是存储过程中类型为OUT的参数必须被注册,通过CallableStatement对象的registerOutParameter()方法来完成。
    CallableStatement cstmt = conn.prepareCall("call p_changsal(?,?)");
    cstmt.registerOutParameter(2,java.sql.Types.INTEGER);
    cstmt.setInt(1,7369);
    cstmt.execute();
    int sal = cstmt.getInt(2);
5.元数据
在SQL中,用于描述数据库或者它的各个组成部分之一的数据称为元数据,以便和存放在数据库中的实际数据区分 。
在java.sql包中,提供了一个接口ResultSetMetaData ,用来获取描述数据库表结构的元数据。可以调用ResultSet对象的getMetaData()方法来得到ResultSetMetaData对象。
在java.sql包中,还提供了DatabaseMetaData接口和ParameterMetaData接口;DatabaseMetaData对象用于获取数据库的信息,ParameterMetaData对象用于得到PreparedStatement对象中的参数的类型和属性信息;可以通过调用Connection对象的getMetaData()方法得到DatabaseMetaData对象,调用PreparedStatement对象的getParameterMetaData()方法得到ParameterMetaData对象。
事务处理
事务处理保证所有的事务都作为一个工作单元来执行,即使出现了硬件故障或者系统失灵,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的操作被提交(commit),要么整个事件回滚(rollback)到最初状态。
可滚动和可更新的结果集
1.可滚动的结果集
Statement createStatement(int resultSetType,int resultSetConcurrency) throws SQLException
resultSetType用于指定结果集的类型,有3个取值:
●ResultSet.TYPE_FORWARD_ONLY
  结果集只能向前移动,这是调用不带参数的createStatement()方法的默认类型
●ResultSet.TYPE_SCROLL_INSENSITIVE
  结果集可以滚动,但是对数据库的变化不敏感
ResultSet.TYPE_SCROLL_SENSITIVE
  结果集可以滚动,并且对数据库的变化敏感。例如,在程序中通过查询返回了10行数据,如果另一个程序删除了其中的2行,那么这个结果集中就只有8行数据了。

resultSetConcurrency用于指定并发性类型,有2个取值:
●ResultSet.CONCUR_READ_ONLY
  结果集不能用于更新数据库,这是调用不带参数的createStatement()方法的默认类型
●ResultSet.CONCUR_UPDATABLE
  结果集可以用于更新数据库。使用这个选项,就可以在结果集中插入、删除和更新数据行,而这种改变将反映到数据库中。
2.可更新的结果集
可以在创建Statement对象时,指定ResultSet.CONCUR_UPDATABLE类型,这样创建的结果集就是可更新的结果集。
(1)更新一行
  在ResultSet接口中提供了类似于getXXX()方法的updateXXX()方法,用于更新结果集中当前行的数据。updateXXX()方法可以接受列的索引或列的名字作为参数。
  updateRow() cancelRowUpdates()放弃对当前行的修改,必须在updateRow()方法前调用,rowUpdate()判断当前行是否被更新
(2)插入一行
  首先调用moveToInsertRow()方法移动游标到插入行,插入行是一个与可更新的结果集相联系的特殊的缓存行;接下来调用updateXXX()方法,设置行中的数据;最后在行设置完后,调用insertRow()方法,将新行传递给数据库,从而在数据库中真正插入一行数据。
(3)删除一行
  deleteRow(),当游标指向插入行的时候,不能调用这个方法,一个被删除的行可能在结果集中留下一个空的位置,可以调用rowDeleted()方法来判断一行是否被删除
  可更新的结果集的使用必须满足3个条件
●只能是针对数据库中单表的查询
●查询语句中不能包含任何的join操作
●查询操作的表中必须 有主键,而且在查询的结果集中必须包含作为主键的字段
  在结果集上执行插入操作,SQL查询还应该满足2个条件
●查询操作必须选择数据库表中所有不能为空的列
●查询操作必须选择所有没有默认值的列
JDBC数据源和连接池
javax.sql包中定义了DataSource接口,通过向一个JNDI(Java Naming and Directory)服务器查询来得到DataSource对象,然后调用DataSource对象的getConnection()方法来建立数据库的连接。
javax.naming.Context ctx = new javax.naming.InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup("java:ccomp.env/jdbc/bookstore");
java.sql.Connection conn = ds.getConnection();
javax.naming.Context接口表示一个命名上下文,在这个接口中,定义了将对象和名字绑定,以及通过名字查询对象的方法。查询一个命名的对象,是通过调用Context接口中的lookup()方法。
javax.naming.InitialContext是Context接口的实现类
javax.sql.DataSource接口有3种类型的实现:
●基本的实现——产生一个标准的链接对象
●连接池实现——产生一个自动参与到连接池中的链接对象,这种实现需要和一个中间层连接池管理器一起工作
●分布式事务实现——产生一个用于分布是食物的链接对象,这种链接对象几乎总是参与到连接池中,这种实现需要和一个中间层事务管理器和连接池管理器一起工作
连接池技术预先建立多个数据库连接对象,然后将链接对象保存到连接池中,当客户请求到来时,从池中取出一个链接对象为客户服务,当请求完成后,客户程序调用close()方法,将连接对象放回池中。
在普通的数据库访问程序中,客户程序得到的连接对象是物理连接,调用连接对象的close()方法将关闭连接,而采用连接池技术,客户程序得到的链接对象时连接池中物理连接的一个句柄,调用连接对象的close()方法,物理连接并没有关闭,数据源的实现只是删除了客户程序中的链接对象和池中的链接对象之间的联系。
配置server.xml文件Context节点中的Resource节点
MySQL对中文的处理
指定系统变量
mysqld --character_set_server=gbk
或者
mysqld-nt --character_set_server=gbk


预编译

SQL语句尽量使用预编译方式进行参数绑定,硬解析(+)连接符方式效率比较慢
DataParameterCollection dpc = new DataParameterCollection();
    dpc.add(new DataParameter(jgdxId,2005));

事务
BusinessInvokeResult result = new BusinessInvokeResult();
  IDataAccessService idas = this.getDataAccessService();
  try {
   // 开启事务
   idas.beginTrans();
   // 列表OBJ_ID
   String objId = ( String ) context.get("OBJID");
   // 状态
   String state = updateStatus(objId);
   DataParameterCollection dpc = new DataParameterCollection();
   dpc.add(new DataParameter(state,2005));
   dpc.add(new DataParameter(objId,2005));
   StringBuffer sb = new StringBuffer("UPDATE MW_APP.ZXJC_YWJG_JGDX SET ISSHOW = ? WHERE OBJ_ID = ?");
   idas.executeNonQuery(sb.toString(),dpc);
   result.setResultValue("success");
   idas.commit();
   result.setSuccessful(true);
  } catch (Exception e) {
   idas.rollback();
   result.setResultValue("error");
   result.setSuccessful(false);
   result.setResultHint(e.getMessage());
   e.printStackTrace();
  }
  return result;



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值