1.Connection
1.1 Connection简介
获得数据库连接是操作数据库的第一步,是应用程序和数据库的一次“握手”过程。数据库打开的连接数是有限的,所以连接使用完成后需要关闭。
1.2 获得数据连接Connection
获得数据连接的步骤
1)使用Class类加载驱动
Class.forName("com.mysql.jdbc.Driver");
2)使用DriverManager获得连接
DriverManager.getConnection(url,user,password);
DBUtil.java
package com.amaker.util;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
public static void main(String[] args) {
DBUtil util = new DBUtil();
Connection conn1 = util.getConnection();
System.out.println(conn1);
Connection conn2 = util.getConnection("com.mysql.jdbc.Driver",
"jdbc:mysql://192.168.80.101:3306/jdbc_db", "root", "password");
System.out.println(conn2);
}
public Connection getConnection() {
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(
"jdbc:mysql://192.168.80.101:3306/jdbc_db", "root",
"password");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public Connection getConnection(String driver, String url, String username,
String password) {
try {
// 加载驱动
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
测试:
上面的两个getConnection方法都可以获得Connection对象,不同的是第一个getConnection方法得到的是固定配置的Connection对象,第二个Connection方法得到的是参数可以自己设定的Connection对象。
1.3 获得一个使用配置文件配置的连接
如果想要将Connection对象的配置放在一个配置文件中,然后读取这个配置文件来获得Connection对象,该怎么弄呢?
首先,在该包下建立一个DBConfig.properties文件,写入自己想要的配置文件,例如:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.80.101:3306/jdbc_db
username=root
password=password
然后重新建立一个得到Connection方法,比如openConnection():
public Connection openConnection() {
Properties prop = new Properties();
String driver = null;
String url = null;
String username = null;
String password = null;
try {
// 将配置文件加载进内存
prop.load(this.getClass()
.getResourceAsStream("DBConfig.properties"));
// 设置Connection参数
driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
// 加载驱动程序
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
测试:
1.4 关于Connection的其他知识
在得到Connection对象后,可以设定一些参数,比如和事务有关的autocommit,mysql中的事务默认是自动提交的,可以使用Connection对象调用setAutoCommit(false)将自动提交设为手动提交,然后等sql语句真的执行完了后,再调用commit()方法提交事务。如果在执行sql语句的过程中发成了异常,则调用rollback()方法实现回滚。
package com.amaker.util;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DBUtil {
public static void main(String[] args) {
DBUtil util = new DBUtil();
util.add();
}
public void add() {
DBUtil util = new DBUtil();
Connection conn = util.openConnection();
String sql = "insert into UserTable (id,username,password) values (4,'bigtom','666')";
try {
// 设置事务手动提交
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate(sql);
// 提交事务
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
// 如果失败,回滚
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
// 关闭
util.closeConnection(conn);
}
}
public Connection openConnection() {
Properties prop = new Properties();
String driver = null;
String url = null;
String username = null;
String password = null;
try {
// 将配置文件加载进内存
prop.load(this.getClass()
.getResourceAsStream("DBConfig.properties"));
// 设置Connection参数
driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
// 加载驱动程序
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public void closeConnection(Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2. Statement
2.1 Statement简介
Statement用于执行静态 SQL 语句并返回它所生成结果的对象。
2.2 获得Statement
通过Connection类的createStatement()方法或则Statement对象。
package com.amaker.test;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import com.amaker.util.DBUtil;
public class StatementTest {
public static void main(String[] args) {
getStatement();
}
static Statement getStatement() {
DBUtil util = new DBUtil();
// 得到Connection对象
Connection conn = util.openConnection();
// 获得Statement对象
try {
Statement stmt = conn.createStatement();
System.out.println(stmt);
return stmt;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
测试:
2.3 使用Statement执行DDL
调用executeUpdate(String sql)方法来执行一些DDL语句。例如想要在数据库中新建一个StuTbl表,现在首先查看先数据库中现有的表:
mysql> show tables;
+-------------------+
| Tables_in_jdbc_db |
+-------------------+
| UserTable |
+-------------------+
1 row in set (0.00 sec)
编写程序:
package com.amaker.test;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import com.amaker.util.DBUtil;
public class StatementTest {
public static void main(String[] args) {
// getStatement();
createTable();
}
// create table StuTbl(id int, name varchar(20), age int);
static void createTable() {
Statement stmt = getStatement();
String sql = "create table StuTbl(id int, name varchar(20), age int)";
try {
stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
System.out.println("create table success!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
static Statement getStatement() {
DBUtil util = new DBUtil();
// 得到Connection对象
Connection conn = util.openConnection();
// 获得Statement对象
try {
Statement stmt = conn.createStatement();
// System.out.println(stmt);
return stmt;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
测试结果:
mysql> show tables;
+-------------------+
| Tables_in_jdbc_db |
+-------------------+
| StuTbl |
| UserTable |
+-------------------+
2 rows in set (0.00 sec)
2.4 使用Statement执行DML
1. 调用excuteUpdate(String sql)来执行insert、update、delete操作。
比如要向表StuTbl中添加一个一行记录。先查询下StuTbl表的记录:
mysql> select * from StuTbl;
Empty set (0.00 sec)
编写添加程序:
static void add() {
DBUtil util = new DBUtil();
Connection conn = util.openConnection();
try {
Statement stmt = conn.createStatement();
String sql = "insert into StuTbl (id,name,age) values (1,'tom',18)";
stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
util.closeConnection(conn);
System.out.println("insert success!");
}
}
测试结果:
mysql> select * from StuTbl;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | tom | 18 |
+------+------+------+
1 row in set (0.00 sec)
2. 调用executeQuery(String sql)来执行select操作,该方法返回一个ResultSet结果集,然后遍历这个结果集,得到记录即可。
首先先查询下StuTbl表中的数据:
mysql> select * from StuTbl;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | tom | 18 |
+------+------+------+
1 row in set (0.00 sec)
编写程序:
static void query() {
DBUtil util = new DBUtil();
Connection conn = util.openConnection();
try {
Statement stmt = conn.createStatement();
String sql = "select id,name,age from StuTbl";
// 执行查询操作,并返回结果集
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println(id + ":" + name + ":" + age);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
util.closeConnection(conn);
}
}
测试结果:
3. ResultSet
3.1 ResultSet简介
Result表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
ResultSet 接口提供用于从当前行获取列值的获取 方法(getBoolean、getLong 等)。可以使用列的索引编号或列的名称获取值。一般情况下,使用列索引较为高效。列从 1 开始编号。为了获得最大的可移植性,应该按从左到右的顺序读取每行中的结果集列,每列只能读取一次。
3.2 Java数据类型与SQL数据类型的映射
3.3 ResultSet常用方法
package com.amaker.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.amaker.util.DBUtil;
public class ResultSetTest {
public static void main(String[] args) {
testResultSet();
}
static void testResultSet() {
DBUtil util = new DBUtil();
// 得到Connection对象
Connection conn = util.getConnection();
// 得到Statement对象
Statement stmt = null;
try {
stmt = conn.createStatement();
String sql = "select id,name,age from StuTbl";
// 执行查询语句,得到结果集
ResultSet rs = stmt.executeQuery(sql);
// 查看当前光标指向哪里
System.out.println(rs.getRow());
// 获取光标是否位于此 ResultSet对象的第一行之前。
System.out.println(rs.isBeforeFirst());
// 将光标指向下一行
rs.next();
// 获取光标指向的行号
System.out.println(rs.getRow());
// 判断光标是否指向第一行
System.out.println(rs.isFirst());
// 将光标移动到此 ResultSet对象的给定第2行。
rs.absolute(2);
System.out.println(rs.getRow());
} catch (SQLException e) {
e.printStackTrace();
}
}
}
测试结果:
getXxx()方法:
String getString(int columnIndex) :以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。
String getString(String columnLabel) :以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。
package com.amaker.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.amaker.util.DBUtil;
public class ResultSetTest {
public static void main(String[] args) {
testResultSet();
}
static void testResultSet() {
DBUtil util = new DBUtil();
// 得到Connection对象
Connection conn = util.getConnection();
// 得到Statement对象
Statement stmt = null;
try {
stmt = conn.createStatement();
String sql = "select id,name,age from StuTbl";
// 执行查询语句,得到结果集
ResultSet rs = stmt.executeQuery(sql);
/*
* // 查看当前光标指向哪里 System.out.println(rs.getRow()); // 获取光标是否位于此
* ResultSet对象的第一行之前。 System.out.println(rs.isBeforeFirst()); //
* 将光标指向下一行 rs.next(); // 获取光标指向的行号 System.out.println(rs.getRow());
* // 判断光标是否指向第一行 System.out.println(rs.isFirst()); // 将光标移动到此
* ResultSet对象的给定第2行。 rs.absolute(2);
* System.out.println(rs.getRow());
*/
while (rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(2);
int age = rs.getInt(3);
System.out.println(id + ":" + name + ":" + age);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
我们经常将得到的数据封装到List中去,那么怎么封装呢?
package com.amaker.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.amaker.util.DBUtil;
public class ResultSetTest {
public static void main(String[] args) {
List<Student> list = list();
for (Student s : list) {
System.out.println(s);
}
}
static List<Student> list() {
DBUtil util = new DBUtil();
// 得到Connection对象
Connection conn = util.getConnection();
List<Student> list = new ArrayList<Student>();
try {
// 得到Statement对象
Statement stmt = conn.createStatement();
String sql = "select id,name,age from StuTbl";
// 执行查询语句,得到结果集
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(2);
int age = rs.getInt(3);
Student s = new Student();
s.setId(id);
s.setName(name);
s.setAge(age);
// 将s添加到list中
list.add(s);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
class Student {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
测试结果:
3.4 可滚动/可更新的ResultSet
默认的 ResultSet 对象不可更新,仅有一个向前移动的光标。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。可以生成可滚动和/或可更新的 ResultSet 对象。举个例子:
先查看表中原有数据:
mysql> select * from StuTbl;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | tom | 18 |
| 2 | tom | 18 |
+----+------+------+
2 rows in set (0.00 sec)
编写程序:
package com.amaker.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.amaker.util.DBUtil;
public class ResultSetTest {
public static void main(String[] args) {
updateableResultSet();
}
static void updateableResultSet() {
DBUtil util = new DBUtil();
Connection conn = util.openConnection();
String sql = "select id,name,age from StuTbl";
Statement stmt;
try {
// 得到可更新的ResultSet对象
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sql);
// 更新一行
rs.absolute(2);// 将光标指向第2行
rs.updateString("name", "bigtom");// 将第2行的name列更新为bigtom
rs.updateInt("age", 30);// 将第2行的age列更新为30
rs.updateRow();// 用此 ResultSet对象的当前行的新内容更新底层数据库。
// 添加一行
rs.moveToInsertRow(); // 移动到插入行
rs.updateInt("id", 3);// 将插入行的id列更新为3
rs.updateString("name", "kite");// 将插入行的name列更新为kite
rs.updateInt("age", 20);// 将插入行的age列更新为20
rs.insertRow();// 将插入行的内容插入到此 ResultSet 对象和数据库中。
} catch (SQLException e) {
e.printStackTrace();
}
}
}
运行后查看表中的数据:
mysql> select * from StuTbl;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | tom | 18 |
| 2 | bigtom | 30 |
| 3 | kite | 20 |
+----+--------+------+
3 rows in set (0.00 sec)