posts - 0,  comments - 1,  trackbacks - 0
 

一.JDBC原理概述

1JDBC是一套协议,是JAVA开发人员和数据库厂商达成的协议,也就是由Sun定义一组接口,由数据库厂商来实现,并规定了JAVA开发人员访问数据库所使用的方法的调用规范。

       2JDBC的实现是由数据库厂商提供,以驱动程序形式提供。

       3JDBC在使用前要先加载驱动。

          JDBC对于使用者要有一致性,对不同的数据库其使用方法都是相同的。

          driver开发必须要实现Driver接口。

       四种数据库驱动的实现方式

       JDBC-ODBC桥接式

       JDBC网络驱动,这种方式是通过中间服务器的协议转换来实现的

       JDBC+本地驱动,这种方式的安全性比较差

       JDBC驱动,由数据库厂商实现。

二.JDBCAPI

       java.sql包和javax.sql

       1.Driver接口 代表驱动程序

2.DriverManager类(驱动管理器),它可以创建连接,它本身就是一个创建Connection的工厂(Factory)

       3.Connection接口,代表数据库连接,会根据不同的驱动产生不同的连接

       4.Statement接口,执行sql语句

       5. PreparedStatement接口执行sql语句(预编译)

       6.CallableStatement接口 发送sql语句

       7.ResultSet接口(结果集),是用来接收select语句返回的查寻结果的。其实质类似

于集合。

       8.DatabaseMetaData 数据库元数据

       9.ResultSetMetaData   结果集元数据

10.Types:特殊的类。只包含静态的常量,代表JDBC类型。JDBC类型是标准SQL类型的子集

三、事务

       1).原子性,一致性,隔离性,持久性

事务是一个数据操作单元,能够保证在该单元内执行的多个SQL语句,或者一起成

,或者一起失败.

       2).事务的并发控制:

           (dirty)脏读:一个事务能读到另外一个事务没有提交的数据

           不可重复读:在同一个事务的两次查询中,发现值不同,叫做不可重复读.这是因为在

两次查询之间,另外一个事务修改了数据并提交了.

           (phantom)幻影读:在同一个事务的两次查询中,发现记录的数目不同,叫做幻影读.

这是因为在两次查询之间,另外一个事务增加或者删除了数据并提交了.

       3).隔离级别

          Connection 类中的五个静态常量

          A.不使用事务 TRANSACTION_NONE

       B.允许脏读    TRANSACTION_READ_UNCOMMITTED

          C.不允许脏读 TRANSACTION_READ_COMMITTED

          D.防止不可重复读,脏读 TRANSACTION_REPEATABLE_READ

          F.事务串行化    TRANSACTION_SERIALIZABLE

四、JDBC编程步骤

       1,注册加载一个driver驱动

       2,创建数据库连接(Connection

       3,创建一个Statement(发送sql

       4,执行sql语句

       5,处理sql结果ResultSetselect语句)

       6,关闭sql结果ResultSet (如果有)

       7,关闭Statement

       8,关闭连接Connection

       注意:678两个步骤必须要做的,因为这些资源是不会自动释放的,必须要自己关闭

       1,注册加载驱动driver,也就是强制类加载

              一般来说我们使用方法1

              方法1 Class.forName(Driver包名.Driver类名)

                     eg:加载oracle

                     Class.forName("oracle.jdbc.driver.OracleDriver");

              方法2Driver d=new oracle.jdbc.driver.OracleDriver();

                     DriverManager.registerDriver(d);

              方法3java -Djdbc.drivers=驱动全名 类名

              OracleDriver的全名:oracle.jdbc.driver.OracleDriver

              mysqlDriver的全名:com.mysql.jdbc.Driver org.gjt.mm.mysql.Driver

              SQLServerDriver的全名:com.microsoft.jdbc.sqlserver.SQLServerDriver

       2,创建连接

              DriverManager.getConnection(String url,String username,String

password);

              Connection连接是通过DriverManager的静态方法getConnection(.....)来得到

的,这个方法的实质是把参数传到实际的Driver中的connect()方法中来获得数

据库连接的。

       OracleURL值是由连接数据库的协议和数据库的IP地址及端口号还有要连接的

库名(DatebaseName

              Oracle URL的格式

              jdbc:oracle:thin:@数据库IP地址:端口号:数据库名(sid)

              如:oracle所在服务器地址为192.168.0.254,而端口号为默认的1521,数据

库名为tarena,那么URL就应写成

              jdbc:oracle:thin:@192.168.0.254:1521:tarena           

              MySql URL的格式

              jdbc:mysql://数据库IP地址:端口号/数据库名

              例: jdbc:mysql://localhost:3306/test

              访问本机时IP地址用localhost127.0.0.1都可以             

              SQLServer URL的写法

              例:jdbc:microsoft:sqlserver://localhost:1433

       3、创建Statement

              使用Connection对象获得一个Statement

              Statement中的方法:

1)executeQuery(String sql) 方法可以使用select语句查询,并且返回一个结

果集ResultSet,通过遍历这个ResultSet,可以获得select语句的查寻结果。

              ResultSet rs = stmt.executeQuery(“select * from person”);

              2executeUpdate(String sql) 方法用于执行DDLDML语句,可以update

delete操作。

              此方法返回一个int类型的值,表示此条sql语句影响的记录条数

              Int count = stmt.executeUpdate(“delete from person where pid=1”);

              Int count = stmt.executeUpdate(“update person set name=’jack’,age=’20’

where pid=1”);

              3execute(String sql) 这个方法的返回值是boolean类型

              如果返回true就表示sql是一个select语句,然后通过getResultSet()获得结果

              如果返回false sql就是DML语句或者是DDL语句,即没有结果集,

              然后通过getUpdateCount()方法 获得更新的记录条数。

              在不能明确传入sql是何种类型的操作时使用此方法。

              if (stmt.execute(sql)) {

                     ResultSet rs = stmt.getResultSet();

              } else {

                     int count = stmt.getUpdateCount();

              }

              4getUpdateCount() 返回更新的记录条数

       4.处理结果集ResultSet(结果集里存储的是二维的结构,相当于一张表)

              ResultSet rs = stmt.executeQuery(“select pid, name, age from person”);

              Person person = null;

              while(rs.next) {

                     person = new Person();

                     person.setPid(rs.getInt(1));//jdbc下标是从1开始

                     person.setName(rs.getString(“name”));//也可使用列名来得到数据

                     person.setAge(rs.getInt(3));

              }

              1) next()方法会操作一个游标从第一条记录的前边开始读取,直到最后一条记录。

                     由于结果集返回来之后游标的位置在第一条记录的前面,所以调用next()

法不会丢失数据。

              2) getXXX(int index)其中XXX代表数据库中存储的数据类型相对应的java数据

类型,

                     此方法可以根据指定顺序获得字段值,注:顺序是从1开始的。

              eg: int cid = rs.getInt(1);

                     String cname = rs.getString(2);

              3) getXXX(String columnName):此方法可以根据指定字段的名字获取字段的值

                     eg: int cid = rs.getInt("cid");

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

              4updateXXX() XXX代表的是相应的类型,无返回值

              5) isXXXX() XXXX代表的是游标的位置FirstLast。。。返回布尔值

       5.资源的关闭顺序:

              要按先ResultSet结果集,然后Statement,最后Connection的顺序关闭资源。

              因为StatementResultSet是需要连接是才可以使用的,所以在使用结束之后

有可能起他的Statement还需要连接,

              所以不能现关闭Connection

              //关闭结果集

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

              //关闭Statement

              if (stmt != null) try { stmt.close()} catch (SQLException e) {

e.printStackTrace();}

              //关闭链接

              if (conn != null) try { conn.close()} catch (SQLException e) {

e.printStackTrace();}

       6.PreparedStatement(预编译的Statement)

              PreparedStatement 用来执行同构的SQL,它的创建方式:

              PreparedStatement pstmt = con.prepareStatement("insert into clazz values(?,?)");

              可以使用参数替代sql语句中的某些参数使用"?"代替,他先将带参数的sql语句发送到数据库,

              进行编译,然后PreparedStatement会将参数发送给数据库。

              在使用PreparedStatement时,设置相应参数要指明参数的位置和类型,以及给出参数值

              根据不同的参数类型使用不同的setXXX(参数的位置,参数值)来设置参数

              结构跟此方法类似:setInt(int parameterIndex, int x)

              pstmt.setInt(1,i);

              pstmt.setString(2,"xxx"+i)

       7.CallableStatement

              CallableStatement是可以用非sql语句来访问数据库,他是通过调用存储过程(PL/SQL)来访问数据

库的。

              可以直接使用连接来调用 prepareCall(...)方法,来执行这个存储过程,"..."是存储过程的名字。

       8.SQLException是检查异常必须处理,要么throws ,要么try{}catch(){}

          getErrorCode()可以获得错误码,可以对错误进行查询。

五、元数据

       元数据就是描述数据库或其组成部分的数据。(区别于存储在数据库中的实际数据)

       它用来辅助我们更好的处理数据库的用户数据[通俗的讲就是指容器的结果的信息]

JDBC中有两种元数据,一种是数据库元数据(DatabaseMetaData,另一种是结果集元数据(ResultSetMetaData

       1.数据库元数据

              如果要想了解数据库的更多信息。可以从数据库连接中获取一个DatabaseMetaData

              DatabaseMetaData dmd=conn.getMetaData();

              然后可以调用如下的方法获得数据库相关的信息

              getURL(),获得连接数据库的URL

              getDatabaseProductName() 获得数据库产品的名称

              getDriverVersion() 获得JDBC驱动程序的String形式的版本号

              getTables()获得数据库中该用户的所有表

              getUserName() 获得数据库用户名。

       2.结果集元数据

              ResultSet rs=ps.executeQuery();

              ResultSetMetaData m=rs.getMetaData();

              getColumnCount(),获得实际列数

              getColumnName(int colnum),获得指定列的列名

              getColumnType(int colnum),获得指定列的数据类型

              getColumnTypeName(int colnum),获得指定列的数据类型名

       例如:ResultSetMetaData md = rs.getMetaData();

                            // 得到字段个数

                            int cols = md.getColumnCount();

                            // 根据字段个数遍历和打印结果集

                            StringBuffer sb = new StringBuffer();

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

                                   sb.append(md.getColumnName(i + 1) + " ");

                            }

              动态获得表结构

六、JDBC2.0新特性

       默认方式获得的结果集都是1.0的结果集

       能否使用JDBC2.0 ResultSet的新特性要看数据库驱动程序是否支持。

       1.可滚动结果集(可双向滚动),(了解 能说出结果集滚动的方法即可)

              这种结果集不但可以双向滚动,相对定位,绝对定位,并且可以修改数据信息。

              要使用可滚动结果集时,要在Statement创建时指定参数,才可以使用

              Statement st=null;int,int(可滚动特性,可更新特性)

              st=con.createStatement(ReusltSet.TYPE_SCROLL_INSENSITIVE,ResuleSet.CONCUR_UPDATABLE) 

              PreparedStatement

ps=con.createPrepareStatement(sql,ReusltSet.TYPE_SCROLL_INSENSITIVE,ResuleSet.CONCUR_

UPDATABLE);

              ResultSet rs=ps.executeQuery(sql);

       滚动特性

              next(),此方法是使游标向下一条记录移动。

              previous() ,此方法可以使游标向上一条记录移动,前提前面还有记录。

              absolute(int row),绝对定位函数可以使用此方法跳到指定的记录位置。定位成功返回true,不成功返

false,返回值为false,则游标不会移动。

              afterLast() ,游标跳到最后一条记录 之后,(结果集一回来时就有的位置)。无返回值。

              beforeFirst() ,游标跳到第一条记录 之前,(结果集一回来时就有的位置)。(跳到游标初始位)无返回

              first(),游标指向第一条记录。

              last(),有彪指向最后一条记录。

              relative(int rows),相对定位方法,参数值可正可负,参数为正,

              游标从当前位置向下移动指定值,参数为负,游标从当前位置向上移动指定值。

       ResultSet可滚动性的属性值:

              TYPE_FORWARD_ONLY ,单向,该常量指示指针只能向前移动的 ResultSet 对象的类型。不可滚动。

              TYPE_SCROLL_INSENSITIVE ,双向,对数据库的变化不敏感

              TYPE_SCROLL_SENSITIVE ,双向,对数据库的变化敏感

              ResultSet 对象的类型。该特性某些数据库不支持。

       ResultSet可更新性的属性值: 

              CUNCUR_READ_ONLY,不可更新的结果集

              CUNCUR_UPDATEABLE,可更新的结果集

       2.可更新的结果集:(不常用,也不推荐使用)(了解)

              如果你想能够编辑结果集中的数据,并且将结果集上的数据自动反应到数据库中,

              那么就必须使用可更新的结果集,可更新结果集不一定是可滚动的,获得可更新结果集的方法:

       Statement  

stat=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATE

ABLE);

              这样,调用executeQuery()方法返回的结果集就是可更新的结果集。

       例如:

              String query="SELECT * FROM books";

              ResultSet rs=stat.executeQuery(query);

              While(rs.next){

                    If(.......){

                                 Double inscrease=.......;

                                 Double price=rs.getDouble("Price");

                           rs.updateDouble("Price",price+inscrease);

                           rs.updateRow();

                   }

              }

所有的对应于SQL类型的数据类型都配有updateXXX方法。与getXXX方法类似。使用updateXXX方法是必须指定列的名称或序列号。

       然后,可以给 该字段设置新的值。

       updateXXX方法改变的只是结果集中的行值,而非数据库中的值。当更新完行中的字段值后,必须调用

updateRow方法,这个方法将当前的行中所有更新信息发送给数据库。如果没有调用updateRow方法就将

游标移动到其他行上。那么所以的更新信息就将被丢弃,而且永远不会被传递给数据库。还可以调用cancelRowUpates方法来取消对当前行的更新。

       以上是更新数据库中的一行记录,如果想在数据库中添加一条新的记录,首先需要使用moveToInsertRow

()方法将游标移动到特定的位置。然后调用updateXXX()方法在插入行的位置上创建一个新的行。然后调用

insertRow()方法将新建的行发送给数据库。完成插入操作后在调用moveToCurrentRow()方法讲游标移回到调用moveToInsertRow方法之前的位置:

       例子:

              rs.moveToInsertRow();

              rs.updateString("Title",title);

              rs.updateString("Price",price);

              ..........

              rs.insertRow();

              rs.moveToCurrentRow();

       如果要删除一行调用rs.deleteRow()即可删除结果集和数据库中的一行

       能否使用可更新结果集,要看使用的数据库驱动是否支持,还有只能用于单表且表中有主键字段(可能会是

联合主键),不能够有表连接,会取所有非空字段且没有默认值。结果集用select * from t也不行,不能用

*,不能排序

       3,批处理更新 (熟记于心)

              Statement.

              addBatch(String sql) 方法会在批处理缓存中加入一条sql语句

              executeBatch() ,执行批处理缓存中的所有sql语句。

              PreparedStatement.   先准备一组参数

              addBatch() 将一组参数添加到此 PreparedStatement 对象的批处理命令中。

              executeBatch() 将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。

              PreparedStatement中使用批量更新时,要先设置好参数后使用addBatch()方法加入缓存。

              注意:批量更新中用更新或插入语句

面向对象的数据库设计

Id通常是用来表示记录的唯一性的,通常会使用业务无关的数字类型

Object id 对象的idsequence只有Oracle才可用,对象idOID)使用高低位算法先生成高位,在生成低位,通过运算获得对象id

类应当对象到表,属性对应字段,对象对应记录。

类继承关系对应表,

1,每个类建一个表,为父子类每个类都对应的创建表,这种方法类关系清晰,但是如果类比较多就不适合了

2,只有具体类才建表,也就是把父类中的属性均匀分配到子类的表中,也就是父类不建表,这种表关系不能使用多态

3,所有类对应一张表,这种方法是在表中加上一个字段来区分父子类,但是只能用于类属性较少的情况下,而且数据会有冗余。

类关联关系对应表

1,一对一关联,类关系对应成表时有两种做法,一是引用主键,也就是一方引用另一方的主键既作为外键又作为自身的主键。

      二是外键引用,一方引用另一方的主键作为自身的外键,并且自己拥有主键。

2,一对多关联,也就是多端引用一端的主键当作外键,多端自身拥有主键。

3,多对多关系,多对多关系是通过中间表来实现的,中间表引用两表的主键当作联合主键,就可以实现多对多关联。

posted on 2009-03-29 19:40 雨飞 阅读(209) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 

<2025年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

留言簿

文章档案

搜索

  •  

最新评论