JDBC的学习

JDBC

--第一个JDBC
import java.sql.*;
public class JDBCTest02{
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//1、注册驱动
// DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
String url = "jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=utf8&useSSL=false";
String username = "root";
String password = "123456";
conn = DriverManager.getConnection(url,username,password);
//3、获得操作对象
stmt = conn.createStatement();
//4、写sql语句
String sql = "INSERT INTO dept(DEPTNO,DNAME,LOC) VALUES(260,'瓜','重庆');";
int count = stmt.executeUpdate(sql);
System.out.println(count == 1? "插入成功":"插入失败");
//5、处理结果集
  } catch(SQLException | ClassNotFoundException e){
  e.printStackTrace();
  }finally{
  //5、释放资源
  if (stmt != null) {
  try{
  stmt.close();
  }catch(SQLException e){
  e.printStackTrace();
  }
  }
  if (conn != null) {
  try{
  conn.close();
  }catch(SQLException e){
  e.printStackTrace();
  }
  }
  }
}
}

注意:要想插入数据库里的数据显示中文,首先url里的参数要是用useUnicode=true和characterEncoding=utf8,狂神说useSSL参数要设为true,但是使用之后也还有警告信息,甚至也不能显示为中文,后改为false,即可显示为中文,不知其原理。

JDBC六大步

  1. 注册驱动  

    Driver.Manager(new com.mysql.jdbc.Driver()); //注册驱动的语句,不常用,因为数据库写死了

    Class.forName("com.mysql.jdbc.Driver");    //常用,因为字符串可以用配置文件去修改,底层实现原理:Driver实现类中有静态代码块,其中包含Driver.Manager(new com.mysql.jdbc.Driver());所以实现类加载的方式即可完成注册。当类加载的时候,类中的静态代码块也会执行。
  2. 获取连接

    String url = "jdbc:mysql://localhost:3306/bjpowernode"; 
    /*
    jdbc:mysql: 协议,类似网页的http和https协议
    localhost   IP地址
    3306         端口号
    bjpowernode 数据库名字

    URL(Uniform Resource Locator,统一资源定位符)
    如果需要访问某一资源,URL需要这么写:
    协议名://IP地址:端口号/资源名称
    例子:
    百度首页:http://183.232.231.174/index.html
    */
    String username = "root";
    String password = "123456";
    new conn = Driver.Manager(url,user,password);  
  3. 获得操作对象

    new stmt = conn.createStatement(); //调用连接对象的createStatement()创建一个操作SQL的对象
  4. 写SQL语句

    String sql = "INSERT INTO dept(DEPTNO,DNAME,LOC) VALUES(260,'瓜','重庆');";
    int count = stmt.executeUpdate(sql);       //ececuteUpdate语句返回一个整数,该整数表示操作了多少行数据。增删改都用这个语句
    String sql = "select * from dept";
    ResultSet resultSet = stmt.executeQuery(sql); //返回一个结果集   查询(select语句)用executeQuery
  5. 处理结果集

    while (resultSet.next()){
       String deptno = resultSet.getString(2);   --里面可以跟列名,也可以跟第几列
       String dname = resultSet.getString("dname");
       String loc = resultSet.getString("loc");
       System.out.println(deptno+','+dname+',' +loc);
    }
    注意:此处的列名为,查询语句执行后表的列名,如取别名,则以别名为主。
    String sql = "select deptno as a,dname,loc from dept";
       ResultSet resultSet = stmt.executeQuery(sql);
       //5、处理结果集
       while (resultSet.next()){
           String deptno = resultSet.getString("deptno");
           String dname = resultSet.getString("dname");
           String loc = resultSet.getString("loc");
           System.out.println(deptno+','+dname+',' +loc);
    }
    // 错误信息:java.sql.SQLException: Column 'deptno' not found.
    +-----+------------+----------+
    | a   | DNAME      | LOC      |
    +-----+------------+----------+
    |  10 | ACCOUNTING | NEW YORK |
    |  20 | RESEARCH   | DALLAS   |
    |  30 | SALES      | CHICAGO  |
    |  40 | OPERATIONS | BOSTON   |
    |  50 | ?????      | ??       |
    |  60 | ?????      | ??       |
    |  70 | ?????      | ??       |
    |  80 | ?????      | ??       |
    |  90 | ?????      | ??       |
    | 100 | ?????      | ??       |
    | 120 | ?????      | ??       |
    | 200 | 瓜         | 重庆     |
    | 220 |            | ??       |
    | 230 | ?          | ??       |
    | 250 | ?          | ??       |
    | 260 | 瓜         | 重庆     |
    | 270 | 瓜         | 重庆     |
    +-----+------------+----------+
  6. 释放资源

    if (resultSet != null){
       try {
           resultSet.close();
      } catch (SQLException throwables) {
           throwables.printStackTrace();
      }
    }
    if (stmt != null) {
       try{
           stmt.close();
      }catch(SQLException e){
           e.printStackTrace();
      }
    }
    if (conn != null) {
       try{
           conn.close();
      }catch(SQLException e){
           e.printStackTrace();
      }
    }
    // 注意先开后关,类型IO的操作

模拟登录

 public static void main(String[] args) {
       //初始化界面
       Map<String,String> userInfo = initUI();
       //验证用户名和密码
       boolean loginSuccess = login(userInfo);
       //输出结果
       System.out.println(loginSuccess?"登录成功":"登录失败");
  }

   /**
    * 用户登录
    * @param userInfo 用户登录信息
    * @return true登录成功,false登录失败
    */
   private static boolean login(Map<String, String> userInfo) {
       //JDBC
       Connection conn = null;
       Statement stmt = null;
       ResultSet resultSet =null;
       boolean flag = false;

       try {
           //1.注册驱动
           Class.forName("com.mysql.jdbc.Driver");
           //2.获得连接
           String url = "jdbc:mysql://localhost:3306/bjpowernode?&useUnicode=true&characterEncoding=utf8&useSSL=false";
           String username = "root";
           String password = "123456";
           conn = DriverManager.getConnection(url,username,password);
           //3.获得操作对象
           stmt = conn.createStatement();
           //4.执行SQL语句
           //取用户输入信息
           String userLoginName = userInfo.get("username");
           String userLoginPwd = userInfo.get("password");
           String sql = "select * from tbl_user where username = '"+userLoginName+"' and password='"+userLoginPwd+"'";
           resultSet = stmt.executeQuery(sql);
           //5.处理结果集
//           return resultSet.next(); 可读性不好
           if (resultSet.next()){
               flag=true;
          }
      } catch (ClassNotFoundException | SQLException e) {
           e.printStackTrace();
      }finally {
           //6.释放资源
           if (resultSet != null) {
               try {
                   resultSet.close();
              } catch (SQLException throwables) {
                   throwables.printStackTrace();
              }
          }
           if (stmt != null) {
               try {
                   stmt.close();
              } catch (SQLException throwables) {
                   throwables.printStackTrace();
              }
          }
           if (conn != null) {
               try {
                   conn.close();
              } catch (SQLException throwables) {
                   throwables.printStackTrace();
              }
          }
      }
       return flag;
  }

   /**
    * 初始化界面
    * @return 用户的用户名、密码等信息
    */
   private static Map<String, String> initUI() {
       //获取scanner对象
       Scanner scanner = new Scanner(System.in);
       System.out.println("用户名:");
       String username = scanner.nextLine();
       System.out.println("密码:");
       String password = scanner.nextLine();

       //封装成Map
       Map<String, String> userLoginInfo = new HashMap<>();
       userLoginInfo.put("username",username);
       userLoginInfo.put("password",password);

       return userLoginInfo;
  }

注意:statement会导致有SQL注入的问题

使用PreparedStatement解决SQL注入的问题

package com.fw.lesson2;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

//用户名:
//fdsa
//密码:
//fdsa'or'1'='1
//登录失败
/*
解决SQL注入的办法:
   只要让用户输入的内容不参与编译即可,所以使用PreparedStatement创建对象,
   使用?占位符占据输入的信息,然后预编译整个sql语句完成框架。
*/
public class JDBCTest02 {
   public static void main(String[] args) {
       //初始化界面
       Map<String,String> userInfo = initUI();
       //验证用户名和密码
       boolean loginSuccess = login(userInfo);
       //输出结果
       System.out.println(loginSuccess?"登录成功":"登录失败");
  }

   /**
    * 用户登录
    * @param userInfo 用户登录信息
    * @return true登录成功,false登录失败
    */
   private static boolean login(Map<String, String> userInfo) {
       //JDBC
       Connection conn = null;
       PreparedStatement ps = null;
       ResultSet resultSet =null;
       boolean flag = false;

       String userLoginName = userInfo.get("username");
       String userLoginPwd = userInfo.get("password");

       try {
           //1.注册驱动
           Class.forName("com.mysql.jdbc.Driver");
           //2.获得连接
           String url = "jdbc:mysql://localhost:3306/bjpowernode?&useUnicode=true&characterEncoding=utf8&useSSL=false";
           String username = "root";
           String password = "123456";
           conn = DriverManager.getConnection(url,username,password);
           //3.获得操作对象
           String sql = "select * from tbl_user where username =? and password=?" ;
           //预编译SQL语句的框架
           ps = conn.prepareStatement(sql);
           //给站位符传值
           ps.setString(1,userLoginName);
           ps.setString(2,userLoginPwd);
           //4.执行SQL语句
           resultSet = ps.executeQuery();
           //5.处理结果集
//           return resultSet.next(); 可读性不好
           if (resultSet.next()){
               flag=true;
          }
      } catch (ClassNotFoundException | SQLException e) {
           e.printStackTrace();
      }finally {
           //6.释放资源
           if (resultSet != null) {
               try {
                   resultSet.close();
              } catch (SQLException throwables) {
                   throwables.printStackTrace();
              }
          }
           if (ps != null) {
               try {
                   ps.close();
              } catch (SQLException throwables) {
                   throwables.printStackTrace();
              }
          }
           if (conn != null) {
               try {
                   conn.close();
              } catch (SQLException throwables) {
                   throwables.printStackTrace();
              }
          }
      }
       return flag;
  }

   /**
    * 初始化界面
    * @return 用户的用户名、密码等信息
    */
   private static Map<String, String> initUI() {
       //获取scanner对象
       Scanner scanner = new Scanner(System.in);
       System.out.println("用户名:");
       String username = scanner.nextLine();
       System.out.println("密码:");
       String password = scanner.nextLine();

       //封装成Map
       Map<String, String> userLoginInfo = new HashMap<>();
       userLoginInfo.put("username",username);
       userLoginInfo.put("password",password);

       return userLoginInfo;
  }
}

两种方式各有优缺点,不同场景使用不同的方式,大多数情况使用PreparedStatement,但是在需要SQL注入时候,还是会选择statement,例如:升序降序排列时,需要用户传入升序降序的关键字,此时,无法用prepare,因为传进去的值为字符串,无法作为关键字使用。

两种方式该如何使用?

大多是情况我们都选择使用PreparedStatement这种方式,但是在需要用户输入SQL语句的关键字时,需要SQL注入即选用Statement。

例子:

排列商品时,需要一个升序或者降序的需求,让用户自行选择,此时,需要用户输入asc表示升序,输入desc表示降序。此时,如果选择PreparedStatement,则需用setString方法,此时传进去的值为一个字符串而无法被当成SQL语句使用,所以采用SQL注入的方式。

封装JDBC工具类及JDBC开始事务

/*
目的:
   1.测试JDBC工具类
   2.测试事务
*/
public class JDBCTest03 {
   public static void main(String[] args) {
       Connection conn = null;
       PreparedStatement ps = null;
       ResultSet rs = null;

       try {
           conn = DButil.getConnection();
           //开启事务
           conn.setAutoCommit(false);
           String sql = "update tbl_user set realname = ? where id = ? ";
           ps = conn.prepareStatement(sql);
           ps.setString(1,"萝丝");
           ps.setInt(2,4);
           int count = ps.executeUpdate();

           ps.setString(1,"瓜皮");
           ps.setInt(2,2);
           count += ps.executeUpdate();
           System.out.println(count==2?"修改成功":"修改失败");

           sql = "select username,realname from tbl_user";
           ps = conn.prepareStatement(sql);
           rs = ps.executeQuery();
           while (rs.next()){
               System.out.println(rs.getString("username")+","+rs.getString("realname"));
          }
           //提交事务(事务结束)
           conn.commit();
      } catch (SQLException throwables) {
           //捕捉到异常就回滚
           if (conn != null){
               try {
                   conn.rollback();
              } catch (SQLException e) {
                   e.printStackTrace();
              }
          }
           throwables.printStackTrace();
      }finally {
           DButil.close(conn,ps,rs);
      }
  }
}
/**
* 封装JDBC工具类
*/
public class DButil {
   private DButil(){
  }
   static {
       //因为一个类中可能多次连接不同的数据库,如果每次都要注册驱动,太麻烦了,而且也不用每次注册驱动
       //所以写在静态代码块中,使之在类加载的时候执行,并且静态代码块只执行一次
       try {
           Class.forName("com.mysql.jdbc.Driver");
      } catch (ClassNotFoundException e) {
           e.printStackTrace();
      }
  }
   public static Connection getConnection() throws SQLException {
       //获得连接
       return DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=utf8&useSSL=false","root","123456");
  }
   public static void close(Connection conn, Statement ps, ResultSet rs){
       if (rs != null) {
           try {
               rs.close();
          } catch (SQLException throwables) {
               throwables.printStackTrace();
          }
      }
       if (ps != null) {
           try {
               ps.close();
          } catch (SQLException throwables) {
               throwables.printStackTrace();
          }
      }
       if (conn != null) {
           try {
               conn.close();
          } catch (SQLException throwables) {
               throwables.printStackTrace();
          }
      }
  }
}
posted @ 2020-06-19 10:31  lee的学习博客  阅读(370)  评论(0)    收藏  举报