1.什么是 JDBC?
JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),从根本上来说, JDBC 是一种 规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以 用 Java 编写不同类型的可 执行文件
有点像Java虚拟机,可以在不同操作系统运行java代码
2.JDBC体系结构
⾯向应⽤的 API,供程序员调⽤
⾯向数据库的 API,供⼚商开发数据库的驱动程序
3.常见JDBC组件
DriverManager :这个类管理一系列数据库驱动程序。匹配连接使用通信子协议从 JAVA 应用程序中请 求合适的数据库驱动程序。识别 JDBC 下某个子协议的第一驱动程序将被用于建立数据库连接。
取得连接
String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url,user,password);
Driver : 这个接口处理与数据库服务器的通信
加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
Connection : 此接口具有接触数据库的所有方法。该连接对象表示通信上下文,即,所有与数据库的通 信仅通过这个连接对象进行。
Connection conn = DriverManager.getConnection()
Statement : 使用创建于这个接口的对象将 SQL 语句提交到数据库。除了执行存储过程以外,一些派生 的接口也接受参数。
Statement st = conn.createStatement();
ResultSet : 在你使用语句对象执行 SQL 查询后,这些对象保存从数据获得的数据。它作为一个迭代 器,让您可以通过它的数据来移动。
ResultSet rs = st.executeQuery(sql);
SQLException : 这个类处理发生在数据库应用程序的任何错误。
步骤
最开始我们需要引入jar包
出现这种就代表成功了
我们是在idea里使用数据库,jar包是8的版本
举例---增删改查
查询操作-查询emp表的所有信息并输出name+empno
public class Test {
public static void main(String[] args) {
Statement statement = null;
ResultSet resultSet = null;
Connection connection = null;
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url,user,password);
//取得数据库操作对象
statement = connection.createStatement();
//执行sql
String sql = "select * from emp";
resultSet = statement.executeQuery(sql);
//输出
while (resultSet.next()){
System.out.println(resultSet.getString("ename")+" "+ resultSet.getInt("EMPNO"));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally {
//关闭流
if (resultSet != null) {
try {
resultSet.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();
}
}
}
}
}
查询结果(查询操作需要用对象接收,注意getString和getInt方法,所以用到了reaultSet,看看方法也会和下面三种不一样
修改操作 update t_user set username='zhangshang' where id = 1
我们在t-user表进行操作
核心代码,注意执行sql操作的那一步,和查询不一样了
public static void main(String[] args) {
Statement statement = null;
Connection connection = null;
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url,user,password);
//取得数据库操作对象
statement = connection.createStatement();
//执行sql
String sql = "update t_user set username='zhangshang' where id = 1";
int count = statement.executeUpdate(sql);
//输出
System.out.println(count==1?"成功":"失败");
效果(在这里我们可以看到控制台会输出成功,图片跳过了)
插入操作
和上面一样,把sql语句换一下就行了,除了和查询不一样,增加修改都是statement.executeUpdate来执行sql语句
删除操作
String sql = "delete form t_user where id = 6";
Statement 的⼦类 PreparedStatement,提供了 SQL 占位符的功能 使⽤ Statement 进⾏开发有两个问题:
1、需要频繁拼接 String 字符串,出错率较⾼。
2、存在 SQL 注⼊的⻛险。 SQL 注⼊:利⽤某些系统没有对⽤户输⼊的信息进⾏充分检测,在⽤户输⼊的数据中注⼊⾮法的 SQL 语句,从⽽利⽤系统的 SQL 引擎完成恶意⾏为的做法
我们先来写一个查询吧,看看怎么使用,注意我的查询语句有什么变化
public class Test {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url,user,password);
//用?来表示
String sql = "select ename from emp where ename like ?";
//取得数据库操作对象
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"_A%");
//执行查询语句
resultSet = preparedStatement.executeQuery();
//输出
while (resultSet.next()){
System.out.println(resultSet.getString("ename"));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally {
//关闭流
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
看看效果,上面的是我要查询的表
最后我们实现个登录验证,用到prepareStatement ,避免SQL注入等等问题,达到安全性效果
我们就拿最上面图片t_uer表来举例子
用户输入id 和 username 来判断是否是正确的
public class LoginCheckTest {
public static void main(String[] args) {
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
String user = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url,user,password);
//用?来表示
String sql = "select username from t_user where id = ? and username = ?";
//取得数据库操作对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//将用户输入的信息加上sql语句进行查询,看看能不能查到
Map<String,String> map = login();
String username = map.get("name");
String id = map.get("id");
preparedStatement.setString(1,id);
preparedStatement.setString(2,username);
//执行查询语句
ResultSet resultSet = preparedStatement.executeQuery();
//如果查得到,调用next()方法会返回true
if (resultSet.next()) {
System.out.println("成功");
}else {
System.out.println("失败");
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
public static Map<String,String> login(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入账号");
String id = sc.next();
System.out.println("请输入用户名");
String username = sc.next();
//创建Map集合并存入用户输入的账号用户名
Map map = new HashMap();
map.put("id",id);
map.put("name",username);
return map;
}
}
上面的代码忽略我没有关闭流,为了代码量不要太多在博客里
为了不让篇幅太长,下一节我们讲数据库连接池和DBUtils来使我们的程序更加优化,