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 ~ 

    每天都要遇到更好的自己.
  • 相关阅读:
    Get-CrmSetting返回Unable to connect to the remote server的解决办法
    Dynamics 365中的常用Associate和Disassociate消息汇总
    Dynamics 365 Customer Engagement V9 活动源功能报错的解决方法
    Dynamics Customer Engagement V9版本配置面向Internet的部署时候下一步按钮不可点击的解决办法
    Dynamics 365检查工作流、SDK插件步骤是否选中运行成功后自动删除系统作业记录
    注意,更改团队所属业务部门用Update消息无效!
    Dynamics 365的审核日志分区删除超时报错怎么办?
    Dynamics 365使用Execute Multiple Request删除系统作业实体记录
    Dynamics 365的系统作业实体记录增长太快怎么回事?
    Dynamics CRM日期字段查询使用时分秒的方法
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/11864953.html
Copyright © 2011-2022 走看看