使用 JDBC 可以方便的操作各种类型的数据库。以下记录一下 JDBC 的基础操作。
连接数据库
使用 DriverManager 建立 Connection
安装数据库服务和导入相应的 jar 包后,即可使用 JDBC 连接到数据库,得到一个 Connection 对象。
首先需要加载驱动程序,比如对于 mysql 数据库,可以使用如下代码加载驱动:
1 | Class.forName("com.mysql.jdbc.Driver"); |
然后建立连接。常用的是 DriverManager.getConnection(String url,String user, String password) 方法。
其中,参数 url 指定数据库位置,格式为:
1 | jdbc:subprotocol:subname |
即
协议:子协议:数据源标识
比如,我们使用的是本地的 mysql,端口使用默认的 3306,需要连接的数据库名为 userinfo,那么 url 应该为
1 | jdbc:mysql://localhost:3306/userinfo |
同时,为了避免向数据库存入中文字符时出现乱码,可以在 url 中添加参数指定编码,如下:
1 | jdbc:mysql://localhost:3306/userinfo?useUnicode=true&characterEncoding=utf-8 |
user 和 password 即为数据库的用户名和密码。
比如 user 为 root、password 为 12346,那么整个过程如下:
1 | Class.forName("com.mysql.jdbc.Driver"); // 加载驱动程序 |
也可以将 url、用户名、密码等信息存储在 web.xml 中当前 servlet 标签下,在 servlet 中读取,比如在 web.xml 中如下:
1 | <servlet> |
在 servlet 中读取:
1 | String user = getInitParameter("sql_user"); |
此外,DriverManager.getConnection方法还有两个实现,允许传入 url 的带有 user 和 password 参数或者使用 Properties 配置文件类传入参数来建立连接。
这些方法最终都调用了类中的 private 方法实现:
1 | private static Connection getConnection(String url, java.util.Properties info, Class<?> caller) |
使用 DataSource 建立Connection
比如使用 MysqlDataSource 类建立一个 Connection:
1 | MysqlDataSource dataSource = new MysqlDataSource(); |
另外,使用 org.apache.commons.dbcp.BasicDataSource 等开源库可以用 DataSource 建立一个连接池。
connection 使用完毕后应 close 释放资源。
执行语句
有三个相关的类,Statement、PreparedStatement 和 CallableStatement,后两个是 Statement 的子类。三者各有适合的场景。
Statement
Statement 构造的 sql 语句无法带参数,有以下常用方法:
1 | ResultSet executeQuery(String sql) |
可以返回一个结果集,适合查询操作 select 语句。
1 | int executeUpdate(String sql) |
适合 insert、update、delete 等操作,返回值为受影响的行数。
1 | boolean execute(String sql) |
适合执行一个 sql 语句后得到多个结果,或者 sql 语句将执行的操作未知。当得到的第一个结果是一个结果集 ResultSet 时,返回 true;是受影响个数时,返回 false。根据返回值接下来可以调用 getResultSet 方法或者 getUpdateCount 方法。
需要注意的是,注释中特别强调了,PreparedStatement 和 CallableStatement 不能使用此方法。
PreparedStatement
PreparedStatement 的特点是可以带有参数,这样方便重复使用。比如可以构造如下 update 语句:
1 | String sql = "UPDATE userinfo set user_name = ? WHERE user_id = ?"; |
构造的语句 sql 中,两个 ? 是可以替换的参数,使用 setXXX(int parameterIndex, XXX xxx)方法可以将第 parameterIndex 个 ? 替换为需要的值。
需要注意的是,如果要重复使用 PreparedStatement 语句实例传入不同参数,那么应先调用 clearParameters() 方法清楚之前的值。
CallableStatement
CallableStatement 用于调用在数据库中创建的存储过程。
所有的 Statement 对象都应该在使用完毕后 close。