JDBC
简介
- JDBC(Java Data Base Connectivity),Java数据库连接。是一种用于执行SQL语句的Java API。简单来说就是通过Java去操作数据库,向数据库发送SQL语句,执行增删改查等操作。
- Sun公司的Java技术开发人员很早就意识到了Java在数据库应用方面的巨大潜力。从1995年开始,他们就致力于扩展Java标准类库,是之可以应用SQL访问数据库。他们最初希望,通过扩展Java,人们就可以用“纯”Java语言与任何数据库进行通信。但是,他们很快就发现这是一项无法完成的任务:因为市场上存在有很多不同的数据库,而他们使用的协议也各不相同。而每一个数据库公司都希望Sun公司可以使用他们自己的协议。但是显然是不现实的。
- 所有的数据库供应商和工具开发商都认为,如果SUN公司能够为SQL访问提供一套“纯”Java API,同时提供一个驱动管理器,以允许第三方驱动程序可以连接到指定的数据库,那它们会显得非常有用。这样,数据库供应商就可以提供自己的驱动程序,并插入到驱动管理器中。另外还需要一套简单的机会,以使得第三方驱动程序可以向驱动管理器注册。因此,Sun公司制定了两套接口。应用程序开发者使用JDBC API,而数据库供应商和工具开发商使用JDBC驱动API。
- 这种接口组织方式遵循了微软公司非常成功的ODBC模式,ODBC为C语言访问数据库提供了一套编程接口。JDBC和ODBC都基于同一个思想:根据API编写的程序都可以与驱动管理器进行通信,而驱动管理器则通过驱动程序与实际数据库进行通信。
- 这样做的好处就是,我们在使用JDBC的时候只需要导入相应厂商提供的驱动包,然后直接调用JDBC API即可。实际上使用JDBC时,不同的数据库除了SQL语句以及一些配置稍有区别以为,大部分代码都是相同的,也就是说我们使用JDBC操作MySQL和操作Oracle代码上是没有什么区别的。
核心类
java.sql.DriverManager
n 用来管理JDBC驱动和获取Connection对象的类
n static Connection getConnection(String url, String user, String password)
u 建立一个到指定数据库的连接,并返回一个Connection对象
java.sql.Connection
n 表示和指定数据库建立的数据库连接对象。
n Statement createStatement()
u 获取一个Statement对象,用来执行没有占位符的SQL语句
n void close()
u 关闭当前的数据库连接,释放它所创建的JDBC资源
java.sql.Statement
n SQL的执行器,用于执行一个静态的SQL语句并返回它产生的结果
u ResultSet executeQuery(String sql)
l 执行给定的SQL语句,并返回一个用于查询结果的ResultSet对象
u int executeUpdate(String sql)
l 执行给定的SQL语句,用于更新数据库数据,返回发生变化数据的行数
u void close()
l 关闭Statement对象以及它所对应的结果集。
java.sql.ResultSet
n 代表通过查询数据库获取到的结果集。
u boolean next()
l 将结果集的当前行向前移动一行。如果以及到达最后一行的后面,则返回false
u Xxx getXxx(int 列号)
u Xxx getXxx(int 列名)
l Xxx指数据类型,例如int、double、String、Date等
l 用给定的列号或列名返回该列的值,并将值转换为指定类型。
u void close()
l 关闭当前的结果集
DEMO
- 下边我们来开始编写我们的第一个JDBC程序
- 导入数据库厂商提供的驱动jar包,我们这里使用MySQL,所以导入MySQL的驱动
1. 导入驱动jar包
n mysql-connector-java-5.1.7-bin.jar
2. 注册数据库驱动
- 在程序中注册导入的驱动程序,每一个驱动都是java.sql.Driver的实现类,而每个实现类中都会有一个静态代码块,具体如下:
static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } |
n 在驱动程序的静态代码块中,会自动将驱动程序通过DriverManager进行注册,所以我们要做的只是将驱动类加载进JDK中,静态代码块将会自动执行。
//加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); |
3. 获取数据库连接
- 数据库连接也就是我们上边所说的Connection对象,获取数据库连接只需要调用DriverManager的getConnection()方法即可,但是这个方法需要传递三个String类型参数:
n String url
u 数据库URL
l 在连接数据库时,我们必须使用各种与数据库类型相关的参数,例如主机名、端口号和数据库名。
l 语法:jdbc:子协议:厂商内容
l 例如:
n MySQL
u jdbc:mysql://主机地址:端口号/库名
u jdbc:mysql://localhost:3306/test
n Oracle
u jdbc:oracle:thin:@主机地址:端口号:数据库名
u jdbc:oracle:thin:@localhost:1521:atguigu
n SQLServer
u jdbc:microsoft:sqlserver//主机地址:端口号; DatabaseName=库名
u jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid
n String user
u 连接数据库使用的用户的用户名,我们这里MySQL的用户名就是root
n String password
u 连接数据库使用的用户的密码,我们这里同样也是root
//设置url地址 String url = "jdbc:mysql://localhost:3306/test"; //设置用户名 String username = "root"; //设置用户密码 String password = "root"; //获取数据库连接 Connection conn = DriverManager.getConnection(url,username,password); |
4. 获取Statement对象
- 获取Statement对象用来执行SQL语句,通过Connection对象的相关方法即可。
//获取Statement对象 Statement stat = conn.createStatement(); |
5. 执行SQL语句
- SQL语句可以通过Statement对象的executeUpdate()或executeQuery()方法即可
n executeUpdate()用于执行增、删、改相关的方法,它可以返回一个int值,表示执行SQL语句后影响到的行数。
//创建SQL语句 String sql = "INSERT INTO tb_user VALUES(null,'sunwukong')"; //执行SQL语句 int count = stat.executeUpdate(sql); |
n executeQuery()用于执行查询的方法,该方法会返回一个ResultSet对象,对象中封装了查询到的数据。
//创建SQL语句 String sql = "SELECT * FROM tb_user"; //执行SQL语句查询信息 ResultSet rs = stat.executeQuery(sql); |
6. 读取ResultSet中的数据
- 当通过JDBC做查询操作时,会返回一个ResultSet对象,我们通过数据库查询到的数据都封装在该类实例中。
- ResultSet中实际上就是一个二维的表格,结构和我们从数据库中查询到的表格一样,在ResultSet中维护着一个光标,这个光标会指向表格的某一行,当光标指向某一行时,我们就可以读取当前行的数据。
- ResultSet的光标默认是指向表格外的,也就是最初的ResultSet的光标,并没有指向某一行,我们需要调用next()方法使光标下移。next()方法返回一个boolean值,如果返回值为true则代表当前有可读数据,如果为false则表示数据已经全部读完了。
- ResultSet中给我提供了一系列的getXxx()方法用于读取表中的数据,我们使用ResultSet时,和迭代器类似:
//创建一个while循环用于读取ResultSet中的数据 while(rs.next()){ //获取第一列的数据 int id = rs.getInt(1); //获取第二列的数据 String um = rs.getString(2); //输出数据 System.out.println(id+"--"+um); } |
n 上边的代码我们是通过列的序号来获取列的信息的。如getInt(1)获取第一列的数据并返回一个int值,getString(2)获取第二列的信息并返回一个String,注意这里的列是从1开始的,而不是0。
n 同样我们也可以通过列名来获取指定属性,和上边的用法类似,只不过不在传int行的列序号,而是传String型的列名。如:getInt(“id”) 获取int型的id的值,getString(“username”) 获取String型的username的值。注意这里的id和username都是表的列名,也就是表头中的内容,如果没有使用别名则以表中的名称为准,如果使用了别名则以别名为准。
7. 释放资源
- 当使用完ResultSet、Statement或Connection对象时,应立即调用close方法。这些对象都使用了规模较大的数据结构,所以我们不应该等待垃圾回收期来处理它们。
- Statement对象close()方法会自动关闭它已经打开的结果集(ResultSet),而Connection对象的close()方法会自动关闭和它管理的Statement对象。所以当我们关闭Connection对象时,Statement和ResultSet对象也会自动关闭,但是如果关闭时Statement和ResultSet还没有使用完毕的话,那么就会出问题了,所以我们在关闭这些对象时,一定要注意关闭顺序:先关ResultSet、再关Statement、最后关Connection。
//关闭ResultSet rs.close(); //关闭Statement stat.close(); //关闭Connection conn.close(); |
8. 标准代码
//设置四个参数 String username = "root"; String password = "root"; String driverClass = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/test"; //加载驱动 Class.forName(driverClass); //分别声明Connection Statement ResultSet三个变量 Connection conn = null; Statement stat = null; ResultSet rs = null; try { //获取Connection对象 conn = DriverManager.getConnection(url, username, password); //获取Statement对象 stat = conn.createStatement(); //执行sql获取ResultSet对象 rs = stat.executeQuery(""); //读取rs对象中的内容 } catch (SQLException e) { e.printStackTrace(); } finally{ //关闭rs if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //关闭stat if(stat != null){ try { stat.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //关闭conn if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } |
PreparedStatement
1. SQL注入攻击
- SQL注入攻击是黑客对数据库进行攻击的一个常用手段之一。所谓SQL注入指的就是通过向服务器发送一些特殊的参数,从而使原本的SQL语句的语义发生变化,从而骗过程序的一些验证。
- 最典型的SQL攻击就要说我们登录验证的功能,我们在做登录时都需要这样一条SQL语句:SELECT * FROM tb_user WHERE username='参数1' AND PASSWORD='参数2',这条SQL语句实际上就是根据用户名和密码查询一个用户信息,如果用户名和密码正确则可以查询到用户,则认定登录成功。用户名或密码错误,则不能查询到用户,则认定登录失败。
- 这里的参数1和参数2实际上都是需要用户来传递进来的,但是当用户传过来的是一一些恶意参数可能就会突破我们的验证。
- 比如:用户名传一个 a’ OR ‘1’=’1 密码传一个 a’ OR ‘1’=’1 ,这个用户名和密码显然是不正确的,但是如果将这两个参数设置进SQL语句中,我们的SQL语句就会变成这个样子:SELECT * FROM tb_user WHERE username='a' OR '1'='1' AND PASSWORD='a' OR '1'='1'。显然这条SQL语句无论怎么查都可以查的到用户,于是即使用户不知道用户和密码也可以登录系统,这样可能会给我们的用户或者网站带来不可预估的损失。
- 处理SQL注入有多种方式:
2. 防止SQL注入
n 对用户输入进行校验,检查是否包含非法字符
n 分两次检查用户名和密码,先通过SQL查询用户对象,再检查密码是否正确
n 使用PreparedStatement
3. PreparedStatement
- PreparedStatement即预处理SQL语句。
- PreparedStatement已经实现Statement接口,并且和Statement有两方面的不同:
n PreparedStatement中已经包含了编译好的SQL语句,在这条SQL语句中可以设置一个过多个参数,这些参数使用?作为占位符,我们只需要在SQL语句执行之前使用对应的参数替换占位符即可。PreparedStatement中为我们提供了很多的setXxx()方法用来替换占位符。
n 由于PreparedStatement中的SQL语句已经预编译过了,其执行效率要高于Statement。
n PreparedStatement继承了Statement的所有功能,但是在这个基础上还添加了多个setXxx()方法用来设置占位符。同时三个方法execute()、executeUpdate()、executeQuery()都已经添加了不需要参数的版本,而之前需要参数的方法我们不应该在调用。
- 使用:
n 获取PreparedStatement
u Connection.prepareStatement(String sql);
PreparedStatement pstmt = conn.prepareStatement("SELECt * FROM tb_user WHERE username=? AND password=?"); |
u 我们可以通过Connection对象的prepareStatement方法获取一个PreparedStatement对象,调用这个方法我们必须要传一个SQL语句,这个条SQL语句就是我们的预编的SQL语句,我们会发现SQL语句中出现两个?,这两个问号就是我们所说的占位符,这些占位符在SQL语句执行之前必须要被替换成有效的值。
n 替换占位符:
u 在PreparedStatement中提供了很多的setXxx()方法用来替换占位符。所谓的Xxx就是指我们Java中的数据类型,如int、String、long、double等。
u 例如:setString(占位符位置 , 占位符的值)、setInt(占位符位置 , 占位符的值)、setObject(占位符位置 , 占位符的值)。
pstmt.setString(1, username); pstmt.setString(2, password); |
n 执行SQL
u 执行SQL也很简单,上边也说了PreparedStatement提供类三个无参的execute()、executeUpdate()、executeQuery()三个方法,根据要操作的SQL的数据类型不同执行相应的方法即可。
rs = pstmt.executeQuery(); |
- 注意:通常我们在使用JDBC是不会使用Statement而是使用PreparedStatement,所以时刻注意我们以后应该使用的PreparedStatement。
- 所谓大数据就是占用空间比较大的数据,比如一个比较长的文本,一个视频文件,一个MP3音乐文件这些都是我们所说的大数据。
- 大数据我们在SQL中也称为LOB(large object)大对象,一般标准数据库提供两种类型:存储字节型数据的BLOB,存储字符型大数据的CLOB。
- 如下表示SQL标准提供的LOB类型:
大数据
类型 |
长度 |
tinyblob |
28--1B(256B) |
blob |
216-1B(64K) |
mediumblob |
224-1B(16M) |
longblob |
232-1B(4G) |
tinyclob |
28--1B(256B) |
clob |
216-1B(64K) |
mediumclob |
224-1B(16M) |
longclob |
232-1B(4G) |
- 但是MySQL中的类型稍有不同,它并没有提供tinyclob、clob、mediumclob、longclob四种类型,而是使用的相关的text代替:
类型 |
长度 |
tinytext |
28--1B(256B) |
text |
216-1B(64K) |
mediumtext |
224-1B(16M) |
longtext |
232-1B(4G) |
批处理
- 批处理指的是批量的将部分数据同时插入进数据库。想想一些这样一个场景,我们如果有20条SQL语句需要执行,那么在我们执行时,是20条语句一个一个执行的快,还是将20条语句一起执行来的快呢?显然,一起执行要更快一些,那么批处理也就是多条SQL语句一起执行。
- 批处理主要是来对增删改来说的,查询时我们不需要进行批处理操作。
- 我们可以使用Statement或者PreparedStatement来进行批量操作。
- 我们主要介绍PreparedStatement使用批处理的方式,使用PreparedStatement做批处理主要有两个方法:
n addBatch()
u 将一组已经设置好的参数,添加到批处理中
n executeBatch()
u 执行批处理
- 示例:
//获取connection conn = JDBCUtils.getConnection(); //设置sql语句 String sql = "INSERT INTO customer (name,age,gender) VALUES(?,?,?)"; //获取PreparedStatement对象 pstmt = conn.prepareStatement(sql); //使用for循环批量设置参数 for (int i = 0; i < 10000; i++) { pstmt.setString(1, NameUtils.getName()); pstmt.setInt(2, NameUtils.getAge()); pstmt.setString(3, NameUtils.getGender()); //每设置完一组参数,将参数添加到批量操作中 pstmt.addBatch(); } //执行批量操作 pstmt.executeBatch(); |
- 注意MySQL默认是不支持批量处理的,需要在URL地址中加上如下参数:
n rewriteBatchedStatements=true
事务
什么是事务
- 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。
- 举例来说当我们做一个银行转账的业务时,A账户向B账户转账1000元钱,这个就是一个事务。A向B转1000如果我们简单来考虑的话,首先需要从A的账户中减掉1000元,然后在向B的账户加上1000元。也就是我们一个业务需要操作两次数据库,那么这两次操作必须同时成功,或者同时失败,也就是说要不然A账户减了1000元同时B账户增加了1000元,要不就是两个账户没有发生变化,像这种操作我们称为一次事务。
- 原子性(atomicity)
事务的四个特性(ACID)
n 一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
- 一致性(consistency)
n 事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
- 隔离性(isolation)。
n 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性(durability)。
n 持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
在MySQL中操作事务
- MySQL中的事务主要是三个语句:
n START TRANSACTION
u 开启事务,开启事务后我们在MySQL中输出的每个语句将不会自动提交修改。
n COMMIT
u 提交事务,提交刚才对数据库做的修改操作
n ROLLBACK
u 回滚事务,取消刚才对数据库做的所有操作
JDBC中操作事务
- JDBC中事务的操作主要是通过Connection的三个方法来进行的。
n conn.setAutoCommit(false)
u 设置事务不自动提交,开启事务
n conn.commit();
u 提交事务
n conn.rollback();
u 回滚事务
数据库连接池
- 之前我们的学习使用的数据库连接对象(Connection),都是通过DriverManager获取到的,也就是每次获取到的都是一个新的对象。数据库连接对象使用完毕以后我们需要关闭数据库连接,这时Connection对象就没有用,会等待被GC所回收。
- 这样反复创建新的连接,关闭连接,回收连接,再创建新的连接。这样来回的创建连接释放连接对系统的资源的销毁是很大的。
- 所以为了解决这个问题,我们提出了一个数据库连接池的概念。所谓数据库连接池实际上就是一个集合,这个集合中保存的就是我们的Connection对象。当我们需要使用数据库连接时,直接从集合中获取,而不用再创建新的对象,等我们使用完了再将对象放回到集合中,供以后使用,这样实际上就使我们的Connection对象达到了复用的目的。
- 数据库连接池的常见设置:
n 初始连接数量
n 最小空闲连接数
n 每次增加连接数
n 最大空闲连接数
n 最大连接数
n 最大等待时间
- javax.sql.DataSource
n JDBC为我们提供了DataSource接口,所有的数据库连接池都需要实现该接口,有了该接口以后,我们在获取数据库连接就不需要使用DriverManager了。
n Connection getConnection()
u 从数据库连接池中获取一个连接
DBCP
- DBCP是Apache出品的一款数据库连接池。
- 使用DBCP需要导入两个jar包:
n commons-dbcp-1.4.jar
n commons-pool-1.5.5.jar
- DBCP的核心类为:
n BasicDataSource
n BasicDataSourceFactory
- 示例代码:
//创建连接池对象 BasicDataSource dataSource = new BasicDataSource(); //设置连接信息 dataSource.setUrl("jdbc:mysql://localhost:3306/test"); dataSource.setUsername("root"); dataSource.setPassword("root"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); //指定初始化连接的个数 dataSource.setInitialSize(10); //指定最大的连接数,数据连接池的容量 dataSource.setMaxActive(50); //指定连接池中的最小连接数 dataSource.setMinIdle(5); //设置最大等待时间 dataSource.setMaxWait(1000); //获取数据库连接 Connection connection = dataSource.getConnection(); |
- 配置信息
n initialSize
u 初始化连接的个数,默认值为0
n maxActive
u 连接池中的最大连接数,默认值为8,若设置为负数,表示无限制
n maxIdle
u 最大空闲连接数,默认值为8,若设置为负数,表示无限制
n minIdle
u 最小空闲连接数,默认值为0
n maxWait
u 最大等待时间,默认为-1,无限等待
n connectionProperties
u 连接属性,指定url地址后边的参数
n defaultAutoCommit
u 是否自动提交事务,默认为true
C3P0
- C3P0是一款开源的免费的数据库连接池
- 相比于DBCP来说,C3P0更加的稳定
- 使用C3P0需要导入一个jar包:
n c3p0-0.9.1.2.jar
- 核心类:
n ComboPooledDataSource
- 示例代码:
//获取连接池对象 ComboPooledDataSource dataSource = new ComboPooledDataSource(); //设置连接信息 dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); dataSource.setUser("root"); dataSource.setPassword("root"); //设置连接池信息 dataSource.setAcquireIncrement(5); dataSource.setInitialPoolSize(10); dataSource.setMinPoolSize(2); dataSource.setMaxPoolSize(50); //获取数据库连接 Connection connection = dataSource.getConnection(); |
- 上边这种方式是直接在程序中编码的方式,但是在实际开发中很少使用这种硬编码的方式,而是使用配置文件的方式来配置这些信息。
- c3p0使用xml作为配置文件
n 文件的名称必须为c3p0-config.xml
n 文件必须放到项目的类路径下
n 格式:
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">root</property> <!-- 最小的连接数 --> <property name="minPoolSize">5</property> <!-- 最大的连接数 --> <property name="maxPoolSize">30</property> <!-- 初始化的连接数 --> <property name="initialPoolSize">10</property> <!-- 需要时一次性创建的连接数 --> <property name="acquireIncrement">5</property> <!-- 缓存多少个Statement对象 --> <property name="maxStatements">15</property> </default-config> <named-config name="oracle-config"> <property name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:orcl</property> <property name="driverClass">oracle.jdbc.driver.OracleDriver</property> <property name="user">orcl</property> <property name="password">orcl</property> <!-- 最小的连接数 --> <property name="minPoolSize">5</property> <!-- 最大的连接数 --> <property name="maxPoolSize">30</property> <!-- 初始化的连接数 --> <property name="initialPoolSize">10</property> <!-- 需要时一次性创建的连接数 --> <property name="acquireIncrement">5</property> <!-- 缓存多少个Statement对象 --> <property name="maxStatements">15</property> </named-config> <named-config name="mysql-config"> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">root</property> <!-- 最小的连接数 --> <property name="minPoolSize">5</property> <!-- 最大的连接数 --> <property name="maxPoolSize">30</property> <!-- 初始化的连接数 --> <property name="initialPoolSize">10</property> <!-- 需要时一次性创建的连接数 --> <property name="acquireIncrement">5</property> <!-- 缓存多少个Statement对象 --> <property name="maxStatements">15</property> </named-config> </c3p0-config> |
n 在配置文件中可以配置一个default-config或多个named-config。
n 当在项目中创建了配置文件时,在通过ComboPooledDataSource无参的构造器时,他会自动加载default-config中的的配置信息,而不用再在程序中编写。
n 如果调用的是有参的构造器,则可以通过传递named-config的name属性来指定要加载的配置文件。
n 加载默认配置文件:
DataSource dataSource = new ComboPooledDataSource(); Connection connection = dataSource.getConnection(); |
n 加载默认指定配置文件:
DataSource dataSource = new ComboPooledDataSource("mysql-config"); Connection connection = dataSource.getConnection(); |
DbUtils
- Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
- JDBC的操作复杂、且非常容易出错。因此,DbUtils可以让我们从这些复杂繁琐的工作中解放出来,是我们更加的专注于数据库的相关操作。
- DbUtils
核心类
n 数据库操作基本类,提供了数据库连接相关操作的静态方法。
u public static void close(Connection conn)
l 关闭数据库连接
u public static void close(ResultSet rs)
l 关闭结果集
u public static void close(Statement stmt)
l 关闭Statement
u public static void commitAndClose(Connection conn)
l 提交是否并关闭连接
- QueryRunner
n 用于执行数据库操作的类,主要使用的类
u batch()
l 批量操作数据库
u insert()
l 向数据库中插入一条数据,可以返回插入数据的自增ID
u insertBatch()
l 向数据库中批量插入多条数据
u query()
l 从数据库中查询数据
u update()
l 修改数据库中的内容,返回修改的条数
n 该类中给我们提供了大量的重载方法来调用,我们可以根据不同的需要调用不同的方法。
- ResultSetHandler
n ResultSetHandler是一个接口,我们操作数据库时,最麻烦的问题就是将从数据库中查询到的数据封装为对象,这是一个非常繁琐,非常容易出错的操作。这个接口就是帮我们解决这个问题。而更好的是他已经给我们提供了足够多的实现类,而不用我们再去自己实现。
n ArrayHandler
u 将查询到的数据封装为一个Object数组
n ArrayListHandler
u 将查询到的数据封装为一个List<Object[]>
n BeanHandler
u 返回一个对象
n BeanListHandler
u 返回对象的集合(List)
n BeanMapHandler
u 返回一个map,map的key为第一个数据,值为一行数据
n ColumnListHandler
u 返回第一列的数据
n KeyedHandler
u 返回一个map,map的key为第一个数据,值为一行数据
n MapHandler
u 将查询到的数据封装为一个Map<String,Object>
n MapListHandler
u 将查询到数据封装为一个List< Map<String,Object>>
n ScalarHandler
u 返回一个单独的结果