jdbc简介


JDBC简介

JDBC是我们使用JAVA程序操作数据库的工具.

Java Data Base Connectivity java数据库连接

是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成

 

我们想用Java程序操作数据库, 就需要使用数据库的驱动.

由于每种数据库存储数据的方式不同, 他们所提供的数据库驱动也就不同.

如果我们学习所有数据库的驱动, 那么学习成本是很高的.

JDBC就是一套数据库驱动的规范, 由多个接口组成.

例如在JDBC的接口中定义了查询方法, 所有数据库厂商都在自己的驱动中实现这个查询方法.

搭建环境

在数据库中创建库、表、插入数据.

Java工程, 导入驱动

在程序中加载驱动

DriverManager.registerDriver(driver)

建立连接

Connection conn = DriverManager.getConnection(url, user, password)

创建Statement对象

Statement st = conn.createStatement()

执行SQL语句, 获取ResultSet

ResultSet rs = st.executeQuery(sql)

Result中获取数据, 显示

rs.next()

rs.getObject(columnLabel)

释放资源

rs.close()

st.close()

conn.close()

注册驱动

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

可以加载MySQL的驱动, 但我们不推荐这么做.

参考com.mysql.jdbc.Driver的源代码我们可以看到, 这个类的静态代码块中已经将自己注册到DriverManager了.

如果我们在程序中再次注册, 相当于注册了两次.

参考文档26.3.1.1, 我们可以使用一下形式注册驱动, 当类被加载时自动注册.

Class.forName("com.mysql.jdbc.Driver");

Statement

ResultSet executeQuery(String sql)

执行查询语句, 返回结果集

 

int executeUpdate(String sql)

执行插入, 修改, 删除语句, 返回影响行数

 

boolean execute(String sql)

执行任意sql语句, 返回执行是否成功

ResultSet

通过Statement运行查询语句可以获得结果集.

结果集中存储从数据库中查询出数据的集合, 内部维护一个指针, 默认指向开始位置之前.

 

boolean next()

尝试将指针向下移动一行, 返回是否成功

 

Object getObject(int columnIndex)

Object getObject(String columnName)

当指针指向某一条记录之后, 可以根据列号或者列名获取某一列的数据, 由于数据库中可以存放多种类型数据, 所以返回Object

 

由于我们通常是将获取到的结果集中的数据封装到对象中, 所以经常要将Object强转成其他类型.

ResultSet中定义了一系列方法方便我们的操作.

SQL类型

JDBC对应方法

Java类型

BIT

getBoolean()

boolean

TINYINT

getByte()

byte

SMALLINT

getShort()

short

INT

getInt()

int

BIGINT

getLong()

long

CHAR, VARCHAR, LONGVARCHAR

getString()

String

TEXT(CLOB)

getClob()

java.sql.Clob

BLOB

getBlob()

java.sql.Blob

DATE

getDate()

java.sql.Date

TIME

getTime()

java.sql.Time

TIMESTAMP

getTimestamp()

java.sql.Timestamp

 

ResultSet除了大量get方法外还有一些控制指针移动的方法

 

boolean next()

尝试将指针向后移动一行, 返回是否成功

 

boolean previous()

尝试将指针向前移动一行, 返回是否成功

boolean absolute(int row)

尝试将指针移动到指定行, 返回是否成功

 

void beforeFirst()

将指针移动到第一行以前

 

void afterLast()

将指针移动到最后一行以后

释放资源

在程序运行结束以后, 和数据库相关的资源不会被自动释放掉, 我们需要手动释放ResultSet, Statement, Connection

尤其Connection是非常宝贵的资源, 使用结束之后应该尽早释放.

为了确保释放资源的代码一定会执行到, 我们通常将它们放在finally

 

 

 

JDBC(2)

 

1事务ACID

原子性(atomicity):组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。有假设一个事物两个或者多个人物组成,其中的语句必须同时成功才能认为事物是成功的。如果是无失败系统会返回到事物以前的状态。

一致性(consistency):在事务处理执行前后,数据库是一致的(两个账户要么都变,或者都不变)。不管事务完全成功还是中途失败当事务使系统处于一致状态时存在一致性。

隔离性(isolcation):一个事务处理对另一个事务处理没有影响。每个事物在它自己的空间发生,和其它在系统中发生的事物隔离,而且事务的结果只有在它完全被执行时才会看到。大多数事务系统使用页隔离级锁定或行级锁定不同事务之间的变化,这是要以降低性能为代价的。

持续性(durability):事务处理的效果能够被永久保存下来。即使系统崩溃一个提交的事务仍存在当一个事务完成时数据库的日志已经被更新时,持久性会发生作用。

2常用API7u

connection.setAutoCommit(false);

关闭自动提交, 打开事务。

connection.commit();

提交事务。

connection.rollback();

回滚事务。

Savepoint sp = conn.setSavepoint();

设置保存点

conn.rollback(sp);

回滚到保存点

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

 

当事务回滚到某个保存点后,在该保存点之后设置的保存点将被删除。

3隔离级别

在多线程并发访问数据库并且使用事务的时候, 可能会遇到脏读, 不可重复读, 幻读的情况, 需要设置隔离级别来避免

 

脏读: 读到的线程未提交的数据

不可重复读: 在一个事务中读取同一个记录两次, 获取数据不同

幻读: 在一个事务中, 读取到的记录数不同

select @@tx_isolation;

查看隔离级别

set transaction isolation level read uncommitted;

设置读未提交

set transaction isolation level read committed;

设置读已提交

set transaction isolation level repeatable read;

设置可重复读

set transaction isolation level serializable;

设置可序列化

start transaction;

开始事务

rollback;

回滚事务

commit;

提交事务

 

4获取插入的ID

conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

ResultSet rs = ps.getGeneratedKeys();

if (rs.next())

user.setId(rs.getInt(1));

 

MySQL的select last_insert_id()可以获取之前插入的记录的id, 但这只是MySQL才有的函数

 

只有对自增长的列发生自增长的赋值后才会导致一个key的产生,并且用getGereratedKeys()返回。

5分页

通过ResultSet的滚动可以设置获取记录的位置, 但这样是从数据库中查询出所有数据, 然后再从结果中筛选结果, 性能非常低.

 

MySQL提供了分页语法. 在查询语句后可使用LIMIT关键字完成分页功能, 例如:

 

select * from user limit 40,20

 

查询从user表中取出从第41条开始的20条记录. 第一个参数表示忽略前面多少个, 第二个参数代表取多少个.

6   可更新结果集、敏感结果集

conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

 

ResultSet.TYPE_SCROLL_SENSITIVE

表示获得ResultSet之后是敏感的, 随数据库更新的. 但MySQL没有支持这项功能

 

ResultSet.CONCUR_UPDATABLE

表示获得ResultSet之后是可更新的, 例如:

rs.next();

rs.updateString("name", "updateName");

rs.updateRow();

可以将当前行的name属性改为updateName.

 
0

 

posted @ 2016-04-18 10:06  starskyhu  阅读(447)  评论(0编辑  收藏  举报