0
点赞
收藏
分享

微信扫一扫

JDBC应用最全笔记(附带案例)

JDBC

一、概述

二、理解

在这里插入图片描述

在这里插入图片描述

三、JDBC API

四、JDBC的使用

 private static void queryAll() throws ClassNotFoundException, SQLException {
        //  1、加载驱动
        // DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        Class.forName("com.mysql.jdbc.Driver");
        //  2、获取连接  参数1:连接路径    参数2:用户名  参数3:密码
        //  https://downloads.mysql.com/archives/c-j/
        Connection connection = DriverManager
                .getConnection("jdbc:mysql://localhost:3306/java0210", "root", "123456");

        System.out.println(connection);
        System.out.println(connection==null?"连接失败":"连接成功");

        //3、 编写sql语句
        String sql = "select * from user";

        //4、创建命令对象
        Statement statement = connection.createStatement();

        //5、执行sql语句 返回结果
        ResultSet rs = statement.executeQuery(sql);


        //6、处理结果    rs.next()如果为true 集合中还有内容 如果为false 数据获取完毕
        while(rs.next()){
            String name = rs.getString("name");
            int age = rs.getInt("age");
            System.out.println("姓名:"+name+"\t姓名:"+age);
           // System.out.println(rs.getString("name")+" 年龄:"+rs.getInt("age"));
        }

        //7、释放资源  遵循 先开后关原则
        rs.close();
        statement.close();
        connection.close();
    }

五、连接池

5.1、为什么使用连接池

5.2、连接池原理

5.3、连接池的好处

5.4、常见的开源连接池

5.5、连接池的使用

5.5.1、c3p0连接池

代码配置⽅式

 //1、创建连接池对象
        ComboPooledDataSource cpds = new ComboPooledDataSource();
#必配信息
c3p0.driverClass = com.mysql.jdbc.Driver
c3p0.jdbcUrl = jdbc:mysql://localhost:3306/java0210
c3p0.user = root
c3p0.password = 123456

#选配
c3p0.InitialPoolSize = 10   #初始连接数
c3p0.MaxPoolSize = 200		#最大连接数
c3p0.MinPoolSize = 15		#最小连接数
c3p0.MaxIdleTime = 30		#最大空闲时间
 //从池子中获取连接
        Connection connection = cpds.getConnection();
		//1、编写sql
        String sql = "select * from user where age = 23";
        //2、创建命令对象
        Statement statement = connection.createStatement();
        //3、执行命令 返回结果
        ResultSet resultSet = statement.executeQuery(sql);
        //4、处理结果
        if (resultSet.next()){
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            System.out.println("姓名:"+name+"\t姓名:"+age);
        }
        //5、把连接对象放回连接池
        connection.close();

5.5.2、Druid连接池

#必配
driver.ClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/java0210
username = root
password = 123456
#选配
initialSize = 15		#初始连接数
maxActive = 100			#最大连接数
minIdle = 5				#最小连接数
maxWait = 30000			#最大空闲时间
// 一、读取配置文件
        Properties properties = new Properties();

        // 根据当前线程对象的上下文类加载器 以流的方式 读取src目录下的文件
        InputStream asStream = Thread.currentThread()
                .getContextClassLoader().getResourceAsStream("druid.properties");

        properties.load(asStream);
// 二、创建druid连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
 //从池子中获取连接
        Connection connection = dataSource.getConnection();
		//1、编写sql
        String sql = "select * from user where age = 23";
        //2、创建命令对象
        Statement statement = connection.createStatement();
        //3、执行命令 返回结果
        ResultSet resultSet = statement.executeQuery(sql);
        //4、处理结果
        if (resultSet.next()){
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            System.out.println("姓名:"+name+"\t姓名:"+age);
        }
        //5、把连接对象放回连接池
        connection.close();

5.6、封装JDBCTools

ThreadLocal类

public class JDBCPoolTools2 {
    static DataSource dataSource;
    // 实例化ThreadLocal类
    private static ThreadLocal<Connection> t = new ThreadLocal<>();
    static {
        try{
            // 一、读取配置文件
            Properties properties = new Properties();

            // 根据当前线程对象的上下文类加载器 以流的方式 读取src目录下的文件
            InputStream asStream = Thread.currentThread()
                    .getContextClassLoader().getResourceAsStream("druid.properties");
            properties.load(asStream);
            //2、创建连接池
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 定义一个获取连接的静态方法
    public static Connection getConnection(){
        try {
            //1、从连ThreadLocal中获取连接
            Connection connection = t.get();
            if (connection==null){
                //2、如果连接为空,从连接池中获取一个连接对象
                t.set(dataSource.getConnection());
                //3、把这个连接对象绑定到ThreadLocal类
                connection = t.get();
            }
            return connection;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //封装释放连接对象的方法
    public static void release(){
        // 1、将连接对象 和 ThreadLocal类 解绑
        Connection connection = t.get();
        t.remove();
        // 2、释放资源
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

测试类

public static void main(String[] args) {
        //    建立连接  从JDBCPoolTools2中调用 getConnection()方法
        Connection connection = JDBCPoolTools2.getConnection();
        try {
        //     sql操作
            String sql = "select * from admin_user";
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                System.out.println("账号:"+username+"\t密码:"+password);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
        //     必须必须【解绑】和【释放资源】,从JDBCPoolTools2中调用 release()方法
            if (connection!=null){
                Up_DruidPool_03.release();
            }
        }
    }

六、juint

6.1、概述

6.2、使用

6.3、常见注解

七、SQL注入

7.1、理解

7.2、解决

public class JDBCTest2 {
    String username;
    String pwd;
    Connection connection;
    @Before
    public void bef(){
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        username = input.nextLine();
        System.out.println("请输入密码:");
        pwd = input.nextLine();

        connection = JDBCTools.getConnection();
    }
    @Test  // 使用Statement
    public void testLogin1(){

        // 根据用户名和密码查询用户
        try {

            // select * from user where name='大洋洋' and password='123321';
            String sql = "select * from user where name='"+username+"' and password='"+pwd+"'";

            Statement statement = connection.createStatement();

            ResultSet resultSet = statement.executeQuery(sql);

            System.out.println(resultSet.next()?"登录成功!":"登录失败!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }

    @Test  // 使用PreparedStatement
    public void testLogin2(){
        try {
            // 1. 编写sql语句
            String sql = "select * from user where name=? and password=?";

            // 2. 创建命令对象 预编译sql语句
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            // 3. 传递sql中的参数
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, pwd);

            // 4. 执行sql命令
            ResultSet resultSet = preparedStatement.executeQuery();

            // 5. 处理结果
            System.out.println(resultSet.next()?"登录成功!":"登录失败!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }
    @After
    public void aft(){
        JDBCTools.release();
    }
}

八、事务实现

public class JDBCTxTest {
    Connection connection;
    @Before
    public void bef(){
        connection = JDBCTools.getConnection();
    }

    @Test  // 使用事务
    public void textUseTx(){
        try {
            // 1. 设置事务提交为手动  2. 开启一个新的事务
            connection.setAutoCommit(false);

            String sql = "update user set money=? where uid=?";

            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setDouble(1, 900);
            preparedStatement.setInt(2, 1);

            preparedStatement.executeUpdate();

            // 模拟异常
            int i = 10/0;

            preparedStatement.setDouble(1, 1100);
            preparedStatement.setInt(2, 2);

            preparedStatement.executeUpdate();

            connection.commit();
            System.out.println("转账成功!");
        } catch (SQLException throwables) {
            try {
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        }
    }

    @After
    public void aft(){
        JDBCTools.release();
    }
}

九、批处理

9.1、概述

9.2、实现

public class JDBCBatchTest {
    Connection connection;
    @Before
    public void bef(){
        connection = JDBCTools.getConnection();
    }

    @Test  // 使用批处理
    public void textUseBatch(){
        try {
            String sql = "insert into user(name, password, money) values(?,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            long start = System.currentTimeMillis();

            for(int i=1; i<=10000; i++){
                preparedStatement.setString(1,"root"+i);
                preparedStatement.setString(2, i+"");
                preparedStatement.setDouble(3, i);
                // 保存到批处理中
                preparedStatement.addBatch();

                if(i%100==0){
                    // 执行批处理
                    preparedStatement.executeBatch();

                    // 清除批处理  便于下一次使用
                    preparedStatement.clearBatch();
                }
            }

            long end = System.currentTimeMillis();
            System.out.println("插入10000条花费的时间:"+(end-start)); // 6080
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    @After
    public void aft(){
        JDBCTools.release();
    }
}

十、DBUtils

10.1、简介

10.2、作用

10.2、常用方法

10.4、使用

QueryRunner qr = new QueryRunner();
// 执⾏增删改
int update = qr.update(connection,sql,params); 
// 查询单条数据
T t = qr.query(connection,sql,new BeanHandler,params);
// 查询多条数据
List t = qr.query(connection,sql,new BeanListHandler,params);
// 查询特殊数据类型,如返回值为数量等等
Object t = qr.query(connection,sql,new ScalerHandler,params);

十一、Dao封装

11.1、介绍

11.2、作用

11.3、封装

public class BasicDao<T> {
    QueryRunner qr;
    {
        qr = new QueryRunner();
    }
    // 1. 增删改方法
    public int update(String sql, Object...params){
        try {
            return qr.update(JDBCTools.getConnection(), sql, params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 2. 查询单个
    public T querySingle(String sql, Class<T> clazz, Object...params){
        try {
            return qr.query(JDBCTools.getConnection(), sql, new BeanHandler<>(clazz), params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 3. 查询多个
    public List<T> queryMore(String sql, Class<T> clazz, Object...params){
        try {
            return qr.query(JDBCTools.getConnection(), sql, new BeanListHandler<>(clazz), params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 4. 查询个数
    public Object scale(String sql, Object...params){
        try {
            return qr.query(JDBCTools.getConnection(), sql, new ScalarHandler<>(), params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}

十二、项目三层架构

12.1、理解

12.2、特点

     return qr.query(JDBCTools.getConnection(), sql, new ScalarHandler<>(), params);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

}


## 十二、项目三层架构

### 12.1、理解

> 【**三层架构**】 通常意义上的三层架构就是将整个业务应⽤划分为:界⾯层、业务逻辑层、数据访问层。区分层次的⽬的即为了 “⾼内聚低耦合” 的思想。在软件体系架构设计中,分层式结构是最常⻅,也是最重要的⼀种结构。微软推荐的分层式结构⼀般分为三层,从下⾄上分别为:数据访问层、业务逻辑层(⼜或称为领域层)、表示层。
>
>  **表示层(JSP)**
>
>  表现层也称为界⾯层,位于最外层(最上层),离⽤户最近。⽤于显示数据和接收⽤户输⼊的数据,为⽤户提供⼀种交互式操作的界⾯。
>
>  **业务层(service)**
>
> * 业务层在体系架构中的位置很关键,它处于数据访问层与表示层中间,起到了数据交换中承上启下的作⽤。
>
> * 由于层是⼀种弱耦合结构,层与层之间的依赖是向下的,底层对于上层⽽⾔是“⽆知”的,改变上层的设计对于其调⽤的底层⽽⾔没有任何影响。如果在分层设计时,遵循了⾯向接⼝设计的思想,那么这种向下的依赖也应该是⼀种弱依赖关系。
>
>  **持久层(DAO)**
>
>  持久层,有时候也称为是数据访问层,其功能主要是负责数据库的访问,可以访问数据库系统

### 12.2、特点

> 1、上⼀层可以调⽤下⼀层 但是 下⼀层不能调⽤上⼀层
>
> 2、不可以隔层调⽤

![在这里插入图片描述](https://img-blog.csdnimg.cn/4b4814e9b2d54fbb9cab16991b7b31ff.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUElLYXBpa2FhYWE=,size_20,color_FFFFFF,t_70,g_se,x_16)

举报

相关推荐

0 条评论