JDBC01
JDBC基本介绍
基本介绍
好处
直接访问数据库:
使用jdbc访问数据库——面向接口编程
JDBC模拟
/** * @author 紫英 * @version 1.0 * @discription 模拟JDBC */ public interface JDBCInterface { //连接方法 public Object getConnection(); // crud方法 public void crud(); // 关闭连接 public void close(); } ================================== /** * @author 紫英 * @version 1.0 * @discription mysql实现jdbc接口 */ public class MysqlJdbcImpl implements JDBCInterface { @Override public Object getConnection() { System.out.println("mysql 链接"); return null; } @Override public void crud() { System.out.println("mysql增删改查"); } @Override public void close() { System.out.println("mysql增删改查"); } } ================================= /** * @author 紫英 * @version 1.0 * @discription oracle实现jdbc接口 */ public class OracleJdbcImpl implements JDBCInterface{ @Override public Object getConnection() { System.out.println("oracle 链接"); return null; } @Override public void crud() { System.out.println("oracle crud"); } @Override public void close() { System.out.println("oracle close"); } } =============================== /** * @author 紫英 * @version 1.0 * @discription 测试类 */ public class JdbcTest { public static void main(String[] args) { JDBCInterface jdbcInterface = new MysqlJdbcImpl(); // 接口的多态 jdbcInterface.getConnection(); jdbcInterface.crud(); jdbcInterface.close(); jdbcInterface = new OracleJdbcImpl(); jdbcInterface.getConnection(); jdbcInterface.crud(); jdbcInterface.close(); } }
JDBC API
- java.sql接口
- javax.sql接口
程序编写步骤
JDBC快速入门案例
1.先将mysql的jar包添加到项目中
在项目下创建一个文件夹比如 lib,将 mysql.jar 拷贝到该目录下,点击 add to project ..加入到项目中
2.代码实现
package com.recorder.jdbc; import com.mysql.jdbc.Driver; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /** * @author 紫英 * @version 1.0 * @discription Jdbc快速入门案例 */ public class Jdbc01 { public static void main(String[] args) throws SQLException { //1. 注册驱动,创建 driver 对象 Driver driver = new Driver();//new com.mysql.jdbc.Driver.v //2. 得到连接 // (1) jdbc:mysql:表示协议,通过 jdbc 的方式连接 mysql(写死的)// (2) localhost 主机,也可以是 ip 地址 // (3) 3306 表示 mysql 监听的端口 // (4) db01 连接到 mysql dbms 的哪个数据库 // (5) mysql 的连接本质就是前面学过的 socket 连接 String url = "jdbc:mysql://localhost:3306/db01";//要链接的数据库地址 //将 用户名和密码放入到 Properties 对象 Properties properties = new Properties(); //user 和 password 是规定好,后面的值根据实际情况写 properties.setProperty("user","root"); properties.setProperty("password","123456"); Connection connect = driver.connect(url, properties); //连接数据库
//3. 执行 sql //statement 用于执行静态 SQL 语句并返回其生成的结果的对象 Statement statement = connect.createStatement(); String sql = "insert into Dog values(null,'大黄')"; // 如果是 dml 语句,返回的就是影响行数 int i = statement.executeUpdate(sql); System.out.println(i > 0 ? "添加成功" : "添加失败"); //4. 关闭连接资源 statement.close(); connect.close(); } }
获取数据库连接 5 种方式
第一种
缺点:静态加载,灵活性差,依赖性强
第二种方法
优点:使用反射加载Driver类,动态加载,更加灵活减少依赖性,还可以读取配置文件中的数据
第三种方法
使用DriverManager替代driver进行统一管理,扩展性更好,无需创建properties对象,更加灵活
第四种方法(使用最多)
第五种方式(第四种的改进,推荐使用)
properties文件
user=root password=root url=jdbc:mysql://localhost:3306/db01 driver=com.mysql.jdbc.Driver
package com.recorder.jdbc; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.*; import java.util.Properties; /** * @author 紫英 * @version 1.0 * @discription 第五种方式 */ public class Jdbc02 { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //1.通过properties对象获取配置文件信息 Properties properties = new Properties(); properties.load(new FileInputStream("src\\jdbc.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //注册驱动 建议写上 Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); System.out.println("数据库连接成功(方式5)"); String sql = "create table actor (id int,name varchar(10))"; Statement statement = connection.createStatement(); statement.execute(sql); System.out.println("actor创建成功"); for (int i = 0; i < 5; i++) { String sql1 = "insert into actor values(" + i + "," + i + ")"; statement.executeUpdate(sql1); System.out.println("1条数据添加成功"); } sql = "update actor set name = '张三' where id = 1"; statement.executeUpdate(sql); System.out.println("修改成功"); sql = "delete from actor where id = 3"; statement.executeUpdate(sql); System.out.println("删除成功"); statement.close(); connection.close(); } }
ResultSet
基本介绍
package com.recorder.jdbc; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.*; import java.util.Properties; /** * @author 紫英 * @version 1.0 * @discription resultset查询演示 */ public class Resultset { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { Properties properties = new Properties(); properties.load(new FileInputStream("src\\jdbc.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //加载驱动建议写上 Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); System.out.println("数据库连接成功(方式5)"); Statement statement = connection.createStatement(); String sql = "select * from goods"; ResultSet resultSet = statement.executeQuery(sql); System.out.println("查询结果:"); while (resultSet.next()){//光标向后移动,如果没有行了返回false int goods_id = resultSet.getInt(1);//获取第一列
//int id1 = resultSet.getInt("id"); 通过列名来获取值, 推荐
int cat_id = resultSet.getInt(2);//获取第二列 String name = resultSet.getString(3); double price = resultSet.getDouble(4); System.out.println("[goods_id]" + goods_id + "[cat_id]" + cat_id + "[name]" + name + "[price]" + price); } //关闭连接 resultSet.close(); statement.close(); connection.close(); } }
-
debug源码简单解读
注意:
1.这里的ResultSet是一个接口
2.结构查看
Statement
SQL注入
-- 演示 sql 注入 -- 创建一张表 CREATE TABLE admin ( -- 管理员表 NAME VARCHAR(32) NOT NULL UNIQUE, pwd VARCHAR(32) NOT NULL DEFAULT '') CHARACTER SET utf8; -- 添加数据 INSERT INTO admin VALUES('tom', '123'); -- 查找某个管理是否存在 SELECT * FROM admin WHERE NAME = 'tom' AND pwd = '123 -- SQL -- 输入用户名 为 1' or -- 输入万能密码 为 or '1'= '1 SELECT * FROM admin WHERE NAME = '1' OR' AND pwd = 'OR '1'= '1' SELECT * FROM admin
package com.recorder.jdbc; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.*; import java.util.Properties; import java.util.Scanner; /** * @author 紫英 * @version 1.0 * @discription statement sql注入演示 */ public class Statement01 { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { Scanner scanner = new Scanner(System.in); //让用户输入管理员名和密码 System.out.print("请输入管理员的名字: "); //next(): 当接收到 空格或者 '就是表示结束 String admin_name = scanner.nextLine(); // 说明:如果希望看到 SQL 注入,这里需要用 nextLine System.out.print("请输入管理员的密码: "); String admin_pwd = scanner.nextLine(); Properties properties = new Properties(); properties.load(new FileInputStream("src\\jdbc.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //1. 注册驱动 Class.forName(driver);//建议写上 // 2. 得到连接 Connection connection = DriverManager.getConnection(url, user, password); //3.得到 Statement Statement Statement statement = connection.createStatement(); //4. 组织 SqL String sql = "select name , pwd from admin where name ='" + admin_name + "' and pwd = '" + admin_pwd + "'"; ResultSet resultSet = statement.executeQuery(sql); if (resultSet.next()) { //如果查询到一条记录,则说明该管理存在 System.out.println("恭喜, 登录成功"); } else { System.out.println("对不起,登录失败"); } //关闭连接 resultSet.close(); statement.close(); connection.close(); } }
正常情况:
sql注入:
PreparedStatement(预处理查询)
基本介绍
通过类图可以看到——PreparedStatement是Statement的一个子接口
3.executeUpdate返回类型是int,表示受影响的行数
代码演示
使用预处理查询后,因为是占位符赋值,所以也不会再出现sql注入问题
package com.recorder.jdbc; import java.io.FileInputStream; import java.io.IOException; import java.sql.*; import java.util.Properties; import java.util.Scanner; /** * @author 紫英 * @version 1.0 * @discription 预处理查询 */ @SuppressWarnings({"all"}) public class PreparedStatement { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //看 PreparedStatement 类图 Scanner scanner = new Scanner(System.in); //让用户输入管理员名和密码 System.out.print("请输入管理员的名字: "); //next(): 当接收到 空格或者 '就是表示结束 String admin_name = scanner.nextLine(); // 说明:如果希望看到 SQL 注入,这里需要用 nextLine System.out.print("请输入管理员的密码: "); String admin_pwd = scanner.nextLine(); Properties properties = new Properties(); properties.load(new FileInputStream("src\\jdbc.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //1. 注册驱动 Class.forName(driver);//建议写上 // 2. 得到连接 Connection connection = DriverManager.getConnection(url, user, password); //Statement statement = connection.createStatement(); //3. 得到 PreparedStatement // 3.1 组织 SqL , Sql 语句的 ? 就相当于占位符 String sql = "select name , pwd from admin where name =? and pwd = ?"; //3.2 preparedStatement 对象是实现了 PreparedStatement 接口的实现类的对象 java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sql); //3.3 给 ? 赋值 preparedStatement.setString(1, admin_name); preparedStatement.setString(2, admin_pwd); //4. 执行 select 语句使用 executeQuery // 如果执行的是 dml(update, insert ,delete) executeUpdate() // 这里执行 executeQuery ,不要再写 sql //ResultSet resultSet = preparedStatement.executeQuery(sql); ——错误 //因为前面已经给占位符赋值了,这里括号内再写sql相当于没有赋值,执行的是带占位符得sql,会报错 ResultSet resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { //如果查询到一条记录,则说明该管理存在 System.out.println("恭喜, 登录成功"); } else { System.out.println("对不起,登录失败"); } //关闭连接 resultSet.close(); preparedStatement.close(); connection.close(); } }
PreparedStatement执行dml语句
package com.recorder.jdbc; import java.io.FileInputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import java.util.Scanner; /** * @author 紫英 * @version 1.0 * @discription PreparedStatement执行dml语句 */ @SuppressWarnings({"all"}) public class PreparedStatement02 { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //看 PreparedStatement 类图 Scanner scanner = new Scanner(System.in); //让用户输入管理员名和密码 System.out.print("请输入管理员的名字: "); //next(): 当接收到 空格或者 '就是表示结束 String admin_name = scanner.nextLine(); // 说明:如果希望看到 SQL 注入,这里需要用 nextLine System.out.print("请输入管理员的密码: "); String admin_pwd = scanner.nextLine(); Properties properties = new Properties(); properties.load(new FileInputStream("src\\jdbc.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //1. 注册驱动 Class.forName(driver);//建议写上 // 2. 得到连接 Connection connection = DriverManager.getConnection(url, user, password); //Statement statement = connection.createStatement(); //3. 得到 PreparedStatement // 3.1 组织 SqL , Sql 语句的 ? 就相当于占位符 String sql = "insert into admin values (?,?)";//添加 //String sql = "update admin set name= ? where pwd = ?";//修改 //String sql = "delete from admin where name = ?";//删除 //3.2 preparedStatement 对象是实现了 PreparedStatement 接口的实现类的对象 java.sql.PreparedStatement preparedStatement = connection.prepareStatement(sql); //3.3 给 ? 赋值 preparedStatement.setString(1, admin_name); //preparedStatement.setString(2, admin_pwd); //4. 执行 select 语句使用 executeQuery // 如果执行的是 dml(update, insert ,delete) executeUpdate() // 这里执行 executeQuery ,不要再写 sql //ResultSet resultSet = preparedStatement.executeQuery(sql); ——错误 //因为前面已经给占位符赋值了,这里括号内再写sql相当于没有赋值,执行的是带占位符得sql,会报错 int i = preparedStatement.executeUpdate(); System.out.println(i + "条记录更新成功"); //关闭连接 preparedStatement.close(); connection.close(); } }
好处
JDBCAPI梳理
本文来自博客园,作者:紫英626,转载请注明原文链接:https://www.cnblogs.com/recorderM/p/15898824.html