本文借postgreSQL通过JDBC连接数据库的示例,介绍了常见数据库操作及JDBC的API、JDBC的一般工作流程及JDBC事务。
A、下载安装好postgreSQL数据库。
B、新建一个java项目,并导入postgreSQL的JDBC驱动程序jar包。
package vertxTest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class PostgreSQLJDBC {
public static void main(String args[]) {
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.postgresql.Driver");
c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/pgsqltest", "postgres", "2016");
c.setAutoCommit(false); // 把自动提交
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "CREATE TABLE STUDENTS " +
"(ID TEXT PRIMARY KEY NOT NULL ," +
" NAME TEXT NOT NULL, " +
" SEX TEXT NOT NULL, " +
" AGE TEXT NOT NULL)";
stmt.executeUpdate(sql);
System.out.println("Table created successfully");
stmt.close();
c.commit();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
}
}
A、定义记录的类(可选)
package vertxTest;
public class Student {
private String Id;
private String Name;
private String Sex;
private String Age;
Student(String Id,String Name, String Sex, String Age) {
this.Id = Id; //default
this.Name = Name;
this.Sex = Sex;
this.Age = Age;
}
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getSex() {
return Sex;
}
public void setSex(String Sex) {
this.Sex = Sex;
}
public String getAge() {
return Age;
}
public void setage(String Age) {
this.Age = Age;
}
}
B、JDBC表数据操作方法
package vertxTest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCOperation {
/**
* @method getConn() 获取数据库的连接
* @return Connection
*/
public Connection getConn() {
String driver = "org.postgresql.Driver";
String url = "jdbc:postgresql://localhost:5432/pgsqltest";
String username = "postgres";
String password = "2016";
Connection conn = null;
try {
Class.forName(driver); // classLoader,加载对应驱动
conn = (Connection) DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* @method insert(Student student) 往表中插入数据
* @return int 成功插入数据条数
*/
public int insert(Student student) {
Connection conn = getConn();
int i = 0;
String sql = "insert into students (id,Name,Sex,Age) values(?,?,?,?)";
PreparedStatement pstmt;
try {
pstmt = (PreparedStatement) conn.prepareStatement(sql);
pstmt.setString(1, student.getId());
pstmt.setString(2, student.getName());
pstmt.setString(3, student.getSex());
pstmt.setString(4, student.getAge());
i = pstmt.executeUpdate();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
/**
* @method delete(Student student) 删除表中数据
* @return int 成功删除表中数据条数
*/
public int delete(String name) {
Connection conn = getConn();
int i = 0;
String sql = "delete from students where Name='" + name + "'";
PreparedStatement pstmt;
try {
pstmt = (PreparedStatement) conn.prepareStatement(sql);
i = pstmt.executeUpdate();
System.out.println("resutl: " + i);
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
/**
* @method update(Student student) 更改表中数据
* @return int 成功更改表中数据条数
*/
public int update(Student student) {
Connection conn = getConn();
int i = 0;
String sql = "update students set Age='" + student.getAge() + "' where Name='" + student.getName() + "'";
PreparedStatement pstmt;
try {
pstmt = (PreparedStatement) conn.prepareStatement(sql);
i = pstmt.executeUpdate();
System.out.println("resutl: " + i);
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
/**
* @method Integer getAll() 查询并打印表中数据
* @return Integer 查询并打印表中数据
*/
public Integer getAll() {
Connection conn = getConn();
String sql = "select * from students";
PreparedStatement pstmt;
try {
pstmt = (PreparedStatement)conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
int col = rs.getMetaData().getColumnCount();
System.out.println("============================");
while (rs.next()) {
for (int i = 1; i <= col; i++) {
System.out.print(rs.getString(i) + "\t");
if ((i == 2) && (rs.getString(i).length() < 8)) {
System.out.print("\t");
}
}
System.out.println("");
}
System.out.println("============================");
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
C、测试类
package vertxTest;
public class JDBCTest {
public static void main(String args[]) {
JDBCOperation op = new JDBCOperation();
op.getAll();
op.insert(new Student("001","Achilles", "Male", "14"));
op.insert(new Student("002","Bean", "Fmale", "15"));
op.getAll();
op.update(new Student("002","Bean", "", "7"));
op.delete("Achilles");
op.getAll();
}
}
C、输出结果
============================ ============================ ============================ 001 Achilles Male 14 002 Bean Fmale 15 ============================ resutl: 1 resutl: 1 ============================ 002 Bean Fmale 7 ============================ |
在上述对数据库进行增删改查的过程中,可以发现其共性部分,即通用的流程:
(1)创建Connection对象、SQL查询命令字符串;
(2)对Connection对象传入SQL查询命令,获得PreparedStatement对象;
(3)对PreparedStatement对象执行executeUpdate()或executeQurey()获得结果;
(4)先后关闭PreparedStatement对象和Connection对象。
可见,使用JDBC时,最常打交道的是Connection、PreparedStatement这两个类,以及select中的ResultSet类。
API |
说明 |
java.sql.Connection |
与特定数据库的连接(会话)。能够通过getMetaData方法获得数据库提供的信息、所支持的SQL语法、存储过程和此连接的功能等信息。代表了数据库。 |
java.sql.Driver |
每个驱动程序类必需实现的接口,同时,每个数据库驱动程序都应该提供一个实现Driver接口的类。 |
java.sql.DriverManager (Class) |
管理一组JDBC驱动程序的基本服务。作为初始化的一部分,此接口会尝试加载在”jdbc.drivers”系统属性中引用的驱动程序。只是一个辅助类,是工具。 |
java.sql.Statement |
用于执行静态SQL语句并返回其生成结果的对象。 |
java.sql.PreparedStatement |
继承Statement接口,表示预编译的SQL语句的对象,SQL语句被预编译并且存储在PreparedStatement对象中。然后可以使用此对象高效地多次执行该语句。 |
java.sql.CallableStatement |
用来访问数据库中的存储过程。它提供了一些方法来指定语句所使用的输入/输出参数。 |
java.sql.PreparedStatement |
继承Statement接口,表示预编译的SQL语句的对象,SQL语句被预编译并且存储在PreparedStatement对象中。然后可以使用此对象高效地多次执行该语句。 |
java.sql.CallableStatement |
用来访问数据库中的存储过程。它提供了一些方法来指定语句所使用的输入/输出参数。 |
Class.forName(“org.postgresql.Driver”); JAVA规范中明确规定:所有的驱动程序必须在静态初始化代码块中将驱动注册到驱动程序管理器中。
conn=DriverManager.getConnection("jdbc:postgresql://localhost:5432/pgsqltest","postgres", "2016");
Connection连接是通过DriverManager的静态方法getConnection(.....)来得到的,这个方法的实质是把参数传到实际的Driver中的connect()方法中来获得数据库连接的。
postgreSQL URL的格式:
jdbc:postgresql:(协议)@XXX.XXX.X.XXX:XXXX(IP地址及端口号):XXXXXXX(所使用的库名)
MySql URL的写法 例:jdbc:mysql://192.168.8.21:3306/test
Statement stmt = conn.createStatement();
stmt.executeQuery(String sql); //返回一个查询结果集。
stmt.executeUpdate(String sql); //返回值为int型,表示影响记录的条数。
将sql语句通过连接发送到数据库中执行,以实现对数据库的操作。
使用Connection对象获得一个Statement,Statement中的executeQuery(Stringsql) 方法可以使用select语句查询,并且返回一个结果集。 ResultSet,通过遍历这个结果集,可以获得select语句的查寻结果,ResultSet的next()方法会操作一个游标从第一条记录的前面开始读取,直到最后一条记录。
executeUpdate(String sql) 方法用于执行DDL和DML语句,比如可以update,delete操作。
只有执行select语句才有结果集返回。
Statement str=con.createStatement(); //创建Statement
String sql=”insert into test(id,name)values(1,”+”’”+”test”+”’”+”)”;
str. executeUpdate(sql);//执行Sql语句
String sql=”select * from test”;
ResultSet rs=str. executeQuery(String sql);//执行Sql语句,执行select语句后有结果集
//遍历处理结果集信息
while(rs.next()){
System.out.println(rs.getInt(“id”));
System.out.println(rs.getString(“name”))
}
rs.close();
stmt.close();
con.close();
ResultSet Statement Connection是依次依赖的。
注意:要按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,因为Statement和ResultSet是需要连接时才可以使用的,所以在使用结束之后有可能其它的Statement还需要连接,所以不能现关闭Connection。
事务的4大特性
(1) 原子性
事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行。
原子操作,也就是不可分割的操作,必须一起成功一起失败。
(2) 一致性
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。
(3) 分离性
分离性指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被其它企图进行修改的事务看到。
(4) 持久性
持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即一旦一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,耐得住任何系统故障。持久性通过数据库备份和恢复来保证。