zoukankan      html  css  js  c++  java
  • JDBC

    JDBC

    JDBC:java和数据库的连接,Sun公司定义的一套java操作数据库的接口规范。

    快速入门

    准备工作

    • 数据库准备
      create database mytestdb character set utf8;
      DROP TABLE IF EXISTS `user`;
      CREATE TABLE `user` (
      `uid` varchar(50) NOT NULL,
      `username` varchar(20) DEFAULT NULL,
      `password` varchar(50) DEFAULT NULL,
      `name` varchar(20) DEFAULT NULL,
      `email` varchar(30) DEFAULT NULL,
      `telephone` varchar(20) DEFAULT NULL,
      `birthday` date DEFAULT NULL,
      `sex` varchar(10) DEFAULT NULL,
      `state` int(11) DEFAULT NULL,
      `code` varchar(64) DEFAULT NULL,
      PRIMARY KEY (`uid`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      
      INSERT INTO `user` VALUES ('10d27af0-7dd7-456c-ac81-bacd4833490d', 'root', '123456', '管理员', 'root@126.com', null, '2017-07-01', 'man', null, null);
      INSERT INTO `user` VALUES ('1be0290a-c300-4bc1-8f67-de061904e60e', 'zhangsan', '123', '张三', 'zhangsan@126.com', null, '2017-07-18', 'woman', null, null);
      INSERT INTO `user` VALUES ('3e663996-83ac-4cda-ad79-b15080553837', 'lisi', '123', '李四', 'lisi@126.com', null, '2017-07-18', 'man', null, null);
      INSERT INTO `user` VALUES ('5814301c-463e-4b66-9dcb-fc1ed7c29341', 'wangwu', '123', '王五', 'wangwu@126.com', null, '2017-07-11', 'woman', null, null);
      INSERT INTO `user` VALUES ('7e1927b6-67b4-4250-a01c-d054e730dd34', 'admin', '123456', 'Administror', 'admin@163.com', null, '2017-07-05', 'woman', null, null);
      
    • 导入jar包
      比如:mysql-connector-java-5.0.8-bin.jar

      统计user表的中记录数

      /**
         * 快速入门
         * 获取user表中所有的记录书
         * @throws Exception 
         */
        @Test
        public void test01() throws Exception {
            // 1、注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2、 获取连接
            String url = "jdbc:mysql://127.0.0.1:3306/mytestdb";
            String user = "root";
            String password = "123456";
            Connection conn = DriverManager.getConnection(url, user, password);
            // 3、获取发送sql的对象
            Statement statement = conn.createStatement();
            // 4、执行sql,返回结果
            String sql = "select count(*) from user";
            ResultSet resultSet = statement.executeQuery(sql);
            // 5、处理结果
            while (resultSet.next()){
                int count = resultSet.getInt(1);
                System.out.println("user表中一共有"+count+"条数据");
            }
            // 6、关闭资源
            resultSet.close();
            statement.close();
            conn.close();
        }
      

      执行结果:user表中一共有5条数据

      修改表中的数据

      /**
         * 修改表的记录
         */
        @Test
        public void test02(){
            Connection conn = null;
            Statement statement = null;
            try {
                // 1、注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 2、 获取连接
                String url = "jdbc:mysql://127.0.0.1:3306/mytestdb";
                String user = "root";
                String password = "123456";
                conn = DriverManager.getConnection(url, user, password);
                // 3、获取发送sql的对象
                statement = conn.createStatement();
                // 4、执行sql,返回结果
                String sql = "update user set name='哈哈' where uid='5814301c-463e-4b66-9dcb-fc1ed7c29341'";
                int num = statement.executeUpdate(sql);
                // 5、处理结果
                if (num > 0){
                    System.out.println("修改成功!");
                }else{
                    System.out.println("修改失败!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                // 6、关闭资源
                try {
                    if (statement != null){
                        statement.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if (conn != null){
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
      
        }
      

      使用PreparedStatement,来方式sql注入的问题。

      /**
         * 使用PreparedStatement来解决sql注入的问题
         * 查询sex = woman的用户
         */
        @Test
        public void test03(){
            Connection conn = null;
            PreparedStatement prepareStatement = null;
            ResultSet rs = null;
            try {
                // 1、注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 2、 获取连接
                String url = "jdbc:mysql://127.0.0.1:3306/mytestdb";
                String user = "root";
                String password = "123456";
                conn = DriverManager.getConnection(url, user, password);
                // 3、获取发送sql的对象
                String sql = "select * from user where sex=?";
                prepareStatement = conn.prepareStatement(sql);
                // 4、执行sql,返回结果
                prepareStatement.setString(1, "woman");
                rs = prepareStatement.executeQuery();
                // 5、处理结果
                while (rs.next()){
                    System.out.println(rs.getString("username")+"==="+rs.getString("password"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                // 6、关闭资源
                try {
                    if (rs != null){
                        rs.close();
                    }
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                try {
                    if (prepareStatement != null){
                        prepareStatement.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if (conn != null){
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
      
        }
      

      使用c3p0连接池:

    • 配置文件,必须放在src目录下,名称为:c3p0-config.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <c3p0-config>
      <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mytestdb</property>
        <property name="user">root</property>
        <property name="password">123456</property>
      
      </default-config>
      
      <!-- This app is massive! -->
      <named-config name="store"> 
          <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/store</property>
        <property name="user">root</property>
        <property name="password">123456</property>
      </named-config>
      </c3p0-config>
      
    • 使用c3p0连接池完成查询

      /**
         * 使用c3p0完成查询工作
         */
        @Test
        public void test04() throws Exception {
            // 创建连接池
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            // 从连接池中获取连接
            Connection conn = dataSource.getConnection();
            // 获取发送sql的对象
            Statement statement = conn.createStatement();
            // 执行sql,返回结果
            String sql = "select count(*) from user";
            ResultSet resultSet = statement.executeQuery(sql);
            // 处理结果
            while (resultSet.next()) {
                int count = resultSet.getInt(1);
                System.out.println("user表中一共有" + count + "条数据");
            }
            // 关闭资源
            resultSet.close();
            statement.close();
            conn.close();
      
        }
      

      创建jdbc的工具类

      public class JDBCUtils {
        private static ComboPooledDataSource ds = new ComboPooledDataSource();
        private static ThreadLocal<Connection> tl = new ThreadLocal<>();
      
        //返回连接池
        public static DataSource getDataSource(){
            return ds;
        }
      
        /**
         * 返回一个连接,此连接与当前线程绑定了
         * 可以保证 此线程拿到的线程都是同一个
         * @return
         * @throws Exception
         */
        public static Connection getConnection() throws Exception {
            Connection conn = tl.get();
            if (conn == null){
                conn = ds.getConnection();
                tl.set(conn);
            }
            return conn;
        }
      }
      

      使用DBUtils来简化JDCB操作

        /**
         * 使用DBUtils来统计user表中的记录数
         */
        @Test
        public void test05(){
            // 利用工具类获取连接池,创建QueryRunner对象
            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
            String sql = "select count(*) from user";
            try {
                Number number = qr.query(sql, new ScalarHandler<Number>());
                System.out.println("user表中共有"+number.intValue()+"条记录。");
            } catch (SQLException e) {
                e.printStackTrace();
            }
            /**
             * 这里不用释放连接,DBUtils会自动关闭,如果创建QueryRunner对象没有参数时,如下:
             * QueryRunner qr = new QueryRunner()
             * 这时,需要自己关闭连接
             */
        }
      

      事务的特性(ACID)

    • A:原子性:事务是一个整体,不可分割
    • C:一致性: 事务执行前和执行后,数据库必须处于一致的状态;如果事务执行成功,数据库的所有变化都将发生变化;如果事务执行失败,数据库的变化都将回滚,回到原始状态
    • I:隔离性: 多用户进行并发访问时,一个用户的事务,不能被其他用户的事务干扰,多个事务之间是互相隔离的。多个事务时事件是独立的,不能互相干扰
    • D:持久性: 一旦事务提交,它对数据库的改变将是持久性的

      如果不考虑事务的隔离性,将发生:脏读,不可重复度,幻读/虚读

    • 脏读: 一个事务读取到其他事务未提交的数据
    • 不可重复度: 一个事务多次读取表中的数据,结果不一样;读取了其它事务已经提交的数据(强调的数据被update)
    • 幻读: 一个事务读取到了其他事务提交的数据(强调的是记录数的变化,insert,delete)

      数据库的隔离级别

    • read uncnmitted 读未提交 问题:脏读,不可重复读,幻读
    • read cnmitted 读已提交 问题: 不可重复读,幻读 (oracle默认的级别)
    • repeatable read 可重复读 问题: 幻读 (mysql默认的级别)
    • serializable 串行化
  • 相关阅读:
    nyoj 16 矩形嵌套
    nyoj 44 子串和
    nyoj 448 寻找最大数
    nyoj 14 会场安排问题
    hdoj 1008 Elevator
    bzoj1588
    bzoj3224
    bzoj1503
    bzoj1834
    bzoj1066
  • 原文地址:https://www.cnblogs.com/xiaoshitoutest/p/7326908.html
Copyright © 2011-2022 走看看