今天我们将探讨如何使用Java数据库连接(JDBC)在控制台上进行简单的增删改查操作。数据库是现代应用程序的重要组成部分,因此了解如何与其进行交互是非常有用的技能。JDBC是Java开发中使用最广泛的数据库API,它提供了一种标准的方式来连接和管理各种类型的数据库。在本文中,我们将介绍如何使用JDBC API连接到数据库,执行基本的增删改查操作,并关闭连接,以确保数据的安全性。无论您是新手还是有经验的开发人员,本文都将为您提供有用的信息和指导,让您能够轻松地在控制台上操作数据库。
本篇中部分内容在我发的其他博客中已经介绍过,错过的小伙伴可通过点击以下链接快速了解相关内容
JDBC中java与数据库的连接-CSDN
要想在IDEA的控制台对数据库进行操作,连接数据库是必须的,在这里,我会将IDEA连接数据库的操作一一列出来并做部分讲解
注册驱动有两种方法,第一种方法我并不推荐
DriverManager.registerDriver(new Driver());
DriverManager.registerDriver(new Driver())是Java中用于注册JDBC驱动程序的代码。JDBC驱动程序是用于连接Java应用程序和各种数据库的组件。在此代码中,DriverManager调用registerDriver方法来注册Driver类的实例,该实例是一个JDBC驱动程序的实现。这样,该驱动程序就可以在应用程序中被使用,并且可以用来连接和操作数据库。
但是用这种方法连接驱动会导致连接多次,因为在registeDriver方法内部是有注册驱动的代码的,而在new Driver()中也是有驱动注册的代码,使用该方法会导致多次注册驱动从而影响整个代码的运行能力,所以我们不推荐这种方法
public static void registerDriver(java.sql.Driver driver)
throws SQLException {
//驱动就是在这注册的
registerDriver(driver, null);
}
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
//在这里又出现了registerDriver方法
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
Class.forName("com.mysql.cj.jdbc.Driver");
第二种方法是使用Class.forNam()方法,也是我所推荐的方法;这行代码的作用是动态加载 MySQL 数据库的 JDBC 驱动程序。在 Java 应用程序中,需要使用 JDBC 驱动程序才能连接和操作数据库。而为了使用 JDBC 驱动程序,需要先将其加载到应用程序的内存中。通过 Class.forName() 方法动态加载 JDBC 驱动程序可以避免在程序运行时静态加载所有可能用到的类,从而减少了内存的消耗。
而Class.forNam()方法中的参数就是是 MySQL 数据库的 JDBC 驱动程序的类名,值得一提的是,如果你使用的是版本号为5的驱动版本的话,那么MySQL 数据库的 JDBC 驱动程序的类名就是com.mysql.jdbc.Driver,而如果你使用的版本号为8的驱动版本的话,那么MySQL 数据库的 JDBC 驱动程序的类名就是com.mysql.cj.jdbc.Driver
Connection connection = DriverManager.getConnection("jdbc:mysql:///数据库名", "账号名", "密码");
这行代码使用Java中的JDBC(Java数据库连接) API连接到MySQL数据库中,它创建了一个名为“connection”的对象,该对象表示与数据库的连接,可以用于执行查询和更新等操作。
在这里你可以会奇怪DriverManager.getConnection()方法有一个参数、两个参数和三个参数,其实它们表达的意思都一样,我个人推荐三个参数的方法
String sql = "select * from t_user where username = ? and password = ?";
这行代码是一个 SQL 查询语句,用于在数据库表 t_user 中根据指定的用户名和密码来查询用户信息。其中,问号 ? 表示占位符,用于在执行查询语句时动态地替换成实际的参数值。这种写法可以避免 SQL 注入等安全问题,提高代码的可读性和可维护性。
PreparedStatement preparedStatement = connection.prepareStatement(sql);
PreparedStatement是在Java中用于执行预编译SQL语句的接口。它通过在执行之前将占位符替换为实际参数值,从而提高了执行效率和安全性。在使用PreparedStatement时,首先需要通过Connection接口的prepareStatement()方法创建一个PreparedStatement对象,并将需要执行的SQL语句作为参数传入。接着,可以使用setXXX()方法设置占位符的参数值,最后调用execute()或executeQuery()方法执行SQL语句并返回结果。这种方式能够避免SQL注入攻击,并且能够重复使用已编译的SQL语句,提高了程序的性能。
preparedStatement.setObject(占位符的位置 从1开始,需要赋的值);
这是一个Java中用于向预编译的SQL语句中填充占位符的方法。其中,占位符的位置从1开始计数。setObject()方法可以接收任何类型的参数并将其转换为与数据库中对应列的类型相匹配的值。这个方法的作用是将需要赋的值赋给预编译SQL语句中的占位符,以便在执行SQL语句时使用这些值。
int rows = executeUpdate();//非DQL
Result result = executeQuery();//DQL
DQL是数据查询语言的缩写,通常用于描述一种用于从数据库中检索数据的编程语言。DQL允许用户通过指定查询条件在数据库表中搜索数据,并且可以使用多种操作符和函数来过滤和排序返回的结果。在数据库中,DQL通常是与DML(数据操作语言)和DDL(数据定义语言)等其他数据库语言一起使用的。
**int rows = executeUpdate() **,是用于执行SQL语句并返回更新行数。在这个代码片段中,executeUpdate() 方法被调用并返回一个整数值,该值被赋给一个名为 rows 的整型变量。这个变量可以用于后续的程序逻辑,如判断SQL语句是否执行成功或者获取更新行数等。
**Result result = executeQuery() **,是用于执行 SQL 查询并返回查询结果的一个对象。该对象可以被视为一个迭代器,可以使用 result.next() 方法来获取查询结果集中的下一行数据。在使用完查询结果后,需要手动关闭该结果集以释放资源。
if (rows > 0){
System.out.println("删除成功!!");
}else {
System.out.println("删除失败!!");
}
while (resultSet.next()){
map.put("id",resultSet.getInt("id"));
map.put("username",resultSet.getString("username"));
map.put("password",resultSet.getString("password"));
map.put("nickname",resultSet.getString("nickname"));
}
对于int rows = executeUpdate(),我们通常只判断rows是否大于0,因为rows多数用于判断SQL语句是否执行成功或者获取更新行数。
而对于Result result = executeQuery(),我们这里使用的是最简单的手动取值,这段代码是在将数据库中查询得到的结果存入一个 map 中,其中 “id”、“username”、“password”、“nickname” 是这个 map 中的键,它们分别对应着 resultSet 中的列名。而 resultSet.getInt(“id”)、resultSet.getString(“username”) 等则是从 resultSet 中获取相应的值,并将它们存入 map 中。这样做的目的是方便我们在后续的代码中使用 map 来操作这些值。
resultSet.close();
preparedStatement.close();
connection.close();
resultSet.close()用于关闭结果集,释放相关资源;preparedStatement.close()用于关闭预处理语句对象,释放相关资源;connection.close()用于关闭数据库连接,释放相关资源。这些操作都是为了释放资源,节省系统资源开销,提高程序效率。同时,关闭这些对象可以防止资源泄漏和数据安全问题。需要注意的是,关闭的顺序应该是resultSet -> preparedStatement -> connection。
在这里我们就直接引用上面的8个步骤了,那么便直接上代码:
//测试方法需要导入junit的测试包
@Test
public void testInsert() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");
//3.编写SQL语句结果,动态值的部分使用?代替
String sql = "insert into t_user(username,password,nickname) values(?,?,?)";
//4.创建preparedStatement,并且传入SQL语句结果
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//占位符赋值
preparedStatement.setObject(1,"test");
preparedStatement.setObject(2,"test");
preparedStatement.setObject(3,"二狗子");
//6.发送SQL语句
int rows = preparedStatement.executeUpdate();
//7.输出结果
if (rows > 0){
System.out.println("数据插入成功!!");
}else {
System.out.println("数据插入不成功!!");
}
//8.关闭资源
preparedStatement.close();
connection.close();
}
@Test
public void testDelete() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");
//3.编写SQL语句结果,动态值的部分使用?代替
String sql = "delete from t_user where id=?";
//4.创建prepareStatement,并且传入SQL语句的结果
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.占位符赋值
preparedStatement.setObject(1,5);
//6.发送SQL语句
int rows = preparedStatement.executeUpdate();
//7.输出结果
if (rows > 0){
System.out.println("删除成功!!");
}else {
System.out.println("删除失败!!");
}
//8.关闭资源
preparedStatement.close();
connection.close();
}
显而易见,我们的结果是:
我们可以发现,我们数据库的id为5的数据已经被删除了。
@Test
public void testUpdate() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");
//3.编写SQL语句结果,动态值的部分使用?代替
String sql = "update t_user set nickname = ? where id = ?";
//4.创建prepareStatement,并且传入SQL语句的结果
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.占位符赋值
preparedStatement.setObject(1,"三狗子");
preparedStatement.setObject(2,4);
//6.发送SQL语句
int rows = preparedStatement.executeUpdate();
//7.输出结果
if (rows > 0){
System.out.println("修改成功!!");
}else {
System.out.println("修改失败!!");
}
//8.关闭资源
preparedStatement.close();
connection.close();
}
同样地,我们的结果是:
可以看见,id为4的数据的nickname已经变为三狗子。
在这里,我使用了更快捷的查询方法,就是自动取值,但对于刚入坑JDBC的小伙伴还是先从手动取值开始吧。
@Test
public void testSelect() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");
//3.编写SQL语句结果,动态值的部分使用?代替
String sql = "select id,username,password,nickname from t_user";
//4.创建prepareStatement,并且传入SQL语句的结果
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.占位符赋值
//6.发送SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
List<Map> list = new ArrayList<>();
//7.输出结果
while (resultSet.next()){
Map map = new HashMap();
// map.put("id",resultSet.getInt("id"));
// map.put("username",resultSet.getString("username"));
// map.put("password",resultSet.getString("password"));
// map.put("nickname",resultSet.getString("nickname"));
for (int i = 1; i <= columnCount ; i++) {
Object object = resultSet.getObject(i);
String columnLabel = metaData.getColumnLabel(i);
map.put(columnLabel,object);
}
list.add(map);
}
System.out.println("list = " + list);
//8.关闭资源
resultSet.close();
preparedStatement.close();
connection.close();
}
在这里可以看到我们的结果:
list = [{password=123456, nickname=经理, id=1, username=admin}, {password=111, nickname=管理员, id=2, username=jjcc}, {password=123456, nickname=三狗子, id=4, username=test_1}]
当我们熟练地掌握以上几种方法后,我们就可以简单地做一个用控制台输入指令来控制IDEA进行相关的数据库操作了,具体的案例我会在以后发布哦,同样,在进行这些操作时,需要注意数据库表的结构和字段类型,避免出现数据类型不匹配或者数据丢失等问题。此外,还需要注意数据安全和数据备份,以免数据被恶意修改或者丢失。