JDBC基础、连接池、Spring JDBCTemplate

目录

 JDBC相关API

DriverManager类:驱动管理对象

Connection:数据库连接对象

获取执行SQL的对象

管理事务

Statement:执行sql的对象

ResultSet:结果集对象,封装查询结果

 PreparedStatement:执行sql的对象

数据库连接池

C3P0数据库连接池

Druid数据库连接池

Spring JDBCTemplate


JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。

 JDBC相关API

注册驱动程序:Class.forName("com.mysql.jdbc.Driver");

代码分析:使用反射机制,将字节码文件加载至内存,返回一个Class对象。该类中定义了一个静态代码块,作用就是注册驱动,所以无需返回对象。(mysql5之后可以省略)

DriverManager类:驱动管理对象

static Connection getConnection(String url, String user, String password)   获取数据库的连接

如果连接的是本地数据库,并且端口号是3306,则url可以简写成: jdbc:mysql:///数据库名称

Connection:数据库连接对象

获取执行SQL的对象

  • Statement createStatement()
  • PreparedStatement prepareStatement(String sql) 

管理事务

  • 开启事务:setAutoCommit(boolean autoCommit)  参数为false为开启事务
  • 提交事务:commit()
  • 回滚事务:rollback()

Statement:执行sql的对象

  • int executeUpdate(String sql):执行DML、DDL语句 返回值是影响行数
  • ResultSet executeQuery(String sql)  :执行DQL(select)语句

ResultSet:结果集对象,封装查询结果

  • boolean next():游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据)
  • getXxx(参数):获取数据    参数可以是列的编号(从1开始),也可以是列的名称

 PreparedStatement:执行sql的对象

SQL注入问题

在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题

               1. 输入用户随便,输入密码:a' or 'a' = 'a
                2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 

预编译的SQL:参数使用?作为占位符,解决了SQL注入问题

  1. PreparedStatement Connection.prepareStatement(String sql)   获取执行SQL语句对象
  2. 使用setXxx(参数1,参数2) 给占位符赋值,参数1:位置编号,参数2:数据
  3. 执行sql语句,并返回查询结果 excuteQuery()或者excuteUpdate()

示例代码:SQL注入

  public static void main(String[] args) throws ClassNotFoundException, SQLException {
        System.out.println("请输入用户名:");
        Scanner in = new Scanner(System.in);
        String name = in.nextLine();
        System.out.println("请输入密码:");
        String password = in.nextLine();

        Class.forName("com.mysql.jdbc.Driver");//注册驱动
        Connection connection = DriverManager.getConnection("jdbc:mysql:///db_6", "root", "110120");//获取连接对象
        String sql="select* from user2 where username='"+name+"'and password='"+password+"'";
        System.out.println(sql);//select* from user2 where username='asd'and password='a' or 'a'='a' SQL注入问题,条件判断永远为真,查询的是全表
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(sql);
        if (resultSet.next()){//判断下一行是否有数据
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        statement.close();//释放资源
        connection.close();//释放资源

    }

//PreparedStatement 解决了SQL注入
 public static void main(String[] args) throws ClassNotFoundException, SQLException {
        System.out.println("请输入用户名:");
        Scanner in = new Scanner(System.in);
        String name = in.nextLine();
        System.out.println("请输入密码:");
        String password = in.nextLine();
        Class.forName("com.mysql.jdbc.Driver");//注册驱动
        Connection connection = DriverManager.getConnection("jdbc:mysql:///db_6", "root", "110120");//获取连接对象
        String sql="select * from user2 where username=? and password=?";//含有占位符的sql语句
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1,name);//给占位符赋值
        statement.setString(2,password);
        ResultSet resultSet = statement.executeQuery();
        if(resultSet.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        statement.close();
        connection.close();
    }

案例:使用事务

public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");//注册驱动
        Connection connection = DriverManager.getConnection("jdbc:mysql:///db_6", "root", "110120");//获取连接对象
        connection.setAutoCommit(false);//开启事务
        String sql1="update account set balance= balance-500 where id=1";
        String sql2="update account set balance= balance+500 where id=2";
        Statement statement = connection.createStatement();
        statement.executeUpdate(sql1);
        int i=1/0;//制造错误
        statement.executeUpdate(sql2);
        connection.commit();//提交事务
        connection.rollback();//事务回滚
        statement.close();
        connection.close();
    }

数据库连接池

连接池:其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

好处:

  • 节约资源
  • 用户访问高效

实现数据库连接池的方法 标准接口DataSource

相关方法:

  • getConnection():获取连接
  • close():归还连接

C3P0数据库连接池

步骤:

  • 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar  还有数据库驱动jar包
  • 定义配置文件:c3p0-config.xml  直接将文件放在src目录下即可
  • 创建核心对象 数据库连接池对象 ComboPooledDataSource
  • 获取连接: getConnection

示例代码

配置文件 :可以进行多个数据库配置(一般使用默认)

<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_1</property>
    <property name="user">********</property>
    <property name="password">********</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">10</property>
    <property name="checkoutTimeout">3000</property>
  </default-config>

  <named-config name="otherc3p0"> 
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_1</property>
    <property name="user">********</property>
    <property name="password">********</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>

测试代码

 public static void main(String[] args) throws SQLException {
        DataSource dataSource = new ComboPooledDataSource();//建立对象,使用默认配置
        DataSource otherc3p0 = new ComboPooledDataSource("otherc3p0");//建立对象,使用名为otherc3p0的配置
        Connection connection = dataSource.getConnection();//获得连接
        connection.close();//归还连接
    }

Druid数据库连接池

步骤

  • 导入jar包 druid-1.0.9.jar
  • 定义配置文件:properties形式、可以叫任意名称,可以放在任意目录下
  • 加载配置文件
  • 获取数据库连接池对象:通过工厂来来获取  DruidDataSourceFactory
  • 获取连接:getConnection

示例代码

配置文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db_1
username=********
password=********
initialSize=5
maxActive=10
maxWait=3000

测试代码

public static void main(String[] args) throws Exception {
        Properties properties = new Properties();//连接Properties对象
        properties.load(test22.class.getResourceAsStream("druid.properties"));//加载文件
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//通过工厂类 获得DataSource对象、
        Connection connection = dataSource.getConnection();//获取连接
        connection.close();//归还连接
    }

创建工具类:

  • 在静态代码块中创建数据库连接池对象  
  • 成员方法:获取连接、释放资源、获取连接池对象

Spring JDBCTemplate

Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发

创建JdbcTemplate对象。依赖于数据源DataSource。

成员方法

  • update(sql,args...):执行DML语句。增、删、改语句
  • queryForObject:查询结果,将结果封装为对象 (多个结果)
  • query():查询结果,将结果封装成对象(单个结果)
  • queryForList():查询结果将结果集封装为list集合
    •  将每一条记录封装为一个Map集合,再将Map集合装载到List集合中

示例代码

public static void main(String[] args) throws Exception {
        Properties properties = new Properties();//连接Properties对象
        properties.load(test22.class.getClassLoader().getResourceAsStream("druid.properties"));//加载文件
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//通过工厂类 获得DataSource对象、
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql1="insert into user2 values(?,?)";
        jdbcTemplate.update(sql1,"张三","123456789");//添加数据
        String sql2="select * from user2";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql2);//将集合封装成list 一行一行的读取{username=tom, password=123}
        for (Map<String, Object> map : maps) {
            System.out.println(map);
        }
        List<user> query = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(user.class));//将多个结果封装成对象
        for (user user : query) {
            System.out.println(user);
        }
        String sql3="select * from user2 where username='张三'";
        user user = jdbcTemplate.queryForObject(sql3, new BeanPropertyRowMapper<>(user.class));//将单个结果封装成对象
        System.out.println(user);
        
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值