2.2 JDBC&XML

一:JDBC


1.JDBC 概述
  • JDBC(Java Data Base Connectivity) 是 Java 访问数据库的标准规范.是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范.

  • JDBC 原理: JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。

  • JDBC就是由sun公司定义的一套操作所有关系型数据库的规则(接口),而数据库厂商需要实现这套接口,提供数据库
    驱动jar包, 我们可以使用这套接口编程,真正执行的代码是对应驱动包中的实现类。
    在这里插入图片描述

2.JDBC 开发
  • 1.加载驱动:Class.forName(数据库驱动实现类)
  • 2.获取连接:使用 DriverManager类的静态方法getConnection方法,获取数据库的连接
  • 3.获取Statement对象
  • 4.处理结果集:只有在进行查询操作的时候, 才会处理结果集ResultSet
  • 5.释放资源:先开的后关,后开的先关,ResultSet ==> Statement ==> Connection
    在这里插入图片描述
3.SQL注入问题
  • SQL注入: 我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了原有SQL 真正的意义,以上问题称为 SQL注入。
# SQL注入演示 
-- 填写一个错误的密码 
SELECT * FROM jdbc_user WHERE username = 'tom' AND PASSWORD = '123' OR '1' = '1';

相当于 select * from user where true=true; 查询了所有记录
如果这是一个登陆操作,那么用户就登陆成功了.显然这不是我们想要看到的结果
  • 要解决 SQL 注入,就不能让用户输入的密码和我们的SQL语句进行简单的字符串拼接。
4.预处理对象
  • PreparedStatement 是Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的SQL语句对象.

  • 预编译: 是指SQL语句被预编译,并存储在PreparedStatement对象中。然后可以使用此对象多次高效地执行该语句。

  • PreparedStatement特点: 因为有预先编译的功能,提高SQL的执行效率。可以有效的防止 SQL 注入的问题,安全性更高
    在这里插入图片描述

  • Statement 与 PreparedStatement的区别

  • 1.Statement用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句。
  • 2.PrepareStatement是预编译的SQL语句对象,语句中可以包含动态参数“?”,在执行时可以为“?”动态设置参数值。
  • 3.PrepareStatement可以减少编译次数提高数据库性能。
5.JDBC 控制事务
  • 使用Connection中的方法实现事务管理
  • void setAutoCommit(boolean autoCommit):参数是 true 或 false 如果设置为 false,表示关闭自动提交,相当于开启事务
  • void commit():提交事务
  • void rollback():回滚事务
  • 开发步骤
  • 1.获取连接
  • 2.开启事务
  • 3.获取到 PreparedStatement , 执行两次更新操作
  • 4.正常情况下提交事务
  • 5.出现异常回滚事务
  • 6.最后关闭资源
public class TestJDBCTransaction {

    //使用JDBC操作事务
    public static void main(String[] args) {

        Connection con = null;
        PreparedStatement ps = null;

        try {
            //1.获取连接
            con = JDBCUtils.getConnection();

            //2.开启事务
            con.setAutoCommit(false);  //手动提交事务

            //3.获取预处理对象 执行SQL (两次修改操作)
            //3.1 tom账户 - 500
            ps = con.prepareStatement("update account set money = money - ? where name = ?");
            ps.setDouble(1,500.0);
            ps.setString(2,"tom");
            ps.executeUpdate();

            //模拟 tom转账之后出现异常
            System.out.println(1 / 0);

            //3.2 jack账户 + 500
            ps = con.prepareStatement("update account set money = money + ? where name = ?");
            ps.setDouble(1,500.0);
            ps.setString(2,"jack");
            ps.executeUpdate();

            //4.提交事务 (正常情况)
            con.commit();
            System.out.println("转账成功! !");

        } catch (SQLException e) {
            e.printStackTrace();
            //5.出现异常就回滚事务
            try {
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

        } finally {
            //6.释放资源
            JDBCUtils.close(con,ps);
        }

    }

}

二:数据库连接池和DBUtils


  • 连接池: 实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池.

  • 连接池的好处: 用池来管理Connection,这样可以重复使用Connection。 当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。

  • 普通 JDBC方式:
    在这里插入图片描述

  • 连接池方式:

  • Java为数据库连接池提供了公共的接口: javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!常见的连接池有 DBCP连接池, C3P0连接池, Druid连接池,

  • DBCP 是一个开源的连接池,是Apache成员之一,在企业开发中也比较常见,tomcat内置的连接池。

  • 常见配置项:
  • driverClassName: 数据库驱动名称
  • url: 数据库地址
  • username: 用户名
  • password: 密码
  • maxActive: 最大连接数量
  • maxIdle: 最大空闲连接
  • minIdle: 最小空闲连接
  • initialSize: 初始化连接
		/**
		 * DBCPUtils 工具类
		 */
		public class DBCPUtils {
		
		    //1.定义常量 保存数据库连接的相关信息
		    public static final String DRIVERNAME = "com.mysql.jdbc.Driver";
		    public static final String URL = "jdbc:mysql://localhost:3306/lagou_jy?characterEncoding=UTF-8";
		    public static final String USERNAME = "root";
		    public static final String PASSWORD = "root";
		
		    //2.创建连接池对象 (有DBCP提供的实现类)
		    public static BasicDataSource dataSource = new BasicDataSource();
		
		    //3.使用静态代码块进行配置
		    static{
		        dataSource.setDriverClassName(DRIVERNAME);
		        dataSource.setUrl(URL);
		        dataSource.setUsername(USERNAME);
		        dataSource.setPassword(PASSWORD);
		        dataSource.setMaxActive(20);
		    }
		
		    //4.获取连接的方法
		    public static Connection getConnection() throws SQLException {
		
		        //从连接池中获取连接
		        Connection connection = dataSource.getConnection();
		        return connection;
		    }
		
		    //5.释放资源方法
		    public static void close(Connection con, Statement statement){
		        if(con != null && statement != null){
		            try {
		                statement.close();
		                con.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		    }
		
		    //5.释放资源方法
		    public static void close(Connection con, Statement statement, ResultSet resultSet){
		        if(con != null && statement != null && resultSet != null){
		            try {
		                resultSet.close();
		                statement.close();
		                con.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		    }
		
		}
  • C3P0 是一个开源的JDBC连接池,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。

      配置文件c3p0-config.xml,文件名不可更改,直接放到src下,也可以放到到资源文件夹中
    
      <c3p0-config>
      
      	<!--默认配置--> 
      	<default-config> 
      		<property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/lagou_jy?characterEncoding=UTF-8</property> 
      		<property name="user">root</property> 
      		<property name="password">root</property> 
      		
      		<!-- initialPoolSize:初始化时获取三个连接, 取值应在minP
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值