JDBC知识点概述

JDBC(java database connectivity)(java数据库连接)

JDBC即是使用统一的一套java代码操作所有的关系型数据库
注意:在一个模块或项目中所有的jar应该导入到一个libs包中

类似于 Person是接口,Worker是实现类, Person p=new Worker();

    public class JDBCDemo01 {
    public static void main(String[] args) throws Exception {
        //1、导入驱动jar包
        //2、注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //3、获取数据库的连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javawebtest01", "root", "123456");
        //4、定义SQL语句
        String sql = "update stuinfo set math=100 where id=1";//将id为1的数学成绩改为100
        //5、获取执行sql语句的对象
        Statement stmt = conn.createStatement();
        //6、执行sql语句,接受返回结果
        int count = stmt.executeUpdate(sql);
        //7、处理结果
        System.out.println(count);
        //8、释放资源
        stmt.close();
        conn.close();

    }
}

JDBC的各个对象

  1. DriverManager(驱动管理对象)
    • 功能:
      1. 注册驱动 告诉程序该用哪个数据库驱动jar包
        Class.forName(“com.mysql.cj.jdbc.Driver”);也是注册驱动
        在Driver类中的静态代码块 DriverManager.registerDriver(new Driver());
        也是在用Driver中的registerDriver方法;
        mysql5之后该代码块可以不写–>Class.forName(“com.mysql.cj.jdbc.Driver”);
      2. 获取数据库连接
        Connection conn = DriverManager.getConnection(url,user,password);
        url指定连接的路径 即ip、端口、数据库名称
        url写法: jdbc:mysql://ip地址(域名):端口号/数据库名称
        若使用本机的3306端口,则url可以简写为–> jdbc:mysql:///javawebtest01
  2. Connection(数据库连接对象)
    1. 功能:获取执行sql的对象
    2. 管理事务:
      • 开启事务setAutoCommit(); 调用该方法设置参数为false,即开启事务
      • 提交事务commit();
      • 回滚事务rollback();
  3. Statement(执行sql的对象) 不能防止sql注入问题
    1. boolean execute(String sql);执行任意sql语句
    2. int executeUpdate(String sql); 执行DML(增删改)语句、DDL(对表和库操作)语句
      返回值是影响的行数,可以通过影响行数判断DML语句是否执行成功(>0)
    3. ResultSet executeQuery(String sql); 执行DQL(查询)语句
      返回结果集对象
  4. ResultSet(结果集对象) 封装查询到的结果对象
    next(); 游标向下移动
    get×××(); 获取数据 xxx代表数据类型 如getInt();
    该方法参数可以就收int或String,int代表列的编号(1即第一列的值)String代表列的名称
  5. PreparedStatement(执行sql的对象) 功能比Statement更强大,能防止sql注入问题

抽取JDBC工具类 MyUtils.JDBCUtils

目的->简化书写,简化重复度高的代码
工具类的方法都建议静态,方便调用


JDBC事务管理

在catch中回滚,实现回滚

管理事务:

  • 开启事务setAutoCommit(); 调用该方法设置参数为false,即开启事务
  • 提交事务commit();
  • 回滚事务rollback(); ,在catch中处理

JDBC事务操作以及preparedStatement使用案例↓

public class TestTransaction {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps1 = null;
        PreparedStatement ps2 = null;

        try {
            conn = JDBCUtils.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            String sql1 = "update account set balance=balance-? where id=?";
            String sql2 = "update account set balance=balance+? where id=?";
            ps1 = conn.prepareStatement(sql1);
            ps2 = conn.prepareStatement(sql2);
            ps1.setInt(1, 500);
            ps1.setInt(2, 1);
            ps2.setInt(1, 500);
            ps2.setInt(2, 2);
            //使用preparedStatement,执行execute函数时不需要传递参数
            ps1.executeUpdate();
            int a = 3 / 0;//手动制造异常,没使用回滚的话ps1会执行,ps2不会执行,
            ps2.executeUpdate();
            //执行这里就提交事务
            conn.commit();

        } catch (Exception e) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps1, conn);
            JDBCUtils.close(ps2, null);
        }
    }
}

数据库连接池

数据库连接池:存放数据库连接的容器
当系统初始化后,容器被创建,容器中会申请一些连接对象,↓
用户访问数据库时从容器中获取对象,访问完成之后归还给容器
如果连接对象Connection是从连接池中获取的↓
那么调用Connection.close()方法则不会关闭连接,而是归还给连接池

  1. 节约资源
  2. 用户访问高效
  • C3P0 数据库连接池技术
    • 导入jar包
    • 定义配置文件 c3p0.properties 或者 c3p0-config.xml
      直接放在src目录下
    • 创建核心对象
    • 获取连接
public class TestC3P0 {
    public static void main(String[] args) throws SQLException {
        //1、创建数据库连接池对象
        DataSource ds = new ComboPooledDataSource();//使用默认配置,有参数就是指定名称配置
        //3、获取数据库连接对象
        Connection conn = ds.getConnection();
        //归还连接对象到连接池
        conn.close();

    }
}
  • Druid 数据库连接池技术,由Alibaba提供
    • 导入jar包
    • 定义配置文件properties
    • 加载配置文件Properties
    • 获取数据库连接对象:通过工厂类来获取DruidDataSourceFactory
    • 获取连接

Druid工具类

public class TestDruid {
    public static void main(String[] args) throws Exception {
        //Druid的配置文件是properties文件可以放在任意位置,起任意名字
        Properties pro = new Properties();
        InputStream is = TestDruid.class.getClassLoader().getResourceAsStream("DatabaseConnectionPool/druid.properties");
        pro.load(is);
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }
}
定义Druid工具类
public class DruidUtils {
    //定义成员变量
    private static DataSource ds;

    static {
        Properties pro = new Properties();
        try {
            pro.load(DruidUtils.class.getClassLoader().getResourceAsStream("MyUtils/druid_utils.properties"));
            //获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    //释放资源
    public static void close(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();
            }
        }*/
        close(null, statement, connection);
    }

    //重载释放
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();//释放
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();//归还
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //获取连接池
    public static DataSource getDataSource() {
        return ds;
    }

}

使用Druid工具类,操作数据库的模板,以后操作数据库就参照如下代码
注意:在同一项目/模板中不能存在内容一样的配置文件

//使用DruidUtils工具类
public class UseDruidUtils {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        //向account表添加记录
        try {
            //1、获取连接
            conn = DruidUtils.getConnection();
            //2、定义sql
            String sql = "insert into account values(null,?,?);";
            //3、获取preparedStatement对象
            ps = conn.prepareStatement(sql);
            //4、给?赋值
            ps.setString(1, "DruidUtils");
            ps.setInt(2, 10000);
            //5、执行sql
            int count = ps.executeUpdate();
            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DruidUtils.close(ps, conn);
        }
    }
}


JDBC Template

JDBCTemplate 是Spring框架对JDBC的简单封装

  1. 导入jar包
    如果使用的是 druid jdbcTemplate ,需要导入 ↓
    JDBCTemplate jar包5个+druid jar包1个 + 数据库驱动包
  2. 创建jdbcTemplate对象,依赖数据源DataSource
  3. 调用jdbcTemplate的方法来完成CRUD(增删改)的操作
    update(); 执行DML
    queryForMap(); 查询结果,将结果集封装为map集合
    queryForList(); 查询结果,结果封装为List集合
    query(); 查询结果,将结果封装为JavaBean对象
    queryForObject();将查询结果封装为对象

JdbcTemplate基本使用

public class TestTemplate {
    public static void main(String[] args) {
        //1、创建JdbcTemplate对象
        JdbcTemplate template = new JdbcTemplate(DruidUtils.getDataSource());
        //2、调用方法
        String sql = "update account set balance=? where id=?";
        int count = template.update(sql, 888, 1);//使用参数给?赋值
        System.out.println(count);
    }
}

采用Junit单元测试的方法来练习Template的方法

package JDBCTemplate;

import MyUtils.DruidUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class Junit_PracticeTemplate {
    //Junit单元测试,让方法独立执行
    private JdbcTemplate template = null;
    private String sql = null;

    @Before
    public void init() {
        template = new JdbcTemplate(DruidUtils.getDataSource());
        sql = "";
    }

    @After
    public void end() {
        System.out.println("method end !");
    }

    //1、修改一条记录
    @Test
    public void test1() {
        sql = "update account set balance=? where id=?";
        int count = template.update(sql, 666, 1);
        System.out.println(count);
    }

    //2、添加一条记录
    @Test
    public void test2() {
        sql = "insert into account values(?,?,?);";
        int count = template.update(sql, null, "黑马程序员", 20000);
        System.out.println(count);
    }

    //3、删除刚刚添加的记录
    @Test
    public void test3() {
        sql = "delete from account where id=?";
        int count = template.update(sql, 4);
        System.out.println(count);
    }

    //4、查询id为1的记录,并封装到Map集合中
    @Test
    public void test4() {
        sql = "select * from account where id=?";
        //该结果集查询的长度只能是1
        //key=列名   value=值
        Map<String, Object> map = template.queryForMap(sql, 1);
        System.out.println(map);
    }

    //5、查询所有的记录封装为List集合
    @Test
    public void test5() {
        sql = "select * from stuinfo";
        List<Map<String, Object>> list = template.queryForList(sql);
        for (Map<String, Object> stringObjectMap : list) {
            System.out.println(stringObjectMap);
        }
    }

    //6、查询所有的记录,将其封装为Emp对象的List集合
    @Test
    public void test6() {
        sql = "select * from account";
        List<Emp> empList = template.query(sql, new RowMapper<Emp>() {

            @Override
            public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
                Emp emp = new Emp();
                int id = resultSet.getInt("id");
                String name = resultSet.getString(2);
                int balance = resultSet.getInt(3);
                emp.setId(id);
                emp.setName(name);
                emp.setBalance(balance);
                return emp;
            }
        });
        for (Emp emp : empList) {
            System.out.println(emp);
        }
    }

    //6-2、简化上一个方法
    @Test
    public void test6_2() {
        sql = "select * from account";
        List<Emp> empList = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
        for (Emp emp : empList) {
            System.out.println(emp);
        }
    }

    //7、查询总记录数
    @Test
    public void test7() {
        sql = "select count(id) from stuinfo";
        Long total = template.queryForObject(sql, Long.class);
        System.out.println(total);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值