JDBC的增删改查
知不知道JDBC增删改查操作中只有查询需要处理结果集
前言
JDBC编程步骤❗:
- 加载数据库驱动程序 class
- 创建数据库连接对象 Connection
- 创建Statement语句对象(createStatement、prepareStatement)
- 执行SQL语句
- 处理结果集(只有查询需要)
- 释放资源 close
JDBC 的主要作用是连接 Java 数据库连接,使用它可以在Java程序中执行数据库的SQL语句
JDBC 是由 Java 语言定义接口和数据库厂商提供实现类组成。
用到的接口有:
● Connection
:特定数据库的连接,在连接上下文中执行SQL语句并返回结果。
● Statement
:用于执行静态SQL语句并返回它所生成结果的对象。
● PreparedStatement
:表示预编译的SQL语句的对象,继承并扩展了Statement接口。
● ResultSet
:装载数据库结果集的接口。
创建数据库
提示:下面所有代码的实现都是基于此数据库
CREATE TABLE user (
id int(4) PRIMARY KEY auto_increment, -- 用户ID 主键 不需要强调非空
name varchar(20) NOT NULL, -- 用户姓名 非空
email varchar(50) NOT NULL UNIQUE, -- 用户邮箱 非空 唯一
phone varchar(20) NOT NULL UNIQUE, -- 用户电话 非空 唯一
birth date NOT NULL -- 用户生日 非空
);
在上面创建语句中,约束应该大写,因此 PRIMARY KEY、NOT NULL、UNIQUE 应该全部大写。
在Eclipse中新建Java项目,然后新建文件夹取名lib,放入jar包
以下是MySQL8版本的代码
随后右键放入的jar包,选择构建路径→添加至配置路径
选择完后就会看到多一个引用的库
随后新建src新建包和类
基础版
JDBC实例添加
//所有导入的包都是java.sql的
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class InsertDemo {
public static void main(String[] args) throws Exception {
//JDBC编程步骤
//1、加载数据库驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
//2、创建数据库连接对象
//传入三个参数 数据库的URL、用户名、密码
//每种数据库驱动程序的名字和数据库URL的写法都不同
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user?characterEncoding=utf8&serverTimezone=Asia/Shanghai","root","123456");
System.out.println(connection);
//3、创建Statement语句对象
Statement statement = connection.createStatement();
//4.执行SQL语句
//如果执行的是增加 删除 修改语句 ,调用exceuteUpdate,返回值是整数,代表的是影响数据库的行的数量
//如果执行的是查询语句,调用的是executeQuery 返回值是结果集
int rows = statement.executeUpdate("insert into user values(4,'赵六','124502@qq.com','12781200101','2019-08-11')");
System.out.println(rows); //rows拿到影响数据库的行数
//5、处理结果集
//插入语句不需要
//6、释放资源
//连接、语句、结果集需要释放,调用close方法,先创建的后释放
statement.close();
connection.close();
}
}
运行结果:
Navicat中的显示:
以此类推我们改个id和其他几个字段数据,多添加几条
JDBC实例删除
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class DeleteDemo {
public static void main(String[] args) throws Exception {
//1、加载数据库驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
//2、创建数据库连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user?characterEncoding=utf8&serverTimezone=Asia/Shanghai","root","123456");
//3、创建Statement语句对象
Statement statement = connection.createStatement();
//4、执行SQL语句
int rows = statement.executeUpdate("delete from user where id=1"); //删除id是1的数据
System.out.println(rows);
//5、处理结果集,这里没有
//6、释放资源
statement.close();
connection.close();
}
}
运行结果
删到最后控制台就是0了
JDBC实例修改
修改按照上述方法也可以改,但我们接下来换个方法,给他封装一下
把第一步和第二步、第六步封装一下
接下来定义一个JDBC的工具类封装一下
这里是新建了一个包和类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcUtil {
//加载驱动程序和创建数据库连接,封装到一个静态代码方法里
public static Connection createConnection() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//这里不再抛出异常,而是包围它
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user?characterEncoding=utf8&serverTimezone=Asia/Shanghai","root","123456");
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return connection;
}
//释放资源,封装到静态方法中,方便调用
public static void close(Statement statement,Connection connection) {
try {
statement.close();
connection.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
回到之前的包,新建修改类
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import com.jdbc.work.util.JdbcUtil;
public class UpdateDemo {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
//刚才封装到了静态方法里面,这里直接调用
connection = JdbcUtil.createConnection();
try {
statement=connection.createStatement(); //这里异常也用try...catch
int rows = statement.executeUpdate("update user set name='王朝',email='74123@163.com' where id=2"); //修改编号为2的用户姓名与邮箱
System.out.println(rows);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
JdbcUtil.close(statement, connection);
} //释放资源放在finally块里,无论try内代码是否有异常,finally块内代码都会运行
}
}
JDBC实例查询
只有查询用到了结果集,我们在JdbcUtil类中再写一个方法,把结果集加进去
public static void close(ResultSet resultSet,Statement statement,Connection connection) {
//重载
try {
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
// 包围方式 自动生成的 catch 块
e.printStackTrace();
}
}
下面代码是查询方法
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import com.jdbc.work.util.JdbcUtil;
public class QueryDemo {
public static void main(String[] args) {
Connection connection = null; //连接
Statement statement = null; //语句
ResultSet resultSet = null; //结果集,只有查询需要
connection = JdbcUtil.createConnection(); //创建连接
try {
statement = connection.createStatement();
resultSet = statement.executeQuery(" select * from user ");
//5.处理结果集
//处理结果集其实就是从结果集中将数据取出使用
//使用while循环语句 次数不固定,先判断
//结果集next方法判断是否有数据行
while(resultSet.next()) {
//查询语句中查询几列就需要取出几列数据
//取数据调用结果集中的getXXX方法
//数据库中列是整数类型 --- getInt
//数据库中列是浮点数类型 float double decimal--- getDouble
//数据库中是日期类型 ---- getDate
//数据库中是字符型 char varchar ---getString
int id = resultSet.getInt("id"); //1:第几个数据.最好放列名
String name = resultSet.getString("name");
String email = resultSet.getString("email");
String phone = resultSet.getString("phone");
Date birth = resultSet.getDate("birth");
System.out.println(id+"\t"+name+"\t"+email+"\t"+phone+"\t"+birth);
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
JdbcUtil.close(resultSet,statement, connection);
}
}
}
控制台结果:
高级版
上面的数据是写在代码内的,但是我们应该让他是个变量的
这里用到了prepareStatement
它是Statement子接口,预编译语句
因为Statement会引起SQL注入问题,同时变量的拼接很不方便
JDBC实例添加
第一种方法:
所用到的方法均作为笔记写在了注释内
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import com.jdbc.work.util.JdbcUtil;
public class InsertDemo {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
//它是Statement子接口,预编译语句
//Statement会引起SQL注入问题,同时变量的拼接很不方便
connection = JdbcUtil.createConnection();
//调用prepareStatement方法创建预编译语句对象
//传入执行的SQL语句,SQL语句中的数据部分替换成?
try {
preparedStatement = connection.prepareStatement("insert into user values(?,?,?,?,?)");
//预编译语句执行前,必须给所有?赋值
//调用PreparedStatement(预编译)语句中的setXXX方法,类似于结果集中的getXXX对应
Scanner scanner = new Scanner(System.in);
int id;
String name;
String email;
String phone;
String birth;
System.out.println("请输入用户id");
id = scanner.nextInt();
System.out.println("请输入用户姓名");
name = scanner.next();
System.out.println("请输入用户邮箱");
email = scanner.next();
System.out.println("请输入用户电话");
phone = scanner.next();
System.out.println("请输入用户生日");
birth = scanner.next(); //需要转换,现在是字符串
//调用setXXX方法,从左向右方向依次给?赋值
preparedStatement.setInt(1, id);
//赋值时问号的序号从1开始,数据库是个特例
preparedStatement.setString(2, name);
preparedStatement.setString(3, email);
preparedStatement.setString(4, phone);
//类型转换 把date类型转换成String类型
//1.将String类型转换成java.util.Date类型
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d1 = sdf.parse(birth); //倒包:java.util
//2.将java.util.Date类型转换成java.sql.Date
java.sql.Date d2 = new java.sql.Date(d1.getTime()); //完整包名加上
preparedStatement.setDate(5, d2);
//预编译执行和普通语句执行的方法一致
//执行时不需要再次指定SQL语句
int rows = preparedStatement.executeUpdate();
System.out.println(rows);
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
JdbcUtil.close(preparedStatement, connection);
}
}
}
输出结果:
运行时在控制台实现
第二种方法:
根据上面增加的例子我们可以看到date类型转换需要两步,比较麻烦
应该把转换代码封装一下,方便使用
我们依旧在JdbcUtil类中封装
//String类型转换为java.sql.Data类型封装到一个方法里
public static java.sql.Date toSqlDate(String string){
java.util.Date d1 = null;
java.sql.Date d2 = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
d1 = sdf.parse(string);
d2 = new java.sql.Date(d1.getTime()); //try...catch后写第二次转换
} catch (ParseException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return d2; //转换后结果的返回
}
那现在上面写的InsertDemo(添加)内的转换代码就不需要了,可以删除
第五条preparedStatement
方法需要调用一下方法,拿到转换后的SqlDate
,把birth
字符串传进去:
preparedStatement.setDate(5, JdbcUtil.toSqlDate(birth));
另外,在JdbcUtil内的加载驱动程序代码在实际运行中只运行了一次
在方法前面加上静态代码块,静态代码块的代码在程序中只会运行一次,所以把try…catch内的代码放在static静态代码块中
最后JdbcUtil类中代码为:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class JdbcUtil {
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//这里不再抛出异常,而是包围它
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//加载驱动程序和创建数据库连接,封装到一个静态代码方法里
public static Connection createConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user?characterEncoding=utf8&serverTimezone=Asia/Shanghai","root","123456");
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return connection;
}
//释放资源,封装到静态方法中,方便调用
public static void close(Statement statement,Connection connection) {
try {
statement.close();
connection.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static void close(ResultSet resultSet,Statement statement,Connection connection) {
//重载
try {
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//String类型转换为java.sql.Data类型封装到一个方法里
public static java.sql.Date toSqlDate(String string){
java.util.Date d1 = null;
java.sql.Date d2 = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
d1 = sdf.parse(string);
d2 = new java.sql.Date(d1.getTime());
} catch (ParseException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return d2;
}
}
再次运行添加
JDBC实例删除
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
import com.jdbc.work.util.JdbcUtil;
public class DeleteDemo {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
Scanner scanner = new Scanner(System.in);
connection = JdbcUtil.createConnection();
try {
preparedStatement = connection.prepareStatement("delete from user where id=?");
System.out.println("请输入删除的用户id");
int id = scanner.nextInt();
preparedStatement.setInt(1, id);
int rows = preparedStatement.executeUpdate();
System.out.println(rows);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} finally {
JdbcUtil.close(preparedStatement, connection);
}
}
}
运行结果
JDBC实例修改
根据ID值改其他条件
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
import com.jdbc.work.util.JdbcUtil;
public class UpdateDemo {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
Scanner scanner = new Scanner(System.in);
connection = JdbcUtil.createConnection();
try {
preparedStatement = connection.prepareStatement("update user set name = ?,email=?,phone=?,birth=? where id=?");
int id,age;
String name,birth,pwd;
System.out.println("请输入需要修改的用户id");
id = scanner.nextInt();
System.out.println("请输入修改后的用户名");
name = scanner.next();
System.out.println("请输入修改后的用户邮箱");
String email = scanner.next();
System.out.println("请输入修改后的用户电话");
String phone = scanner.next();
System.out.println("请输入修改后的用户生日");
birth = scanner.next();
preparedStatement.setString(1, name);
preparedStatement.setString(2, email);
preparedStatement.setString(3, phone);
preparedStatement.setDate(4, JdbcUtil.toSqlDate(birth));
preparedStatement.setInt(5, id);
int rows = preparedStatement.executeUpdate();
System.out.println(rows);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
JdbcUtil.close(preparedStatement, connection);
}
}
}
输出结果:
JDBC实例查询
模糊查询
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import com.jdbc.work.util.JdbcUtil;
public class QueryDemo {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Scanner scanner = new Scanner(System.in);
connection = JdbcUtil.createConnection();
try {
preparedStatement = connection.prepareStatement("select * from user where name like ?");
System.out.println("请输入查询的用户名(支持模糊查询)");
String name = scanner.next();
preparedStatement.setString(1, "%"+name+"%");
resultSet = preparedStatement.executeQuery();
//处理结果集
while(resultSet.next()) {
int id = resultSet.getInt("id");
name = resultSet.getString("name");
String email = resultSet.getString("email");
String phone = resultSet.getString("phone");
Date birth = resultSet.getDate("birth");
System.out.println(id+"\t"+name+"\t"+email+"\t"+phone+"\t"+birth);
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
JdbcUtil.close(resultSet, preparedStatement, connection);
}
}
}
这里为了输出美观,已提前在Navicat内更改了数据
输入要查询的数据:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)