1、什么是JDBC
1.1 什么是JDBC
- JDBC(Java Database Connectivity)Java连接数据库规范(标准),可以使用java语言连接数据库完成CRUD操作
- JDBC API允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据
- 从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 Java编写不同类型的可执行文件,例如:
- Java 应用程序
- Java Applets
- Java Servlets
- Java ServerPages(JSPs)
- Enterprise JavaBeans (EJBs)
- 所有这些不同的可执行文件就可以使用 JDBC
驱动程序来访问数据库,这样可以方便的访问数据。 JDBC 具有 ODBC 一样的性能,允许 Java 程序包含与数据库无关的代码。
1.2 JDBC架构
- JDBC 的 API 支持两层和三层处理模式进行数据库访问,但一般的 JDBC 架构由两层处理模式组成:
- JDBC API: 提供了应用程序对 JDBC 管理器的连接。
- JDBC Driver API: 提供了 JDBC 管理器对驱动程序连接。
- JDBC API 使用驱动程序管理器和数据库特定的驱动程序来提供异构(heterogeneous)数据库的透明连接。
- JDBC 驱动程序管理器可确保正确的驱动程序来访问每个数据源。该驱动程序管理器能够支持连接到多个异构数据库的多个并发的驱动程序。
以下是结构图,其中显示了驱动程序管理器相对于在 JDBC 驱动程序和 Java 应用程序所处的位置。
1.3 常用JDBC API
JDBC 是由多个接口和类进行功能实现。
类型 | 权限定名 | 简介 |
---|---|---|
class | java.sql.DriverManager | 管理多个数据库驱动类,提供了获取数据库连接的方法(用于获取连接对象) |
interface | java.sql.Connection | 代表一个数据库连接(当connection不是null时,表示已连接数据库(用于获取操作对象)) |
interface | java.sql.Statement | 发送SQL语句到数据库工具 (用于执行sql语句) |
interface | java.sql.ResultSet | 保存SQL查询语句的结果数据(结果集) |
class | java.sql.SQLException | 处理数据库应用程序时所发生的异常 |
1.4 环境搭建
- 在项目下新建 lib 文件夹,用于存放 jar 文件。
- 将 mysql 驱动复制到项目的 lib 文件夹中。
- 选中 lib 文件夹右键 Add as Libraay,点击 OK。
2、使用JDBC开发
2.1 加载驱动
使用 Class.forName(“com.mysql.jdbc.Driver”);手动加载字节码文件到 JVM 中。
Class.forName("com.mysql.jdbc.Driver");//加载驱动
2.1 获取连接对象
- 通过 DriverManager.getConnection(url,user,password) 获取数据库连接对象
- URL:jdbc:mysql://localhost:3306/wzy
- username:root
- password:root
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/wzy?useUnicode=true&characterEncoding=utf8", "root","root");
2.1 获取操作对象
//通过连接对象获取操作对象
Statement statement = connection.createStatement();
2.1 执行sql语句
执行语句分两种,
- 一种是executeUpdate,用于执行DML语句。返回的数据是int类型的户数,表示执行sql语句后,影响数据库数据的数量
ResultSet resultSet = statement.executeQuery("select * from user where is_delete=1 or is_delete=0");
- 另一种是executeQuery,用于执行DQL语句。返回的是一个数组集合,存储着从数据库返回的数据表。可用于后端数据处理
String sql = "insert into user (username,password,sex,hobbies,addrs,is_delete) values " +
"('wss','123','男','吃饭','广西',1)," +
"('wss','123','男','聊天','广西',1)";
int i = statement.executeUpdate(sql);
2.1 处理结果
//创建一个泛型为User的ArrayList对象
List<User> list = new ArrayList<>();
User user;
while (resultSet.next()){
//根据字段名获取数据库对应的数据
//使用此方法的前提是,需要知道数据库表的字段
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String sex = resultSet.getString("sex");
String hobbies = resultSet.getString("hobbies");
String addrs = resultSet.getString("addrs");
/*
//根据字段的索引获取数据,索引从1开始
//当不知道数据库的字段时,可以使用此种方法
int id = resultSet.getInt(1);
String username = resultSet.getString(2);
String password = resultSet.getString(3);
String sex = resultSet.getString(4);
String hobbies = resultSet.getString(5);
String addrs = resultSet.getString(6);
*/
user = new User(id,username,password,sex,hobbies,addrs);
list.add(user);
}
2.1 关闭资源
遵循先开后关原则,释放所使用到的资源对象。
statement.close();
conn.close();
2.1 综合案例
- 向数据库中插入数据
- 查询wzy数据库中,user表里的数据
package com.qf.wzy.entity;
/**
* @Author wzy
* @Date 0007 2021-01-07 16:00
* @Version 1.0
*
* 实体类
* 用于接收来自数据库的各种参数,构建成一份数据模板
*/
public class User {
private Integer id;
private String username;
private String password;
private String sex;
private String hobbies;
private String addrs;
public User() {
}
public User(Integer id, String username, String password, String sex, String hobbies, String addrs) {
this.id = id;
this.username = username;
this.password = password;
this.sex = sex;
this.hobbies = hobbies;
this.addrs = addrs;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getHobbies() {
return hobbies;
}
public void setHobbies(String hobbies) {
this.hobbies = hobbies;
}
public String getAddrs() {
return addrs;
}
public void setAddrs(String addrs) {
this.addrs = addrs;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", sex='" + sex + '\'' +
", hobbies='" + hobbies + '\'' +
", addrs='" + addrs + '\'' +
'}';
}
}
package com.qf.wzy.utils;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
* @Author wzy
* @Date 0007 2021-01-07 17:18
* @Version 1.0
*
* 封装常用到的各种工具类方法
*/
public class DButils {
private static String className=null;
private static String url=null;
private static String username=null;
private static String password=null;
static {
Properties properties = new Properties();
try {
properties.load(DButils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
className = properties.getProperty("className");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
}
//封装连接对象的方法
public static Connection getConnection(){
//定义连接对象
Connection connection=null;
//通过DriverManger获取连接对象
try {
//加载驱动
Class.forName(className);
//调用DriverManager的getConnection获取连接对象
connection = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//返回连接对象
return connection;
}
public static void closeAll(AutoCloseable ... closeables){
for (AutoCloseable closeable:closeables) {
if (closeable!=null){
try {
closeable.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
package com.qf.wzy.dao;
import com.qf.wzy.entity.User;
/**
* @Author wzy
* @Date 0007 2021-01-07 17:50
* @Version 1.0
*
* 接口,用于数据访问层的类继承
*/
public interface IUserDao {
//添加用户
void addUser(User user);
//查看用户名是否存在
int checkUsername(String username);
}
package com.qf.wzy.dao.impl;
import com.qf.wzy.dao.IUserDao;
import com.qf.wzy.entity.User;
import com.qf.wzy.utils.DButils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Author wzy
* @Date 0007 2021-01-07 17:51
* @Version 1.0
*
* 数据访问层
* 封装操作数据库的方法,并返回操作结果给业务访问层处理
*/
public class UserDaoImpl implements IUserDao {
@Override
public void addUser(User user) {
}
@Override
public int checkUsername(String username) {
Connection connection=null;
PreparedStatement ps=null;
ResultSet resultSet=null;
int count=0;
try {
connection = DButils.getConnection();
//通过预处理处理sql语句,并返回预处理对象,?代表占位符
//此刻预处理的原因是防止sql注入攻击
ps = connection.prepareStatement("select count(*) from user where username=?");
//对占位符进行复制,第一个参数是占位符的索引(从1开始),第二个参数是赋予占位符的值
ps.setString(1,username);
resultSet = ps.executeQuery();
if (resultSet.next()){
//获取查询到呃
count=resultSet.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DButils.closeAll(connection,ps,resultSet);
}
return count;
}
}
package com.qf.wzy.jdbc;
import com.qf.wzy.entity.User;
import com.qf.wzy.utils.DButils;
import org.junit.Test;
import sun.security.pkcs11.Secmod;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @Author wzy
* @Date 0007 2021-01-07 15:37
* @Version 1.0
*
*
*/
public class Demo01 {
/**
* 插入数据
* @throws Exception
*/
@Test
public void test1() throws Exception {
//加载数据库连接驱动
Connection connection = DButils.getConnection();
//通过连接对象获取操作对象
Statement statement = connection.createStatement();
//通过操作对象执行sql语句,并返回打印结果集
String sql = "insert into user (username,password,sex,hobbies,addrs,is_delete) values " +
"('wss','123','男','吃饭','广西',1)," +
"('wss','123','男','聊天','广西',1)";
int i = statement.executeUpdate(sql);
if (i!=0){
System.out.println("添加成功, "+i+" 条数据被添加!");
}else {
System.out.println("添加失败, 0 条数据被添加!");
}
//关闭资源
/*connection.close();
statement.close();*/
DButils.closeAll(connection,statement);
}
/**
* 查询数据
* @throws Exception
*/
@Test
public void test2() throws Exception {
//调用DButils类封装的getConnection方法获取连接对象
Connection connection = DButils.getConnection();
//获取操作对象
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from user where is_delete=1 or is_delete=0");
//创建一个泛型为User的ArrayList对象
List<User> list = new ArrayList<>();
User user;
while (resultSet.next()){
//根据字段名获取数据库对应的数据
//使用此方法的前提是,需要知道数据库表的字段
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String sex = resultSet.getString("sex");
String hobbies = resultSet.getString("hobbies");
String addrs = resultSet.getString("addrs");
/*
//根据字段的索引获取数据,索引从1开始
//当不知道数据库的字段时,可以使用此种方法
int id = resultSet.getInt(1);
String username = resultSet.getString(2);
String password = resultSet.getString(3);
String sex = resultSet.getString(4);
String hobbies = resultSet.getString(5);
String addrs = resultSet.getString(6);
*/
user = new User(id,username,password,sex,hobbies,addrs);
list.add(user);
}
//关闭资源
DButils.closeAll(statement,connection,resultSet);
if (list.size()>0){
//遍历list输出查询数据
for (User u:list) {
System.out.println(u);
}
System.out.println("查询完毕,共有 " +list.size()+" 条数据" );
}
else {
System.out.println("查询失败");
}
}
/**
* 更新数据
* @throws SQLException
*/
@Test
public void test4() throws SQLException {
Connection connection = DButils.getConnection();
Statement statement = connection.createStatement();
String update_sql = "update user set password='123456' where is_delete=0";
int i = statement.executeUpdate(update_sql);
if (i!=0){
System.out.println("更新成功, "+i+" 条数据被更新!");
}
else {
System.out.println("查无符合数据,更新失败!");
}
//关闭资源
DButils.closeAll(connection,statement);
}
/**
* 删除数据
*/
@Test
public void test3() throws Exception {
Connection connection = DButils.getConnection();
Statement statement = connection.createStatement();
String delete_sql = "delete from user where username='wss'";
int i = statement.executeUpdate(delete_sql);
if (i!=0){
System.out.println("删除成功, "+i+" 条数据被删除!");
}
else {
System.out.println("查无符合数据,删除失败!");
}
//关闭资源
DButils.closeAll(connection,statement);
}
}
数据库连接配置
- className:数据库驱动名称
- url:数据库地址
- username:数据库账户名
- password:数据库密码
className=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/wzy?characterEncoding=utf8
username=root
password=root