JDBC的常用类和接口
DriverManager :数据库驱动管理类。这个类的作用:
1)注册驱动;
2)创建java代码和数据库之间的连接,即获取Connection接口;
Connection: 是一个接口, 建立数据库连接的一个接口。
作用:建立数据库和java代码之间的连接。
Statement(接口)、PreparedStatement(接口)
作用:(解决安全隐患问题,比如sql注入的问题)
CallbackStatement(操作存储过程):
作用:数据库操作,向数据库发送sql语句。
ResultSet(接口): 结果集。
作用:Statement 发送sql语句,得到的结果 封装在 ResultSet 中。
JDBC-API详解
1) DriverManager 驱动管理类介绍
DriverManager驱动管理类的作用:
Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接。
使用DriverManager类的静态方法可以注册数据库驱动,
这个静态方法是:registerDriver(),如下所示:
static void registerDriver(Driver driver) 向 DriverManager 注册给定驱动程序
// 注册驱动代码 这里的new Driver()的类Driver就是来自mysql数据库。
DriverManager.registerDriver(new Driver());
注意:在实际开发中并不推荐采用registerDriver方法注册驱动。 原因:
虽然 DriverManager.registerDriver(new com.mysql.jdbc.Driver())方法可以注册
驱动,但会使数据库驱动注册两次。
Drive.class源码中有如下static静态代码块:
当我们在创建Driver类的对象时就会加载静态代码块中的代码。
这时我们就会很明显发现,静态代码块中的代码与我们之前自已写的注册驱动 的方式重复了。
针对上面的注册驱动重复的问题,我们可以思考:我们只需要执行Driver.class中静态代码块
中的代码就行了。那么我们如何做才能让静态代码块执行呢?
当类加载到内存中的时候,静态代码块就会执行。
所以我们只需要让Driver.class加载到内存中就可以达到我们的目的了。
想要让Driver.class类加载到内存中,并给类进行初始化,可以使用反射技术。
所以注册驱动的方式最终使用如下代码:
Class.forName("com.mysql.jdbc.Driver");
说明:上述这种方式可以在加载驱动类的时候,会自动执行静态代码块static中的内容。
也就相当于实现了数据库驱动的注册。
2) Connection详解
URL介绍:指定一个具体的数据库
使用DriverManager类中的getConnection(url,user,password)方法和mysql数据库建立连接。
url :连接到具体的数据库的地址。
user : 数据库用户名。
password : 数据库密码。
举例:
Connection con = DriverManager.getConnection
(“jdbc:mysql://localhost:数据库端口/数据库名”, “root”, “123”);
作用:URL用于标识数据库的位置,程序员通过URL地址告诉JDBC程序连接哪个数据库。
语法格式:jdbc:mysql:// localhost:3306/数据库名
上述地址的简写形式:jdbc:mysql:///数据库名 等价于 jdbc:mysql://localhost:3306/数据库名
简写要求:必须是本地数据库,即ip位置必须是localhost或者 127.0.0.1
而端口号必须是3306.不建议使用简写方式.
属性:useUnicode=true&characterEncoding=utf8(很少使用)
是否使用Unicode字符集,如果本参数值设置为true,表示是。
解决问题:如果是java代码操作数据库时发生中文乱码问题,我们可以按照如下格式来解决。
举例:
jdbc: mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8
获取数据库连接Connction的方法:
Connection con = DriverManager.getConnection(url, user, password);
url:连接到某一个具体的数据库的地址。
user:数据库的用户名。
password:数据库用户名对应的密码。
注意:获取连接时导入的包是java.sql.Connection;
Jdbc程序中的Connection,它用于代表数据库的链接,
Connection是数据库编程中最重要的一个对象,
客户端与数据库所有交互都是通过connection对象完成的.
Connection常用方法:
createStatement():创建向数据库发送sql的statement对象;
Statement conn.createStatement() 该对象可以将SQL发送给数据库进行执行 ;
PreparedStatement conn.preparedStatement(sql) 对SQL语句进行预编译,防止SQL注入;
3) Statement 详解
当我们得到向数据库发送sql的statement对象之后,
我们就可以将sql语句发送给数据库,让数据库执行sql语句了。
目标:向数据库发送sql,获得执行结果。
3.1 executeQuery(sql)
Statement接口中的方法:
如果发送的是select语句,那么我们必须使用 Statement接口中的方法executeQuery(sql)将 sql语句发送给数据库执行。
当然了,我们执行了select语句,我们必须得知道select语句执行的查询结果,
executeQuery(sql)返回值就是select语句的查询结果。返回值类型为ResultSet类型。
用于向数据库发送 select 语句,返回ResultSet 结果集对象.
例:
String sql = “select * from user”;
ResultSet rs = st.executeQuery(sql);
3.2 executeUpdate(sql)
Statement接口中的方法:
当然除了向数据库发送select语句,我们有时还需要向数据库发送增(insert )删( delete)改(update )语句,
那么这时候必须要使用Statement接口中的方法executeUpdate(sql),
此方法用于向数据库发送非select语句。方法的返回值为int 类型参数,
代表sql语句影响记录行数。
举例:
String sql = “update user set password=‘abcdef’”;
int sum = stmt.executeUpdate(sql);
如果不加条件会修改数据库所有数据,一共修改三条,因此返回值为3。
如果添加 where id = 1 就会修改1行记录。 此时返回值为1。
总结:
executeQuery(sql) 执行select语句。
executeUpdate(sql) 执行insert update delete 语句。
4) ResultSet 结果集
4.1 如何遍历结果集
遍历的原理:
结果集其实就是一张表。那么在java中怎么遍历这个表呢?
首先,ResultSet结果集有一个光标,一开始这个光标处于数据表的第一行数据之前。
而我们可以通过ResultSet接口中的next()方法将光标下移。
如果说,光标所指向的当前行有数据的话,那么会返回true,
如果没有值的话,那么会返回false。
基于这样一个情况,我们可以通过 while(rs.next())的方式对ResultSet做遍历。
一直到光标所在行没有数据的话,结束遍历。
注意:根据数据库内部列类型,选择相应 getXXX方法来获取数据。
while( rs.next() )
{
int ---- getInt()
varchar ---- getString()
date ----- getDate()
}
4.2 如何从结果集取出数据,并且转化对应的数据类型
那么会了如何遍历结果集,我们需要解决的就是如何获取结果集中的数据?
需要注意的是:每一次循环遍历我们获取的是表中的一行数据。
我们获取一行中的任何列中的值,可以通过如下的方法:
getXXX(列名/下标);
XXX指的是表中的列在java中对应数据类型.
如果某一列是varchar,java中对应的就是String.
如果某一列是int,java中对应的就是int.
参数可以是列的名称,可以是列所在的索引(索引从1开始).
两种方式说明如下所示:
方式1: getInt(index 结果集中列索引) 注意:索引从1开始。
getInt(1) – > 取出第一列的内容,转成 整形 返回
方式2:getString(列名 或者 列的别名)
getString(“username”); – > 取出列名为 username 的内容,转成 字符串 返回。
//假如有表如下:
id | username | password |
---|---|---|
1 | zhangsan | 123 |
对于上图中的一行数据,我要获取username为zhangsan这列的值,
有如下2种写法:
4.2.1) rs.getString(“username”); 通过列名获取该列的值。
4.2.2) rs.getString(2); 通过username列所在的第二个位置获取该列的值。
JDBC 编程步骤总结:(六步)
1) 注册驱动
class.forName(“com.mysql.jdbc.Driver”); // JDBC4.0以后该步骤可以省略
2) 获得数据库连接
Connection conn =DriverManager.getConnection(url,user,password);
3) 创建向数据库发送sql的statement对象
Statement stmt = conn.CreateStatement();
4) 向数据库发送sql
ResultSet rs = stmt.executeQuery(sql); //select 语句
int updateSum = stmt.executeUpdate(sql); // insert\update\delete 语句
5) 处理结果集
while(re.next()){
rs.getString(列名 或 列的别名)
rs.getInt(别名)
}
6) 关闭资源
rs.close;
stmt.close;
conn.close;
JDBC工具类
在上面的学习过程中,我们发现我们有很多重复的操作。
那么这样一方面来说对我们开发带来了不便,更多的时候是当我遇到如下的问题:
数据库的用户名发生了变化,这时候我们发现,我们需要修改每处获取连接的用户名参数。
这样是对于我们后期的维护是非常繁琐的。所以我们需要对jdbc操作数据库的步骤的一些常用的方法抽出来,放到一个外部的工具类中。
JDBC工具类JDBCUtils (Demo版本)
例:
public class JDBCUtilsDemo {
static String url = null;
static String user = null;
static String password = null;
static {
try {
//通过properties对象读取到外部配置的内容
Properties prop = new Properties();
FileInputStream is = new FileInputStream("jdbc.properties");
// 加载外部的配置文件
prop.load(is);
// 读取外部配置文件的内容
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
}
}
//获得连接方法
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//释放资源方法
public static void release(Connection conn, Statement st, ResultSet rs) {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (st != null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}