zoukankan      html  css  js  c++  java
  • JDBC

    JDBC 基本概念

    JDBC: Java DataBase Connectivity, 即 Java 数据库连接.

    JDBC本质: 是官方定义的一套操作所有关系型数据库的规则, 即接口, 各个数据库厂商去实现这套接口, 提供数据库驱动 jar 包, 我们可以使用这套 (JDBC) 编程, 真正执行的代码是驱动 jar 包中的实现类.

    Java 连接 MySQL 需要驱动包,最新版下载地址为:http://dev.mysql.com/downloads/connector/j/,解压后得到jar库文件,然后在对应的项目中导入该库文件.

    JDBC 初步使用 (创建表)

    使用 mysql jar 包操作数据库的步骤:

    首先需在 mysql 上创建数据库

    1. 在项目里边导入 mysql jar 包, 注册驱动

    2. 获取数据库连接对象, 获取游标对象 cursor

    3. 组织 sql 语句

    4. 使用 cursor 执行 sql

    5. 处理结果

    6. 释放资源

    demo: 

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.Statement;
    
    /**
     * JDBC 初步使用
     */
    public class ConnectDataBase {
        public static void main(String[] args) throws Exception {
            // 导入 mysql jar 包, 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 获取数据库连接对象, 获取 cursor
            Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.115/JDBC", "username", "passwd");
            Statement st = conn.createStatement();
            // 写 sql
            String sql = "create table student(id int unsigned primary key auto_increment not null, name varchar(150))";
            // 执行 sql
            int num = st.executeUpdate(sql);
            // 处理结果
            // 执行成功返回 0, 再次执行: Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'student' already exists
            System.out.println(num);
            // 释放资源
            st.close();
            conn.close();
        }
    }

    JDBC 包中各个实现类详解

    DriverManager: 驱动管理对象

    1. 导入 mysql jar 包, 注册驱动

      Class.forName("com.mysql.jdbc.Driver");

      通过查看源码发现, 在 com.mysql.jdbc.Driver 类中存在静态代码块:

      static {
          try {
              java.sql.DriverManager.registerDriver(new Dirver());
          } catch (SQLException E) {
              throw new RuntimeException("Can't register driver!");
          }
      }

      提示: mysql 1.5版本之后的 jar 包可以省略注册驱动的步骤 (会根据配置文件自动导入)

       

    2. 获取数据库连接

      public static Connection getConnection(String url, String user, String password)

      url: jdbc:mysql://IP:PORT/DataBaseName

    Connection: 数据库连接对象

    1. 获取执行 sql 的cursor 对象

      Statement createStatement();

      PreparedStatement prepareStatement(String sql);

       

    2. 管理事务

      开启事务: void setAutoCommit(boolean autoCommit);

      提交事务: commit()

      回滚事务: rollback()

    Statement: 执行 sql 的对象

    1. 执行sql

      int executeUpdate(String sql): 执行 DML (insert, update, delete) , DDL (create, alter, drop)

      ResultSet executeQuery(String sql): 执行DQL (select)

      boolean execute(String sql): 可以执行任意的sql (不常用)

     

    ResultSet: 结果集对象

    封装查询结果

    常用方法:

    1. boolean next(): 游标向下移动一行

    2. int getInt(int columnIndex): 获取一个 int 类型的值 (传编号[编号从1开始] 或 列名)

    3. int getInt(String columnLabel)

    4. String getString(int columnIndex): 获取一个 String 类型的值 (传编号 或 列名)

    5. String getString(String columnLabel)

     

    PreparedStatement: 执行 sql 的对象

    使用 PreparedStatement 对象能解决 sql 注入的问题,

    JDBC 操作数据库练习

    插入一条数据:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /**
     * 使用 JDBC 插入一条数据
     */
    public class JdbcDemo01 {
        public static void main(String[] args) {
            Connection conn = null;
            Statement st = null;
            try {
                // 1.注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 2.编写sql
                String sql = "insert into student values(null, 'johny')";
                // 3.获取数据库连接
                conn = DriverManager.getConnection("jdbc:mysql://192.168.0.115:3306/JDBC", "username", "passwd");
                // 4.获取statement操作对象
                st = conn.createStatement();
                // 5.执行sql
                int num = st.executeUpdate(sql);
                // 6.处理sql执行结果
                System.out.println(num);  // 1
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 7.释放资源
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
    
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    View Code

    查询一条数据:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.ResultSet;
    
    /**
     * 使用 JDBC 查询一条数据
     */
    public class JdbcDemo01 {
        public static void main(String[] args) {
            Connection conn = null;
            Statement st = null;
            ResultSet ret = null;
            try {
                // 1.注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 2.编写sql
                String sql = "select * from student";
                // 3.获取数据库连接
                conn = DriverManager.getConnection("jdbc:mysql://192.168.0.115:3306/JDBC", "username", "passwd");
                // 4.获取statement操作对象
                st = conn.createStatement();
                // 5.执行sql
                ret = st.executeQuery(sql);
                // 6.处理sql执行结果
                ret.next();
                int id = ret.getInt(1);
                String name = ret.getString("name");
                System.out.println(String.format("id: %s, name: %s", id, name));   // id: 1, name: johny
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 7.释放资源
                try {
                    ret.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
    
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
    
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    View Code

    抽取 JDBC 工具类

    步骤:

    1. 封装 JDBCUtils 工具类

    2. 通过 properties 配置文件来读取数据库连接信息

    3. 通过静态代码块来初始化, 连接到数据库

    4. 封装释放资源的静态方法

    jdbc.properties:

    ipaddr=192.168.0.115
    port=3306
    dbname=JDBC
    username=chenkai
    passwd=chenkai

    JDBCUtils:

    import java.sql.*;
    import java.util.Properties;
    import java.io.IOException;
    import java.io.FileReader;
    import java.net.URL;
    
    
    /**
     * 封装 JDBC 的工具类
     */
    public class JDBCUtils {
        private static String ipaddr;
        private static String port;
        private static String dbname;
        private static String username;
        private static String passwd;
    
        static {
            try {
                // 读取配置文件, 初始化连接数据库
                Properties pro = new Properties();
                // 获取 src 路径下的文件 --> ClassLoader
                ClassLoader cl = JDBCUtils.class.getClassLoader();
                URL url = cl.getResource("jdbc.properties");
                String path = url.getPath();  // 配置文件的绝对路径
                // 加载配置文件
                pro.load(new FileReader(path));
                // 获取配置文件中的参数
                ipaddr = pro.getProperty("ipaddr");
                port = pro.getProperty("port");
                dbname = pro.getProperty("dbname");
                username = pro.getProperty("username");
                passwd = pro.getProperty("passwd");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        // 获取连接
        public static Connection getConnection(){
            try {
                // 注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 获取连接
                Connection conn = DriverManager.getConnection(String.format("jdbc:mysql://%s:%s/%s", ipaddr, port, dbname), username, passwd);
                return conn;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            //
            return null;
        }
    
        public static void close(ResultSet ret, Statement statement, Connection conn){
            if (ret!=null) {
                try {
                    ret.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (statement!=null) {
                try {
                    ret.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (conn!=null) {
                try {
                    ret.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void close(PreparedStatement pstatement, Connection conn){
            if (pstatement!=null) {
                try {
                    pstatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    View Code

    demo: 

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.ResultSet;
    
    /**
     * 使用 JDBC 查询一条数据
     */
    public class JdbcDemo01 {
        public static void main(String[] args) {
            Connection conn = null;
            Statement st = null;
            ResultSet ret = null;
            try {
                // 1.获取数据库连接
                conn = JDBCUtils.getConnection();
                // 2.编写sql
                String sql = "select * from student";
                // 4.获取statement操作对象
                st = conn.createStatement();
                // 5.执行sql
                ret = st.executeQuery(sql);
                // 6.处理sql执行结果
                ret.next();
                int id = ret.getInt(1);
                String name = ret.getString("name");
                System.out.println(String.format("id: %s, name: %s", id, name));
    
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 7.释放资源
                JDBCUtils.close(ret, st, conn);
            }
        }
    }

    PreparedStatement & sql注入

    使用 PreparedStatement 对象执行sql的步骤:

    1. 导入驱动包

    2. 获取数据库连接对象

    3. 定义 sql (使用 ? 作为占位符)

    4. 获取sql执行对象 (PreparedStatement)

    5. 给 ? 赋值(setInt, setString... 传递两个参数, 位置和值, 位置从 1 开始)

    6. 执行sql (不需要再传递 sql 语句)

    7. 处理结果

    8. 释放资源

    后边操作数据库都用 PreparedStatement 对象来完成增删改查的所有操作

    模拟用户登录, 处理 sql 注入问题: 

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Scanner;
    
    /**
     * 模拟用户登录, 处理sql注入问题
     */
    public class UserLogin {
        public Connection conn = null;
        public PreparedStatement pstat = null;
        public ResultSet ret = null;
    
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.print("请输入用户名:");
            String username = sc.nextLine();
            System.out.print("请输入密码:");
            String passwd = sc.nextLine();
    
            boolean ret = new UserLogin().login(username, passwd);
            if (ret) {
                System.out.println("登录成功");
            } else {
                System.out.println("用户名或密码输入错误!");
            }
        }
    
        public boolean login(String username, String passwd){
            if (username == null | passwd == null) {
                return false;
            }
    
            try{
                // 通过 JDBCUtils 获取数据库连接
                conn = JDBCUtils.getConnection();
                // 拼写sql
                String sql = "select * from user where username = ? and passwd = ?";
                // 获取 PreparedStatement 对象
                pstat = conn.prepareStatement(sql);
                // 给 sql 赋值
                pstat.setString(1, username);
                pstat.setString(2, passwd);
                // 执行 sql
                ret = pstat.executeQuery();
                // 处理结果
                return ret.next();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtils.close(ret, pstat, conn);
            }
            return false;
        }
    }

    JDBC 控制事务

    事务: 它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的操作单位.

    使用 Connection 对象来管理事务

    1. 开启事务: setAutoCommit(boolean autoCommit): 调用该方法设置参数为 false, 即开启事务

      执行 sql 前开启事务.

    2. 提交事务: commit()

      所有 sql 都执行完提交事务.

    3. 回滚事务: rollback()

      在 catch 中回滚事务.

    demo: 

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    /**
     *  JDBC 事务的应用, 模拟转账
     */
    public class JdbcDemo02 {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement pstat1 = null;
            PreparedStatement pstat2 = null;
    
            try {
                // 获取数据库连接
                conn = JDBCUtils.getConnection();
                // 开启事务!!!
                conn.setAutoCommit(false);
                // 编写sql
                String sql1 = "update user set balance = balance - 500 where username = ?";
                String sql2 = "update user set balance = balance + 500 where username = ?";
                // 获取 preparedStatement 对象
                pstat1 = conn.prepareStatement(sql1);
                pstat2 = conn.prepareStatement(sql2);
                // 给 sql 赋值
                pstat1.setString(1, "xiaoming");
                pstat2.setString(1, "xiaohong");
                // 执行sql
                pstat1.executeUpdate();
                pstat2.executeUpdate();
    
                //手动抛出异常
                int a = 3 / 0;
    
                // 提交事务
                conn.commit();
                System.out.println("处理完成");
            } catch (Exception e) {
                e.printStackTrace();
                // 回滚事务, 数据库连接不为空的时候进行回滚  (不会滚也不会更新成功, 回滚是不是在释放资源 ?)
                if (conn != null) {
                    try {
                        conn.rollback();
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                }
            } finally {
                // 释放资源
                JDBCUtils.close(pstat1, conn);
                JDBCUtils.close(pstat2, null);
            }
        }
    }

    ending ~ 

    每天都要遇到更好的自己.
  • 相关阅读:
    淘宝IP地址库采集
    Android MediaCodec硬编兼容性测试方案
    《Tensorflow实战》之6.3VGGnet学习
    tensorflow问题集锦
    <tensorflow实战>之5.3实现进阶的卷积网咯
    CNN_minist
    tensorflow之MLP学习
    tensorflow学习之等价代码
    tensorflow学习之softmax regression
    NPE进一步学习
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/11864953.html
Copyright © 2011-2022 走看看