引入 mysql-jdbc 驱动
- 驱动 jar 版本的选择:推荐使用 8.0.25+,省略时区设置
- java 工程导入依赖
- 项目创建 lib 文件夹
- 导入驱动依赖 jar 包
- jar 包右键 - 添加为库
JDBC 基本使用步骤
- 注册驱动
- 获取连接
- 创建发送 sql 语句对象
- 发送 sql 语句,并获取返回结果
- 结果集解析
- 资源关闭
基于 statement 演示查询
-
准备数据库数据
1 2 3 4 5 6 7 8 9 10 11 12
create database study; use study; create table t_user( id int primary key auto_increment comment '用户主键', account varchar(20) not null unique comment '账号', PASSWORD varchar(64) not null comment '密码', nickname varchar(20) not null comment '昵称'); insert into t_user(account,PASSWORD,nickname) values ('root','123456','经理'),('admin','666666','管理员');
-
查询目标
- 查询全部用户信息,进行控制台
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package com.binxin.api.statement; import com.mysql.cj.jdbc.Driver; import java.sql.*; /* * 使用statement查询t_user表下全部数据 * */ public class StatementQueryPart { public static void main(String[] args) throws SQLException { //1. 注册驱动 /* * 驱动版本:8+ com.mysql.cj.jdbc.Driver * */ DriverManager.registerDriver(new Driver()); //2. 获取连接 /* * url: jdbc:数据库厂商名://ip地址:port/数据库 * */ // 接口=实习类 Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/study", "root", "123456"); //3. 创建statement Statement statement = connection.createStatement(); //4. 发送 sql 语句,并获取返回结果 String sql = "select * from t_user;"; ResultSet resultSet = statement.executeQuery(sql); //5. 结果集解析 // 看看有没有下一行数据,有就可以获取 while (resultSet.next()) { int id = resultSet.getInt("id"); String account = resultSet.getString("account"); String password = resultSet.getString("PASSWORD"); String nickname = resultSet.getString("nickname"); System.out.println(id + "--" + account + "--" + password + "--" + nickname); } //6. 资源关闭 resultSet.close(); statement.close(); connection.close(); } } |
-
模拟登录:控制台输入账号密码,判断是否登录成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
package com.binxin.api.statement; import com.mysql.cj.jdbc.Driver; import java.sql.*; import java.util.Properties; import java.util.Scanner; /* * 控制台输入账号密码,判断是否登录成功 * */ public class StatementUserLoginPart { public static void main(String[] args) throws SQLException, ClassNotFoundException { //1. 从键盘获取输入 Scanner scanner = new Scanner(System.in); System.out.print("请输入账号:"); String account = scanner.nextLine(); System.out.print("请输入密码:"); String password = scanner.nextLine(); //2. 注册驱动 //方案1 DriverManager.registerDriver(new Driver()); //方案2 //new Driver(); //方案3 字符串->提取到外部配置文件 Class.forName("com.mysql.cj.jdbc.Driver"); //触发类加载 //3. 获取连接 /* * getConnection(1,2,3)方法是一个重载方法 * 允许以不同形式传入参数 * * 核心属性 * 1. 数据库软件所在的ip地址 localhost | 127.0.0.1 * 2. 端口号 3306 * 3. 数据库名称 study * 4. 账号 root * 5. 密码 123456 * 6. 其他可选信息 * * 三个参数 * String url 数据库软件所在的ip地址、端口号、数据库名称、其他可选信息 * 语法:jdbc:数据库厂商名[mysql,oracle]://ip地址|主机名:port端口号/数据库?key=value * &key=value 可选信息 * 具体:jdbc:mysql://127.0.0.1:3306/study * jdbc:mysql://localhost:3306/study * 本机的省略写法:省略本机地址和3306端口号 * jdbc:mysql:///study * String user 账号 root * String password 密码 123456 * * 两个参数 * String url 数据库软件所在的ip地址、端口号、数据库名称、其他可选信息 * Properties info 存储账号和密码 * Properties类似于Map,只不过key和value都是字符串形式 * * 一个参数 * String url jdbc:数据库厂商名[mysql,oracle]://ip地址|主机名:port端口号/数据库?user=root&password=123456 * * url的可选信息 * url?user=账号&password=密码 * * severTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true * */ Connection connection = DriverManager.getConnection("jdbc:mysql:///study", "root", "123456"); Properties info = new Properties(); info.put("user", "root"); info.put("password", "123456"); Connection connection1 = DriverManager.getConnection("jdbc:mysql:///study", info); Connection connection2 = DriverManager.getConnection("jdbc:mysql:///study?user=root&password=123456"); //4. 创建发送 sql 语句对象 //statement可以发送SQL语句到数据库,并且获取返回结果 Statement statement = connection.createStatement(); //5. 发送 sql 语句,并获取返回结果 String sql = "select * from t_user where account='"+account+"' and password='"+password+"';"; ResultSet resultSet = statement.executeQuery(sql); //6. 结果集解析 //while (resultSet.next()){ // int id = resultSet.getInt("id"); // String account1 = resultSet.getString("account"); // String password1 = resultSet.getString("PASSWORD"); // String nickname = resultSet.getString("nickname"); // System.out.println(id + "--" + account1 + "--" + password1 + "--" + nickname); //} if (resultSet.next()){ System.out.println("登录成功"); }else { System.out.println("登录失败"); } //7. 资源关闭 resultSet.close(); statement.close(); connection.close(); } }
-
存在的问题
- SQL 语句需要字符串拼接,比较麻烦
- 只能拼接字符串类型,其他的数据库类型无法处理
- 可能发生注入攻击
基于 prepareStatement 方式优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package com.binxin.api.preparedstatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Scanner; /* * 使用预编译的statement完成用户登录 * */ public class PSUserLoginPart { public static void main(String[] args) throws Exception { //1. 从键盘获取输入 Scanner scanner = new Scanner(System.in); System.out.print("请输入账号:"); String account = scanner.nextLine(); System.out.print("请输入密码:"); String password = scanner.nextLine(); //2. ps的数据库流程 //a. 注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //b. 获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql:///study", "root", "123456"); //c. 编写sql语句 String sql = "select * from t_user where account = ? and password = ?;"; //d. 创建预编译的statement并设置sql语句结果 PreparedStatement prepareStatement = connection.prepareStatement(sql); //e. 设置sql语句参数 prepareStatement.setString(1, account); prepareStatement.setString(2, password); //f. 执行sql语句,并返回结果 ResultSet resultSet = prepareStatement.executeQuery(); //g. 结果集解析 if (resultSet.next()) { System.out.println("登录成功"); } else { System.out.println("登录失败"); } //h. 资源关闭 resultSet.close(); prepareStatement.close(); connection.close(); } } |
基于 prepareStatement 演示 curd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | package com.binxin.api.preparedstatement; import org.junit.Test; import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /* * 使用preparedstatement进行t_user表的curd动作 * */ public class PSCURDPart { // 测试方法需要导入junit的测试包 @Test public void testInsert() throws Exception { /* * t_user表插入一条数据 * account test * password test * nickname 二狗子 **/ // 1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2.获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "123456"); // 3.编写SQL语句结果,动态值的部分使用?代替 String sql = "insert into t_user(account,password,nickname) values(?,?,?)"; // 4.创建preparedStatement.并且传入sql语句结果 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 5.占位符赋值 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 testUpdate() throws ClassNotFoundException, SQLException { /* * 修改id=3的用户nickname="三狗子" * */ // 1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2.获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "123456"); // 3.编写SQL语句结果,动态值的部分使用?代替 String sql = "update t_user set nickname=? where id=?"; // 4.创建preparedStatement.并且传入sql语句结果 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 5.占位符赋值 preparedStatement.setObject(1, "三狗子"); preparedStatement.setObject(2, 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 { /* * 删除id=3的用户数据 * */ // 1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2.获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "123456"); // 3.编写SQL语句结果,动态值的部分使用?代替 String sql = "delete from t_user where id=?"; // 4.创建preparedStatement.并且传入sql语句结果 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 5.占位符赋值 preparedStatement.setObject(1, 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 testSelect() throws ClassNotFoundException, SQLException { /* * 查询所有用户数据,并且封装到一个List<Map> list集合中 * */ // 1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2.获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "123456"); // 3.编写SQL语句结果,动态值的部分使用?代替 String sql = "select * from t_user;"; // 4.创建preparedStatement.并且传入sql语句结果 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 5.占位符赋值 // 6.发送SQL语句 ResultSet resultSet = preparedStatement.executeQuery(); // 7.结果集解析 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); //获取列的信息对象 ResultSetMetaData metaData = resultSet.getMetaData(); //获取列的个数 int columnCount = metaData.getColumnCount(); while (resultSet.next()) { Map<String, Object> map = new HashMap<>(); //一行数据,对应一个map //手动取值 //map.put("id",resultSet.getObject("id")); //map.put("account",resultSet.getObject("account")); //map.put("password",resultSet.getObject("password")); //map.put("nickname",resultSet.getObject("nickname")); //自动取值 for (int i = 1; i <= columnCount; i++) { //获取指定下角标的值 Object value = resultSet.getObject(i); //获取指定下角标的列名 String columnLabel = metaData.getColumnLabel(i); map.put(columnLabel,value); } list.add(map); } System.out.println("list = " + list); // 8.关闭连接 resultSet.close(); preparedStatement.close(); connection.close(); } } |