本人小白一枚,欢迎大家一起讨论学习,如有错误,还望大家指教。
简述
JDBC即Java DataBase Connectivity(Java数据库连接),就是用Java语言操作数据库。
本质就是Sun公司定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这些接口,提供数据库驱动jar包。我们可以使用这套接口去编程,真正执行的代码是驱动jar包中的实现类。
使用 JDBC 的好处:
- 程序员如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。
- 使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库
下面的案例都是采用Mysql数据实现的。接下来我们简单了解下JDBC编程的步骤:
- 导入驱动jar包(我这里使用的是 mysql-connector-java-5.1.37-bin.jar,工具是idea别忘了Add As Libarary)
- 注册驱动
- 获取数据库连接对象Connection
- 定义sql
- 获取执行sql语句的对象Statement
- 执行sql,接收返回结果
- 处理结果
- 释放资源(释放原则:先开的后关,后开的先关。ResultSet – Statement – Connection )
未操作时的记录
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 定义sql,并将数据库中’张三‘修改为‘王五’,为了防止向数据库插入中文乱码问题,在数据库名称后面加上?characterEncoding=UTF-8
String sql = "update person set name = '王五' where id = 1";
// 获取连接时
Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc?characterEncoding=UTF-8", "root", "root");
// 获取执行sql的对象
Statement statement = connection.createStatement();
// 执行SQL并接受结果
int count = statement.executeUpdate(sql);
System.out.println(count);
// 关闭资源
statement.close();
connection.close();
}
执行后修改记录
下面可以详细了解一下各个对象的作用:
DriverManager:驱动管理对象
1、 用来注册驱动:就是通知程序该使用哪一个数据库驱动jar包。static void registerDriver(Driver drive);
上面我们用反射来注册驱动即:Class.forName("com.mysql.jdbc.Driver");
,我们可以猜出,当我们加载这个类,就会执行注册驱动的动作,那么该动作一定通过静态代码块来完成的,我们可以通过查看源码来证实。
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
2、获取数据库连接:
static Connection getConnection(String url, String user, String password)
- url:指定连接的路径
- 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
- 例子:jdbc:mysql://localhost:3306/db3
- 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
- user:用户名
- password:密码
Connection:数据库连接对象
1、获取执行sql的对象
- Statement createStatement()
- PreparedStatement prepareStatement(String sql)
2、 管理事务:
- 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
- 提交事务:commit()
- 回滚事务:rollback()
Statement:执行sql的对象
1、执行sql
boolean execute(String sql)
:可以执行任意的sql(只做简单了解)int executeUpdate(String sql)
:执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句。我们可以通过返回影响的行数来判断DML语句是否执行成功,返回值大于0的则执行成功,反之,则失败。ResultSet executeQuery(String sql)
:执行DQL(select)语句。
ResultSet:结果集对象,封装查询结果
- boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是则返回false,如果不是则返回true。
- getXxx(参数):获取数据:
- Xxx:代表数据类型 如: int getInt() , String getString()
- 参数:
- int:代表列的编号,从1开始 如: getString(1)
- String:代表列名称。 如: getDouble(“balance”)
案例:查询person表中所有记录,同时对异常进行处理,切记为了防止资源未释放,我们将释放的动作放在了finally中
person表的结构
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet result = null;
try {
Class.forName("com.mysql.jdbc.Driver");
// 定义sql,获取所有记录
String sql = "select * from person";
// 获取连接
connection = DriverManager.getConnection("jdbc:mysql:///jdbc?characterEncoding=UTF-8", "root", "root");
//获取执行sql的对象
statement = connection.createStatement();
// 执行SQL并接受结果
result = statement.executeQuery(sql);
while(result.next()) {
int id = result.getInt(1);
String name = result.getString("name");
int age = result.getInt(3);
System.out.println("id:" + id + "--" + "name:" + name + "--" + "age:" + age);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7. 释放资源
//避免空指针异常
if (result != null) {
try {
result.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
PreparedStatement:执行sql的对象
- PreparedStatement 是 Statement 接口的子接口,继承于父接口中所有的方法。
- 这个类的出现是为了解决sql注入问题:有一些sql的关键字参与字符串的拼接,那样会造成安全问题(例如输入用户随便,输入密码:a’ or ‘a’ = 'a)
- 这个类是通过预编译SQL来解决这个问题的,参数使用?作为占位符。例如
select * from user where username = ? and password = ?
- 我们通过?赋值,来完成参数的拼接。方法setXxx(index,param)。index:代表?位置编号,从1开始。param:?的值。
注意:一般我们在进行JDBC操作时,都会使用prepareStatement来完成增删改查的所有操作。
优点:1、防止SQL注入问题。2、效率更高