zoukankan      html  css  js  c++  java
  • JDBC学习

    概念:java database connectivity,java连接数据库

    • JDBC实质:官方定义了操作所有关系型数据库的规则(接口)。各个数据库厂商实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
    coder--->java代码(jdbc接口)--->数据库驱动(mysql db2 oracle)--->mysql db2 oracle
    

    快速入门

    • 步骤
      1.导入驱动jar包
      2.注册驱动
      3.获取数据库连接对象 Connection
      4.定义sql
      5.获取执行sql语句的对象statement
      6.执行sql,接收结果
      6.处理数据
      7.释放资源
    • 代码实现
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/panda?serverTimezone=UTC","root","123456");
            String sql = "select * from company where company_id < 10";
            Statement stat = conn.createStatement();
            ResultSet resultSet = stat.executeQuery(sql);
            while (resultSet.next()){
                System.out.println(resultSet.getString("name"));
            }
            stat.close();
            conn.close();
    

    详解各个对象

        1.DriverManager:驱动管理对象
        - 功能:
            1)注册驱动
                static void registerDriver(Driver driver)
                写代码:Class.forName("com.mysql.jdbc.Driver");
                通过查看源码得知:在com.mysql.jdbc.Driver类中存在静态代码块
                static {
                    try{
                        java.sql.DriverManager.registerDriver(new Driver());
                    }catch(SQLException E){
                        //...
                    }
                }
                注意:
                msqyl5之后可以不注册驱动,在META-INF==>services==>java.sql.Driver 自动注册了。
            2)获取数据库的连接
                方法:static Connection getConnenction(String url,String user,String password)
                参数:url=>指定连接的路径=>语法:jdbc:mysql://ip:port/databaseName
                例子:jdbc:mysql://localhost:3306/db3
                如果连接是本机的,端口号是3306,则可以缩写:jdbc:mysql:///databaseName
        2.Connection:数据库连接对象
        - 功能:
            1)获取执行sql的对象
                Statement createStatement()
                PreparedStatement prepareStatement(String sql)
            2)管理事务
                开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
                提交事务:commit()
                回滚事务:rollback()
        3.Statement:执行静态sql的对象
            boolean execute(String sql):
                    可以执行任意的sql
            int excuteUpdate(String sql):
                    可以执行DML(insert,update,delete)、DDL(create,alter,drop)
                    返回值:影响的行数,可以通过返回值来检验DML是否执行成功,返回值>1则执行成功。
            ResultSet executeQuery(String sql):
                    执行DQL(select)
        4.ResultSet:结果集对象,封装查询对象
            next():游标向下移动一个位置
            getXxx(参数):获取数据
                Xxx是数据类型
                参数:int:代表列的序号;String:代表列的名称
            注意:游标下移=>判断当前行是否最后一行末尾=>获取数据
        5.PreparedStatement:执行动态sql的对象
            SQL注入问题:在拼接sql时,有一些特殊sql的特殊关键字拼接,会造成安全问题
                sql:select * from table where username='xxx' and password='a' or 'a'='a'
            解决注入问题:使用ProparedStatement来解决
                预编译sql:参数使用?作为占位符
    

    抽取JDBC工具类

    • 目的:简化书写
    • 分析:
    1.注册驱动也抽取
    2.抽取一个方法获取连接对象
        - 配置文件的方法:jdbc.properties
        password=123456
        name=root
        url=jdbc:mysql://localhost:3306/panda?serverTimezone=UTC
        driver=com.mysql.jdbc.Driver
        - 静态代码块来获取配置文件
        static{
            try{
                Properties pro = new Properties();
                //没有初始化所以不能使用下面的方法获取配置文件 ==> pro.load(this.getClass().getClassLoader().getResourceAsStream("jdbc.properties"));
                pro.load(new FileReader(JdbcUtil1.class.getClassLoader().getResource("jdbc.properties").getPath()));
                url = pro.getProperty("url");
                name = pro.getProperty("name");
                password = pro.getProperty("password");
                driver = pro.getProperty("driver");
            }catch(Exception){}    
        }
        - 获取Connection对象
            Connection connection = null;
            try {
                Class.forName(driver);
                connection = DriverManager.getConnection(url, name, password);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return connection;
    3.抽取一个方法释放资源
    4.完整代码:
    package test.jdbc;
    
    import java.io.FileReader;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    public class JdbcUtil1 {
        private static String url;
        private static String name;
        private static String password;
        private static String driver;
    
        static {
            try {
                Properties pro = new Properties();
                //没有初始化所以不能使用下面的方法获取配置文件 ==> pro.load(this.getClass().getClassLoader().getResourceAsStream("jdbc.properties"));
                pro.load(new FileReader(JdbcUtil1.class.getClassLoader().getResource("jdbc.properties").getPath()));
                url = pro.getProperty("url");
                name = pro.getProperty("name");
                password = pro.getProperty("password");
                driver = pro.getProperty("driver");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() {
            Connection connection = null;
            try {
                Class.forName(driver);
                connection = DriverManager.getConnection(url, name, password);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return connection;
        }
    
        public static void closeConnection(Statement statement, Connection connection) {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    

    使用JDBC控制事务

    • 事务:一个包含多个业务的操作。如果这个业务操作被事务管理,那么这些多个步骤要么同时成功,要么同时失败。
    • 操作:
        1.开启
        2.提交
        3.回滚
    
    • 使用Connection对象来管理事务
        开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
            在写sql之前开启事务
        提交事务:commit()
            当所有sql语句执行完之后提交事务
        回滚事务:rollback()
            在catch中回滚事务
    
    • 代码
    @Test
        public void test3() {
            Connection connection = JdbcUtil1.getConnection();
            Statement statement = null;
            //设置为false,开启事务
            try {
                connection.setAutoCommit(false);
                statement = connection.createStatement();
                int index = statement.executeUpdate("update company set name = '小米科技有限责任公司' where company_id = 1");
                int i = 3/0;
                System.out.println(index);
                //提交事务
                connection.commit();
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    //回滚事务
                    connection.rollback();
                } catch (SQLException e1) {
                }
            } finally {
                JdbcUtil1.closeConnection(statement, connection);
            }
    
        }
    

    数据库连接池

    • 概念:其实就是一个容器集合,存放数据库连接的容器。当系统初始化好,容器被创建,容器会申请一些连接对象,当用户来访问数据库时,从容器中获取数据库连接对象,用户访问完之后,会将连接对象归还给容器。
    • 好处:节约资源;用户访问效率高
    • 实现:
    标准接口:
       DataSource javax.sql包下的
       方法:获取连接getConnection()
            归还连接如果是从Connection池中获得的Connection,用Connection.close(),则归还连接,而不是释放 
    一般我们不需要实现它:
       C3P0:数据库连接池技术
       Druid:数据库连接池技术,阿里巴巴实现
    
    • C3P0:
    1.导入jar包(两个): c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar mysql驱动包也得导入
    2.定义配置文件:c3p0.properties or c3p0-config.xml
    3.创建核心对象 数据库连接对象 ComboPooledDataSource
    4.获取连接:getConnection()
    --代码:
    配置文件:c3p0-config.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <!--默认配置-->
        <default-config>
            <property name="initialPoolSize">10</property>
            <property name="maxIdleTime">30</property>
            <property name="maxPoolSize">100</property>
            <property name="minPoolSize">10</property>
            <property name="maxStatements">200</property>
        </default-config>
    
        <!--配置连接池mysql-->
        <named-config name="mysql">
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/panda?serverTimezone=UTC</property>
            <property name="user">root</property>
            <property name="password">123456</property>
            <property name="initialPoolSize">10</property>
            <property name="maxIdleTime">30</property>
            <property name="maxPoolSize">100</property>
            <property name="minPoolSize">10</property>
            <property name="maxStatements">200</property>
        </named-config>
    </c3p0-config>
    工具类:C3p0Util.java
    package test.jdbc;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class C3p0Util {
        static ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");
    
        public static Connection getConnection() {
            try {
                return dataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public static void closeConnection(Statement statement, Connection connection, ResultSet resultSet) {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    -测试
            Connection conn = C3p0Util.getConnection();
            Statement statement = conn.createStatement();
            int index = statement.executeUpdate("update company set name = '小米' where company_id = 1");
            System.out.println(index);
            C3p0Util.closeConnection(statement, conn, null);
    
    • Druid:
    -- 步骤
    1.导入jar包(两个): druid-1.0.9.jar mysql驱动包也得导入
    2.定义配置文件:是properties形式的;可以是任意名称任意目录下
    3.加载配置文件。properties
    4.创建核心对象 通过工厂类获取的  DruidDataSourceFactory   
    5.获取连接:getConnection()
    
    -- 定义工具类
    1.定义一个类 JDBCUtils
    2.提供静态代码块加载配置,初始化连接池对象
    3.提供方法
        1)获取连接的方法:通过连接池获取连接
        2)释放资源
        3)获取连接池的方法
    

    Spring JDBC

    * Spring对JDBC的简单封装。提供了一个JDBC的template对象简化开发
    * 步骤
    
    1.导入jar包
    2.创建JDBCTemplate对象。依赖于数据源DataSource
        - JdbcTemplate template = new JdbcTemplate(ds);
    3.调用JdbcTemplate的方法完成CRUD的操作
        - update():DML语句
        - queryForMap():将一条结果的列名作为key,值作为value,封装成map集合
        - queryForList():将多条结果的列名作为key,值作为value,封装成map集合的list
        - query():
            List<Student> list  = template.query(sql,new BeanPropertyRowMapper<Student>(Student.class));
        - queryForObject():查询结果将结果封装成对象
    
  • 相关阅读:
    基于go语言的消息推送系统架构分析
    golang IDE 工具liteide打开报错解决方法
    centos 安装ffmpeg 并生成文件截图
    android 微信分享
    函数编程之闭包漫谈(Closure)
    2017-06-26
    本周总结
    一周总结
    一周总结
    一周总结
  • 原文地址:https://www.cnblogs.com/yejiang/p/11794824.html
Copyright © 2011-2022 走看看