了解JDBC

一、什么是JDBC

  • JDBC全称Java Database Connectivity
  • JDBC可以通过载入不同的数据库的“驱动程序”而与不同的数据库进行连接。

二、JDBC的优点

  • 使用的驱动不同,即可连接不同的数据库。
  • 使用同一套操作来操作不同的数据库
  • 如果每一个数据库java都制订一套连接方式,那么当不同的数据库更新的时候,java也需要更新自己的代码,而使用jdbc,使用同一套代码来操作,使用不同的驱动程序(驱动程序由数据库厂商提供)来连接,这使得可以连接不同的数据库。

三、JDBC的使用

  • 导入对应数据库的驱动类

  • 加载驱动class.forName(“com.mysql.cj.jdbc.Driver”) 注:com.mysql.cj.jdbc.Driver是mysql 8以上的数据库驱动

  • 获取连接

    • 在考虑使用forName节省资源后,下面介绍的获取连接的方法使用的是DriverManager.getConnection()
      在这里插入图片描述

    • getConnection需要参数

      • url:定义了连接的数据库的路径
        jdbc协议:数据库子协议://主机[:端口][/连接的数据库] 【[]代表可选的】
        • 例如:jdbc:mysql://localhost:3306/testimage
        • 配置流Properties:定义了连接数据库的方式,一般至少包含user和password
        • 不使用配置流时,传入user和password
        • 如果使用匿名登录,则只传入url
          在这里插入图片描述
  • 执行SQL语句

     JDBC执行SQL语句的方式主要有三种:
     1.使用Statement执行sql语句
     2.使用PreparedStatement执行sql语句
     3.使用CallableStatement执行sql语句
    

    上面的 StatementPerPareStatementCallalestatement都可以使用连接对象来获取。
    在这里插入图片描述

    .

    • 使用Statement执行语句

      • Statement对象的获取可以使用createStatement()来获取

      • 获取Statement对象后,对于查询类的sql语句使用:executeQuery(sql),sql是一个字符串sql语句,返回结果是一个结果集

      • 对于更新类(插入、修改、删除、更新)的语句使用:executeUpdate(sql),sql是一个字符串sql语句,返回结果是一个整数(受影响的行数)

        在这里插入图片描述

    • 使用PreparedStatement执行语句

      • PreparedStatement对象的获取可以使用prepareStatement(sql)来获取,注意的是需要传入一条sql语句

      • PreparedStatement的功能类似Statement,但不同的是PreparedStatement可以使用占位符,它是由占位符标识需要输入数据的位置,然后再逐一填入数据。当然,PreparedStatement也可以执行没有占位符的sql语句

         使用占位符后,使用setString或setInt等方法来设置每一位的数据。【有各种对应数据类型的设置方法,比如还有setFloat】
         
         setXXX方法中,第一个参数是位置,第二个是数据
        
      • 获取Statement对象后,对于查询类的sql语句使用:executeQuery(),返回结果是一个结果集

      • 对于更新类(插入、修改、删除、更新)的语句使用:executeUpdate(),返回结果是一个整数(受影响的行数)

      • 对于有sql缓存池的数据库,PreparedStatement的效率要高于Statement
        在这里插入图片描述

    • 使用CallableStatement执行语句

      • CallableStatement主要用来调用存储过程

      • 对于输出参数,需要使用registerOutParameter注册,第一个参数是位置,第二个参数是参数类型(使用Types.xxx)

      • 注册之后,想要获取输出参数,可以使用CallableStatement对象自身的getXXX方法来获取
        在这里插入图片描述

        在这里插入图片描述

  • 关闭连接:

    • 后开启的需要先关闭,Statement、Connection、ResultSet都是需要关闭的

      注意:关闭之前需要留心检查是否为null

四、事务

  • 设置事务管理:连接对象.setAutoCommit(boolean)【当参数为true时,代表允许自动提交(事务管理是关闭的,每一条命令都会自动提交);当为false时,代表不允许自动提交,命令会在执行commit之后再统一提交(开启事务管理的)】
  • 提交事务:连接对象.commit()
  • 回滚事务:连接对象.rollback()

五、数据库连接池

连接池的意义就是提前创建连接,避免需要使用时再申请连接造成的重复申请资源造成的浪费。
连接池负责在需要的时候分发连接,使用者释放连接时需要放回到连接池中。
下面给出的是两个常用的连接池的用法。

1、DBCP:

首先,使用DBCP连接池需要导入包:commons-dbcp.jar和commons-pool.jar【如果需要日志功能,还需要commons-logging-1.2.jar

DBCP根据配置方式,下面给出两种使用方法:

1.手动配置法:

  • 创建BasicDataSource对象: BasicDataSource dataSource = new BasicDataSource();
  • 配置BasicDataSource对象:调用对应函数配置,例如
  • dataSource.setDriverClassName(“com.mysql.jdbc.Driver”);
  • 得到连接对象:Connection conn = ds.getConnection();
  • 操作数据库。(得到数据库连接对象后,就可以像以前一样去操作数据库了)
    在这里插入图片描述
    2.配置文件配置法:
    • 创建BasicDataSourceFactory对象:BasicDataSourceFactory factory = new BasicDataSourceFactory();
    • 利用BasicDataSourceFactory对象的createDataSource函数读取配置文件配置DataSource对象:DataSource dataSource = factory.createDataSource(properties);
    • 得到连接对象:Connection conn = ds.getConnection();
    • 操作数据库。(得到数据库连接对象后,就可以像以前一样去操作数据库了)
      在这里插入图片描述
      当使用完毕后,像往常一样调用close关闭连接即可【这里通过连接池获取的Connection对象已经封装过了,使用close函数相当于放回连接池中】
常用的dbcp.properties的配置信息:
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000


#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

2、C3P0:

首先,使用C3P0连接池需要导入包:c3p0-0.9.1.2.jar【还有扩展包如c3p0-oracle-thin-extras-0.9.1.2.jar】

1.配置文件配置法:

  • 创建配置文件,c3p0的配置文件名字是固定的,必须是c3p0.propertiesc3p0-config.xml,否则识别不了。配置文件的写法看下面【配置文件存储的位置:1.能在classpath中获取到的目录(比如工程的src目录)、2.WEB-INF/classes、3.某些类似功能的路径】
  • 创建ComboPooledDataSource对象【如果有配置文件,那么会读取配置文件来配置ComboPooledDataSource对象】
  • 获取连接
  • 执行sql语句
    在这里插入图片描述
    当你使用完后,Connection对象调用close函数,就会把连接释放会连接池中【这里通过连接池获取的Connection对象已经封装过了,使用close函数相当于放回连接池中】

配置文件c3p0-config.xml的写法:

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost/bank</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <!-- 下面的是额外的配置,如最大连接数,连接池大小。。 
        <property name="initialPoolSize">10</property> 
        <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> 
        <property name="minPoolSize">10</property> <property name="maxStatements">200</property> 
        -->

    </default-config>
    <!-- 上面是默认的,如果不给参数,默认是上面的; -->
    <!-- 下面的是单独的,在创建对象时把下面name中的那个值赋给对象的构造函数,那么将使用下面的配置 -->
    <named-config name="student">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost/student</property>
        <property name="user">root</property>
        <property name="password">123456</property>
    </named-config>

</c3p0-config>

配置文件c3p0.properties的写法:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost/bank
c3p0.user=root
c3p0.password=123456

3.DbUtils
  • DbUtils是apache旗下的一个操作数据库的工具
  • DbUtils可以简化我们对数据库的CRUD操作,一个常用功能是能把查询到的数据自动封装起来,而不再需要我们操作ResultSet。

要想使用DBUtils,首先要导入包:commons-dbutils-1.4.jar

  • 增、删、改:

    • DbUtils的写操作是一类,读操作是一类

    • 写操作主要是调用update函数

      • 新建QueryRunner对象【如果传入一个连接池对象,那么后续操作的数据库连接就是这个连接池的连接;如果不设置,那么执行update时要给一个连接对象】
      • 调用update函数.

在这里插入图片描述
在这里插入图片描述

常见ResultSetHandler实现类:

  • BeanHandler:把数据库中的一行数据根据变量名自动封装到对象中;如果查询语句返回多条结果,将ResultSet中第一行的数据根据变量名自动封装到对象中

  • BeanListHandler:把数据库中的多行数据根据变量名自动封装到对象中,并存储到List中返回。所以返回结果是一个含有多个bean对象的list

  • ScalarHandler:将ResultSet中一条记录的某一列的数据存成Object,返回值是一个Object。不给参数时默认是第一列的值,参数可以给列数,也可以给字段名
    【可以用于统计函数等返回一个值的情况】

  • ArrayHandler:把一条记录的所有数据存储到一个数组中,第一列的数据在数组的第一个位置。

  • ArrayListHandler:与ArrayHandler功能类似,但可以返回包含多个数组的list了。

补充:对于封装成对象的,需要提供一个bean类.class参数,这是为了能创建对象

注:实体类的属性名与数据库字段不对应,无法正确映射匹配。

解决方式为:在dbutils的1.6版本之后,官方给出了当字段名与成员属性名不一致时的解决方案,具体解决方案有2个.

情况一:只涉及到下划线,表字段名用下划线间隔,现在要封装到Javabean中Users类(代码见上),其中属性使用驼峰命名。可以用dbutils1.6提供的BeanProcessor类的子类GenerousBeanProcessor

String sql = "select id,user_name,login_name,user_password,user_level,user_lock from users_t";

// 创建一个BeanProcessor对象
// GenerousBeanProcessor 仅仅重写了父类BeanProcessor的mapColumnsToProperties方法
BeanProcessor bean = new GenerousBeanProcessor();

// 将GenerousBeanProcessor对象传递给BasicRowProcessor
RowProcessor processor = new BasicRowProcessor(bean);

// 最后使用GenerousBeanProcessor的mapColumnsToProperties处理表字段到javabean的属性映射
Users rs = runner.query(sql, new BeanHandler<Users>(Users.class, processor));

return rs;

情况二:完全改变表字段到Javabean属性的映射(如表users_m字段:[yhmid],[charUsername],[charLoginName],[charPassword],[intLevel],[boolLock])映射到Users类(代码同上):

// BeanProcessor 有两个构造方法,可以传入一个HashMap集合
// HashMap 规定了表字段映射到Javabean的哪个属性,即key为字段名称,value为对应的javabean属性
// map.put(表字段名称, Javabean属性名称)
Map<String, String> map = new HashMap<String, String>();
map.put("yhmid", "id");
map.put("charUsername", "userName");
map.put("charLoginName", "loginName");
map.put("charPassword", "userPassword");
map.put("intLevel", "userLevel");
map.put("boolLock", "userLock");

// 用构建好的HashMap建立一个BeanProcessor对象
BeanProcessor bean = new BeanProcessor(map);

RowProcessor processor = new BasicRowProcessor(bean);

Users rs = runner.query(sql, new BeanHandler<Users>(Users.class, processor));

return rs;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值