Java-JDBC的使用—简介

目录

1、prepareStatement的使用

2、批处理的使用

2.1、场景(执行不同的SQL语句)

2.2、场景(执行100条SQL语句)

3、事务的处理

3.1、就是事务的使用

4、连接池的使用

4.1、常见的优秀的连接池有哪些呢?

4.2、Druid的使用

5、讲一个组件的使用(dbutils)

6、Beanutils组件(略,懒)

7.元数据的使用(略,没人看)

8.事物的隔离级别(略,写个屁)


1、prepareStatement的使用

select * from t_user where userName=xxx and password=xxx

这个SQl语就是通过我们的用户名 和密码 查询用户对象

这个SQL语句经常用来 进行用户的登陆操作

前端传递过来 用户名 ----- 密码

接下来我们就可以通过用户名和密码去查询用户对象

public class Test001 {


    //如果你访问的是 本地 那么localhost:3306可以省略
    // jdbc:协议   mysql:子协议  ip地址  端口   数据库的名字
    private static final String URL="jdbc:mysql:///cd2106";
    //如果你访问的是远程数据库 host:3306  这个就不能省略
    private static final String URL_NEW="jdbc:mysql://localhost:3306/cd2106?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER="root";
    private static final String PASSWORD="root";


    //这里模拟的是前端页面传递过来的这个值
    private static String userName="jonwen";
    private static String password="123";


    public static void main(String[] args){
        Connection connection=null;
        Statement statement=null;
        //首先是 加载驱动
        try {
//            Class.forName("com.mysql.jdbc.Driver");
            //通过DriverManager对象 获取咋们的连接
            //connection这个就相当于是操作修的路
             connection = DriverManager.getConnection(URL_NEW, USER, PASSWORD);

            //通过Connection获取咋们的操作数据库的对象
            //下面这个对象 就是专门用来操作数据库的
            statement = connection.createStatement();


            //这种方式有 潜在的问题存在的
            // 我们是将整个SQL语句带数据 发送到了 数据库管理系统
            //现在假设我们在进行执行SQL的过程中  别人拦截了我们的信息  还能拿到数据库的连接信息  数据库名字  数据库的编码...
            // select * from t_user where userName='xiaobobo' and password='123'

            //他在上面的SQL语句上 跟你 拼接上 这样一句  or  1=1

            // select * from t_user where userName='xiaobobo' and password='123' or 1=1  这个就是比较经典的SQL的注入问题

            //那么于是在这种场景下 另外一种 Statement名字叫做 PrepareStatement就产生了

            //在开发中使用的比较多的 应该是 Preparestatement使用的比较多的

            ResultSet resultSet = statement.executeQuery("select  * from t_user where userName='" + userName + "' and password='" + password + "'");


            //接下来我们就可以遍历这个值了
            while (resultSet.next()){

                String userName = resultSet.getString("userName");
                String password = resultSet.getString("password");
                String id = resultSet.getString("id");
                System.out.println("用户名:"+userName+"----password:"+password+"---id--"+id);
            }

        } catch (Exception e) {
            System.out.println("驱动没找到....");
        } finally {
            //关闭资源
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                System.out.println("关闭资源遇到异常....");
            }
        }
    }
}

PrepareStetement他叫做预编译的SQL的一个执行器

啥意思呀?

意思是他可以将SQL的骨架  和  SQL中的值 进行分离传输

先传输 SQL语句的骨架到 数据库管理系统上去 进行预编译

select * from t_user where  userName=? and password=?

第二步:再发送我们SQL语句中需要的值 传递到 上面的SQL语句中去 这个就是咋们的PrepareStetement
 

public class Test002 {


    //如果你访问的是 本地 那么localhost:3306可以省略
    // jdbc:协议   mysql:子协议  ip地址  端口   数据库的名字
    private static final String URL="jdbc:mysql:///cd2106";
    //如果你访问的是远程数据库 host:3306  这个就不能省略
    private static final String URL_NEW="jdbc:mysql://localhost:3306/cd2106?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER="root";
    private static final String PASSWORD="root";

    //这里模拟的是前端页面传递过来的这个值
    private static String userName="jonwen";
    private static String password="123";


    public static void main(String[] args){
        Connection connection=null;
        PreparedStatement statement=null;
        //首先是 加载驱动
        try {
//            Class.forName("com.mysql.jdbc.Driver");
            //通过DriverManager对象 获取咋们的连接
            //connection这个就相当于是操作修的路
             connection = DriverManager.getConnection(URL_NEW, USER, PASSWORD);

             //这句话就会将SQL发送到数据库管理系统去进行编译
             // 这里的? 表示的是一个占位符  表示的是 需要一个值
             statement = connection.prepareStatement("select * from t_user where userName=? and password=?");

            //接下来再给这个SQL语句设置值
            statement.setString(1,userName);
            statement.setString(2,password);

            //下面就 可以来进行查询了
            ResultSet resultSet = statement.executeQuery();
            //接下来我们就可以遍历这个值了
            while (resultSet.next()){
                String userName = resultSet.getString("userName");
                String password = resultSet.getString("password");
                String id = resultSet.getString("id");
                System.out.println("用户名:"+userName+"----password:"+password+"---id--"+id);
            }

        } catch (Exception e) {
            System.out.println("驱动没找到....");
        } finally {
            //关闭资源
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                System.out.println("关闭资源遇到异常....");
            }
        }
    }
}

2、批处理的使用

我们有没有这种场景
   1、我们一次性需要向数据库 插入100条数据
   2、我们有没有可能一次性执行多种不同类型的SQL语句呢?
   3、一次性执行1000条或者 1000条数据 直接运行到数据库中去
   
   为了解决这个问题呢?批处理在SQL中就被使用进去了

2.1、场景(执行不同的SQL语句)

package com.qf.edu.batch;


import java.sql.*;


public class Test003 {


    //如果你访问的是 本地 那么localhost:3306可以省略
    // jdbc:协议   mysql:子协议  ip地址  端口   数据库的名字
    private static final String URL="jdbc:mysql:///cd2106";
    //如果你访问的是远程数据库 host:3306  这个就不能省略
    private static final String URL_NEW="jdbc:mysql://localhost:3306/cd2106?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER="root";
    private static final String PASSWORD="root";

    //这里模拟的是前端页面传递过来的这个值
    private static String userName="jonwen";
    private static String password="123";


    public static void main(String[] args){
        Connection connection=null;
        Statement statement=null;
        //首先是 加载驱动
        try {
//            Class.forName("com.mysql.jdbc.Driver");
            //通过DriverManager对象 获取咋们的连接
            //connection这个就相当于是操作修的路
             connection = DriverManager.getConnection(URL_NEW, USER, PASSWORD);

             //准备两个SQL语句
             //这种场景很少见 我是没有遇到过

            String sql1="update t_user set userName='xxx' where id>1000";
            String sql2="insert into t_user(userName) values('美女好')";

            statement = connection.createStatement();
            statement.addBatch(sql1);
            statement.addBatch(sql2);

            //在这里就可以统一的执行这个SQL语句了
            //统一执行上面的SQL语句和值
            statement.executeBatch();
        } catch (Exception e) {
            System.out.println("驱动没找到....");
        } finally {
            //关闭资源
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                System.out.println("关闭资源遇到异常....");
            }
        }
    }
}

2.2、场景(执行100条SQL语句)

package com.qf.edu.batch;


import java.sql.*;


public class Test001 {


    //如果你访问的是 本地 那么localhost:3306可以省略
    // jdbc:协议   mysql:子协议  ip地址  端口   数据库的名字
    private static final String URL="jdbc:mysql:///cd2106";
    //如果你访问的是远程数据库 host:3306  这个就不能省略
    private static final String URL_NEW="jdbc:mysql://localhost:3306/cd2106?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER="root";
    private static final String PASSWORD="root";

    //这里模拟的是前端页面传递过来的这个值
    private static String userName="jonwen";
    private static String password="123";


    public static void main(String[] args){
        Connection connection=null;
        PreparedStatement statement=null;
        //首先是 加载驱动
        try {
//            Class.forName("com.mysql.jdbc.Driver");
            //通过DriverManager对象 获取咋们的连接
            //connection这个就相当于是操作修的路
             connection = DriverManager.getConnection(URL_NEW, USER, PASSWORD);

             //这句话就会将SQL发送到数据库管理系统去进行编译
             // 这里的? 表示的是一个占位符  表示的是 需要一个值
             statement = connection.prepareStatement("insert into t_user(userName,password) values(?,?)");
             //接下来咋们就可以来设置这个值了

            for (int i = 0; i < 100; i++) {
                   statement.setString(1,"xiaobobo"+i);
                   statement.setString(2,"123"+i);


                   //这个相当于没有直接执行 把这个结果放到了队列中 后面统一执行
                   statement.addBatch();
            }
            //在这里就可以统一的执行这个SQL语句了
            //统一执行上面的SQL语句和值
            statement.executeBatch();
        } catch (Exception e) {
            System.out.println("驱动没找到....");
        } finally {
            //关闭资源
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                System.out.println("关闭资源遇到异常....");
            }
        }
    }
}

3、事务的处理

什么是事务:
   这个事务 可以看成是我们在业务开发的时候 要执行的业务(简单的说就是你在开发中要做的事这个就称为事务)。你可以认为就叫做事务、也可以认为时候我们在进行业务操作的时候 执行的一个一个小的执行单元 这个就称为事务。
   
事务具有 如下的 几大特性

 原子性:所做的操作 要么 同时成功要么同时失败  这个就叫做原子性  这个也是事务中最重要的特性
 
 一致性:你可以这么认为  一次事务的操作 实际上 就是数据库中 从一个状态到另一个状态。数据库库中只是包含了 事务成功后的状态  事务失败的状态是没有保存的 这个就称为一致性
 
 隔离性:指的是 事务之间的操作 是不会相互影响的 你操作你的 我操作我的 我们之间相互是不会影响的 这个就业类似于咋们前面将的 线程池的中线程 在执行任务时候的 隔离 是一样的
 
 持久性:事务一旦执行成功  那么 对于数据库的操作 是永久的 、除非下一次的事务又来进行一次的更改 这样就变成了下一次的状态 这个就是咋们的持久性  

3.1、就是事务的使用

1、设置手动提交 ---- 因为这个里面已经包含了 打开事务
2、提交事务
3、执行回滚

事例1

package com.qf.edu.tranaction;


import javax.swing.plaf.nimbus.State;
import java.sql.*;

public class Test002 {


    //如果你访问的是 本地 那么localhost:3306可以省略
    // jdbc:协议   mysql:子协议  ip地址  端口   数据库的名字
    private static final String URL="jdbc:mysql:///cd2106";
    //如果你访问的是远程数据库 host:3306  这个就不能省略
    private static final String URL_NEW="jdbc:mysql://localhost:3306/cd2106?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER="root";
    private static final String PASSWORD="root";

    public static void main(String[] args) throws SQLException {
        Connection connection=null;
        Statement statement=null;
        //首先是 加载驱动
        try {

            //获取连接
             connection = DriverManager.getConnection(URL_NEW, USER, PASSWORD);
             //设置手动提交  默认是自动提交
            connection.setAutoCommit(false);

            //第一个要执行的操作
            statement = connection.createStatement();
            statement.executeUpdate("update t_user set userName='hhhh' where id=4");
            int k=1/0;
            //在这里我们就可以模拟异常了
            statement.executeUpdate("update t_user set userName='wwww' where id=5");
            //进行手动的提交
            connection.commit();

        } catch (Exception e) {
            System.out.println("这里会执行回滚....");
            connection.rollback();
        } finally {
            //关闭资源
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                System.out.println("关闭资源遇到异常....");
            }
        }
    }
}

事例2

package com.qf.edu.tranaction;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Test003 {


    //如果你访问的是 本地 那么localhost:3306可以省略
    // jdbc:协议   mysql:子协议  ip地址  端口   数据库的名字
    private static final String URL="jdbc:mysql:///cd2106";
    //如果你访问的是远程数据库 host:3306  这个就不能省略
    private static final String URL_NEW="jdbc:mysql://localhost:3306/cd2106?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER="root";
    private static final String PASSWORD="root";

    public static void main(String[] args) throws SQLException {
        Connection connection=null;
        //首先是 加载驱动
        try {
            //获取连接
             connection = DriverManager.getConnection(URL_NEW, USER, PASSWORD);
             //设置手动提交  默认是自动提交
            connection.setAutoCommit(false);

            //第一个要执行的操作
            PreparedStatement preparedStatement = connection.prepareStatement("update t_user set userName='hhhh' where id=7");
            preparedStatement.executeUpdate();
            int k=1/0;
            //在这里我们就可以老模拟异常了
            PreparedStatement preparedStatement1 = connection.prepareStatement("update t_user set userName='uuuu' where id=8");
            preparedStatement1.executeUpdate();

            //进行手动的提交
            connection.commit();

        } catch (Exception e) {
            System.out.println("这里会执行回滚....");
            connection.rollback();
        } finally {

        }
    }
}

4、连接池的使用

大家有没有想过一个问题:

  就是我们前面的连接 使用了之后 是不是都要关闭  关闭了 就意味着 这个连接不能再次被使用了 那么我们有没有谱一种策略 这种策略就是我们使用完了这个连接之后 放到一个容器中 这个连接并不被销毁  如果是下次我们还需要来访问这个数据库的话 就直接从容器中 去找 这个连接呢 这样就 避免了 连接的创建 消耗咋们的资源  这个就是咋们的连接池产生的 背景  
  
  这个就跟咋们的的 线程池 是一样的 每一次都创建线程的话会 消耗相当一部分的资源  因为线程的创建也需要咋们的CPU的参数 以及资源的分发

4.1、常见的优秀的连接池有哪些呢?

1、DBCP-----今天的市场上用的比较少

2、C3P0------几乎今天也没用了

3、Druid----阿里巴巴开发的------这个在中国今天为止 几乎所有的项目都使用了这个Druid去做连接池

4、Tomcat自带的连接池----用的比较少

4.2、Druid的使用

DataSource这个是所有的连接池的爹

DataSource这个是Sun公司提供的一个数据库的连接池的一个规范 

像我们所说的 其他的连接池  实际上只有 这个规范中的一个实现而已

4.2.1、导包

  <!--这个是Druid的包-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
    </dependency>

4.2.2、编写工具类

/**
 *德鲁伊的工具类
 */
public class DruidUtils {

    private static DruidDataSource dataSource;

    private static ThreadLocal<Connection> threadLocal;

    static {
        //这里就需要加载这个资源文件了
        InputStream in = DruidUtils.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            Properties properties = new Properties();
            properties.load(in);
            dataSource = new DruidDataSource();
            //初始化数据库的连接细信息
            //获取所需要的值
            dataSource.setDriverClassName(properties.getProperty("driverClassName"));
            dataSource.setUrl(properties.getProperty("jdbcUrl"));
            dataSource.setUsername(properties.getProperty("username"));
            dataSource.setPassword(properties.getProperty("password"));
            //这里面其实还有很多的设置
            // 这里一般写项目的时候 去找个模板就可以了

            dataSource.setMaxActive(100);
            dataSource.setMaxWait(1000*60*5);
        } catch (IOException e) {
            System.out.println("加载Properties文件出现异常了:"+e.getMessage());
        }

        //下面初始化 ThreadLocal这个类
        threadLocal = new ThreadLocal<>();
    }

    /**
     * 这个方法用户获取数据库的连接
     *
     * @return
     */
    public static Connection getConnection() throws SQLException {
        Connection connection1 = threadLocal.get();
        if (null != connection1) {
            return connection1;
        }
        //如果执行到这里 说明ThreadLocal中是没有这个对象的
        connection1 = dataSource.getConnection();
        //将上面的连接放到咋们的ThreadLocal中去
        threadLocal.set(connection1);
        return connection1;
    }

    /**
     * 关闭咋们资源
     */
    public static void close() throws SQLException {
        Connection connection = threadLocal.get();
        if (null != connection) {
            connection.close();
        }
    }
}

4.2.3、编写db.properties文件和资源目录

driverClassName=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///cd2106
username=root
password=root

4.2.4、编写测试

    /**
     * 测试Druid的使用
     */
    @Test
    public void testDruid(){
        try {
            Connection connection = DruidUtils.getConnection();
            //我们就可以使用这个Connection对象来进行处理了
            PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user limit 0,10");
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){

                String userName = resultSet.getString("userName");
                String password = resultSet.getString("password");
                System.out.println("查询数来的userName是:"+userName+"----password:"+password);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

5、讲一个组件的使用(dbutils)

dbutils这是一个组件  这个组件的主要功能是完成咋们的数据库的访问

你们肯定有个疑问:
 
 就是我们有了JDBC为啥还要使用dbutils呢? 
 
 我们的dbutils实际上是 咋们的JDBC的一个封装 因为JDBC本身的使用 代码还是比较复杂的 所以使用了dbutils之后就可以很简单的就完成数据库的访问
 
 dbutils就是咋们的JDBC的一个封装而已  没什么高深的

6、Beanutils组件(略,懒)

7.元数据的使用(略,没人看)

8.事物的隔离级别(略,写个屁)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值