1 JDBC(以连接mysql为例)
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
2 数据库URL
jdbc:subprotocol:other stuff
jdbc:mysql://localhost:3306/test
3 驱动程序JAR(以连接mysql为例)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
4 连接mysql数据库
4.1 注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
或者
System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
4.2 连接到数据库
/*连接数据库时候需要*/
private static final String DB_URL = "jdbc:mysql://localhost:3306/test";
private static final String USER = "root";
private static final String PASS = "123456";
private Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
4.3 执行sql语句
-
获取Statement对象(最对只能有一个打开的结果集)
Statement stmt = conn.createStatement();
-
创建sql语句
String sql = "SELECT * FROM test";
-
执行sql
stmt.executeQuery(sql);
4.4 预备语句 PreparedStatement
// prepared.setStrng(1, "pwx");中的1代表sql中第一个?,'pwx'地表name='pwx'
PreparedStatement prepared = conn.prepareStatement("SELECT * FROM test WHERE name = ?");
prepared.setStrng(1, "pwx");
4.5 处理结果集ResultSet
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
int id = rs.getInt("id");
}
5 读取与存储LOB
5.1 读取LOB
除了数字字符串和日期之外,许多数据库还可以存储大对象。例如图片或者其他数据。在SQL中,二进制大对象称为BLOB,字符型大对象称为CLOB。
要读取LOB,需要执行SELECT语句,然后在ResultSet上调用getBlob或者getClob方法,这样就可以获得Blob或者Clob类型的对象。要从Blob中获取二进制数据,可以调用getBytes或者getBinaryStrem。
如果获取Clob对象,那么就可以通过调用getSubString或者getCharacterStream方法来获取其中的字符数据。
// 例如获取一张图片,rs是ResultSet的一个对象
Blob blob = rs.getBlob("img");
Image image = ImageIO.read(blob.getBinaryStream());
5.2 保存LOB
要将LOB置于数据库中,需要在Connection对象上调用createBlob或createBlob或者createClob,然后获取一个用于该LOB的输出流或写出器,写出数据,并将该对象存储到数据库中。
Blob blob0 = conn.createBlob();
int offset = 1; //
OutputStream out = blob0.setBinaryStream(offset);
ImageIO.write(ImageIO.read(new File("pwx.png")),"png",out);
PreparedStatement statement = conn.prepareStatement("INSERT INTO test value (?,?)");
statement.setBlob(1,blob0);
statement.setBlob(2,blob0);
statement.executeUpdate();
6 元数据
// 包含着数据库每张表的详细数据。
DatabaseMetaData data = conn.getMetaData();
// 可以获取该结果集的列数、每一列的名称、类型、字段的大小
ResultSetMetaDate d = rs.getMetaData();
7 事务
我们可以将一组语句构建成一个事务(transaction)。当所有语句都顺利执行之后,事务 可以被提交(commit)。否则,如果其中某个语句遇到错误,那么事务将被冋滚,就好像没有 任何语句被执行过一样。
将多个语句组合成事务的主要原因是为丫确保教据库完整性(database integrity)。例如, 假设我们需要将钱从一个银行账号转移到另一个账号。此时,一个非常重要的问题就是我们 必须同时将钱从一个账号取出并且存人另一个账号。如果在将钱存入其他账号之前系统发生 崩溃,那么我们必须撤销取款操作。
如果将更新语句组合成一个事务,那么事务要么成功地执行所有操作并提交,要么在中 间某个位置发生失败。在这种情况下,可以执行回滚(mllback)操作,则数据库将自动撤销 上次提交事务以来的所有更新操作产生的影响。
7.1 事务的特性
7.2 用JDBC对事务编程
默认情况下,数据库连接处于自动提交糢式(autocommit mode)。每个SQL语句一旦被 执行便被提交给数据库。一旦命令被提交,就无法对它进行冋滚操作。在使用事务时,需要 关闭这个默认值:
`conn.setAutoConit(flase);`
现在可以使用通常的方法创建一个语句对象:
Statement stat = conn.createStatement();
然后任意多次地调用executeUpdate方法:
stat.executeUpdate(commandi);
stat.executeUpdate(commandi);
stat.executeUpdate(commandi);
stat.executeUpdate(commandi);
如果执行了所有命令之后没有出错,则调用commit()方法:
conn.commit();
如果出现错误,则调用:
conn.rollback();
7.3 保存点
在使用某些驱动程序时,使用保存点(savepoint)可以更细粒度地控制回滚操作。创建
一个保存点意味着稍后只需返回到这个点,而非事务的开头。例如:
Statement stat = conn.createStatement(); // 事务的开始
stat.executeUpdate(command1);
Savepoint svpt = conn.setSavepoint(); // 设置保存点,回滚到这里
stat.executeUpdate(command1);
if (. . .) conn.rollback(svpt);
...
conn.commit();
当不再需要保存点时,必须释放它:
conn.releaseSavepoint(svpt);
8 示例
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.OutputStream;
import java.sql.*;
public class MySqlDEMO {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/test";
static final String USER = "root";
static final String PASS = "123456";
public static void conn() {
Connection conn = null;
Statement stmt = null;
try{
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL,USER,PASS);
DatabaseMetaData data = conn.getMetaData();
Blob blob0 = conn.createBlob();
int offset = 1; //
OutputStream out = blob0.setBinaryStream(offset);
ImageIO.write(ImageIO.read(new File("pwx.png")),"png",out);
PreparedStatement statement = conn.prepareStatement("INSERT INTO test value (?,?)");
statement.setBlob(1,blob0);
statement.setBlob(2,blob0);
statement.executeUpdate();
System.out.println("连接数据库成功....");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, name FROM user";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.print("ID: " + id);
System.out.print(", 姓名: " + name);
System.out.print("\n");
// 读取一张图片
Blob blob = rs.getBlob("img");
Image image = ImageIO.read(blob.getBinaryStream());
}
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(stmt!=null) stmt.close();
}catch(SQLException se2){
}
try{
if(conn!=null) conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}