一、JDBC入门
想要使用JDBC就得有一个数据库,这里以mysql为例子。
获取一个mysql的jar包,复制粘贴到该文件夹下,右键bulid path安装到路径内
然后最基本的操作顺序就是加载驱动–>获取连接–>执行SQL–>释放资源。例子如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.junit.Test;
public class JDBCDemo1 {
@Test
public void demo1() throws Exception{
Class.forName("com.mysql.jdbc.Driver");//加载驱动
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "");
//获得连接
Statement statement = conn.createStatement();//获得可执行sql的对象
String sql = "show tables";//sql语句
ResultSet rs = statement.executeQuery(sql);//执行sql语句
//遍历结果集
while (rs.next()) {
System.out.println(rs.getString("Tables_in_db3"));
}
//释放资源
rs.close();
statement.close();
conn.close();
}
}
二、API详解和其他基本操作
DriverManager : 驱动管理类
作用:注册驱动
这个类里面有一个静态注册驱动的方法registerDriver (Driver driver)
这个方法可以完成驱动的注册,但是实际开发中一般不会使用这个方法完成驱动的注册!
原因:
如果需要注册驱动,就会使用DriverManager.registerDriver(new Driver());
但是这个Driver类在代码中有一段静态代码块,静态代码块已经调用了注册驱动的方法。
如果再手动调用则会导致注册两次。
所以一般使用Class.forName(“com.mysql.jdbc.Driver”); 去注册驱动。
作用:获得与数据库的连接
用这个方法获得与数据库连接:getConnection (String url,String user,String password);
这个里面url的写法需要重点关注。入门中的例子里是这样的:
jdbc:mysql://localhost:3306/db3
各个的含义是:
jdbc : 连接数据库的协议
mysql : 是jdbc的子协议
localhost : 连接的MysQL 数据库服务器的主机地址。(连接是本机就可以写成localhost),如果连接不是本机的,就需要写上连接主机的IP地址。
3306 : MySQL数据库服务器的端口号+
db3 : 数据库名称
url如果连接的是本机的路径,可以简化为如下格式:
jdbc:mysql:///db3;
注意:是3个/
Connection :与数据库连接对象
作用:创建执行sql语句的对象
createStatement() : 创建一个 Statement对象来将SQL语句发送到数据库。
prepareCall(String sql) : 创建一个CallableStatement 对象来调用数据库存储过程。
prepareStatement(String sql) : 创建一个PreparedStatement对象来将参数化的SQL语句发送到数据库。
statement : 执行SQL
Callablestatement : 执行数据库中存储过程
PreparedStatement : 执行SQL对SQL进行预处理。解决SQL注入漏洞。
作用:管理事务
setAutoCommit (boolean autoCommit) : 将此连接的自动提交模式设置为给定状态。
commit() : 使所有上一次提交/回滚后进行的更改成为持久更改,并释放此Connection对象当前持有的所有数据库锁。
rollback() : 取消在当前事务中进行的所有更改,并释放此Connection对象当前持有的所有数据库锁。
Statement : 执行SQL
作用:执行SQL
boolean execute(String sql) :执行给定的SQL语句(该语句可能返回多个结果),并通知驱动程序所有自动生成的键都应该可用于获取。 执行查询,修改,添加,删除的SQL语句,如果是查询语句返回true,如果是修改,添加,删除的SQL语句,返回false。
一般使用下面两个方法:
ResultSet executeQuery(String sql) : 执行给定的SQL语句,该语句返回单个ResultSet对象。 执行查询
int executeUpdate(string sql) : 执行给定SQL语句,该语句可能为INSERT、UPDATE或 DELETE语句,或者不返回任何内容的SQL语句(如SQL DDL语句)。执行修改,添加,删除的SQL语句
作用:执行批处理
addBatch (String sql) : 将给定的SQL命令添加到此Statement对象的当前命令列表中。
**clearBatch() **: 清空此 Statement 对象的当前SQL命令列表。
int[] executeBatch() : 将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
ResultSet : 结果集
通过查询语句获得的结果。
next() : 这个光标最早是在第一行之前,当调用了next()之后就会指向第一行。
那么结果集的获取就需要使用getxxx() 方法,如下:
getXxx(int columnlndex); 列号
getXxx(String columnName); 列名,通常是使用这个
资源释放
JDBC程序执行结束后,将与数据库进行交互的对象释放掉,通常ResultSet,Statement,Connection。这几个对象中尤其是Connection对象是非常稀有的。这个对象一定要做到尽量晚创建,尽早释放掉。
将资源释放的代码写入到 finally 的代码块中。
资源释放的代码应该写的标准:手动置为null的用处是让gc更早回收
//释放资源
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
CRUD
1.利用statement保存、修改、删除、查询操作:
保存操作:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
public class JDBCDemo2 {
@Test
public void demo1() {
Connection conn = null;
Statement statement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "");
statement = conn.createStatement();
String sql = new String("insert into user values(null,'小明','10086',18,'1999-01-02')");
int num = statement.executeUpdate(sql);
if (num>0) {
System.out.println("数据保存成功");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
}
此时去数据库查询表可以发现数据已经插入成果!如果出现中文乱码问题应该是数据库字符集未设置好,去手动设置一下就OK了。
修改操作:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
public class JDBCDemo2 {
@Test
public void demo1() {
Connection conn = null;
Statement statement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "");
statement = conn.createStatement();
String sql = "update user set username = '小美',password = '110',age=20,birthday='1999-12-05' where id = 1";
int num = statement.executeUpdate(sql);
if (num>0) {
System.out.println("数据更新成功");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
}
运行结果查询数据库如下图:
删除操作:
@Test
public void demo2() {
Connection conn = null;
Statement statement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "");
statement = conn.createStatement();
String sql = "delete from user where id = 2";
int num = statement.executeUpdate(sql);
if (num>0) {
System.out.println("数据删除成功");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
运行结果查询数据库如下图:
查询操作:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
public class JDBCDemo2 {
@Test
public void demo1() {
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "");
statement = conn.createStatement();
String sql = "select * from user";
rs = statement.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getInt("age")+" "+rs.getString("birthday"));
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
}
程序运行结果如下:
2.工具类的抽取
写出上述代码后发现,代码重复且无趣,于是可以编写一个工具类方便书写,代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils {
private static final String driverClassName;
private static final String url;
private static final String username;
private static final String password;
static {
driverClassName = "com.mysql.jdbc.Driver";
url = "jdbc:mysql:///jdbc";
username = "root";
password = "";
}
public static void loadDriver() {
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
Connection conn = null;
try {
loadDriver();
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static void release(ResultSet rs,Statement statement,Connection conn) {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(Statement statement,Connection conn) {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
以后就可以利用自己的工具类去编写程序。
2.1配置信息提取到配置文件
配置文件有两种,属性文件和XML
本文采用属性文件
文件格式 : 扩展名是properties
内容: key=values
如下图:
有了配置文件后,就可以在文件中修改,那么修改上述我们创建的工具类中static的静态代码块中的部分就可以了。
static {
Properties properties = new Properties();