一、连接池介绍
1) 什么是连接池
实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池.
2) 连接池的好处
用池来管理Connection,这样可以重复使用Connection。 当使用完Connection后,调用Connectio的
close()方法也不会真的关闭Connection,而是把Connection“归还”给池。
3)如何使用数据库连接池
Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。
这样应用程序可以方便的切换不同厂商的连接池!
常见的连接池有 DBCP连接池, C3P0连接池, Druid连接池
二、DBCP连接池的使用和测试
DBCP也是一个开源的连接池,是Apache成员之一,在企业开发中也比较常见,tomcat内置的连接池。
(1)数据准备
#创建数据库CREATE DATABASE db5 CHARACTER SET utf8;#使用数据库USE db5;#创建员工表CREATE TABLE employee(eid INT PRIMARY KEY AUTO_INCREMENT ,ename VARCHAR (20), -- 员工姓名age INT , -- 员工年龄sex VARCHAR (6), -- 员工性别salary DOUBLE , -- 薪水empdate DATE -- 入职日期);#插入数据INSERT INTO employee (eid, ename, age, sex, salary, empdate) VALUES(NULL,'李清 照',22,'女',4000,'2018-11-12');INSERT INTO employee (eid, ename, age, sex, salary, empdate) VALUES(NULL,'林黛 玉',20,'女',5000,'2019-03-14');INSERT INTO employee (eid, ename, age, sex, salary, empdate) VALUES(NULL,'杜 甫',40,'男',6000,'2020-01-01');INSERT INTO employee (eid, ename, age, sex, salary, empdate) VALUES(NULL,'李白',25,'男',3000,'2017-10-01');
(2)编码实现
import org.apache.commons.dbcp.BasicDataSource;
import org.omg.CORBA.DATA_CONVERSION;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBCPUtils {
//1,定义常量,保存数据库连接的相关信息
public static final String DRIVENAME="com.mysql.jdbc.Driver";
public static final String URL="jdbc:mysql://localhost:3306/db5?characterEncoding=utf-8";
public static final String USERNAME="root";
public static final String PASSWORD="root";
//2,创建连接池对象
public static final BasicDataSource datasource=new BasicDataSource();
static {
//3,创建连接池对象并加载
datasource.setDriverClassName(DRIVENAME);
datasource.setUrl(URL);
datasource.setUsername(USERNAME);
datasource.setPassword(PASSWORD);
}
//3,创建连接的成员方法
public static Connection getConnection() throws SQLException {
//4,从连接池中获取连接
Connection conn= datasource.getConnection();
return conn;
}
//5,创建释放资源的方法
public static void close(Connection conn, Statement stt){
if (conn!=null&&stt!=null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
stt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//重载
public static void close(Connection conn, Statement stt, ResultSet rs){
if (conn!=null&&stt!=null&&rs!=null) {
try {
conn.close();
stt.close();
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
(3)编码测试
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBCPTest {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//使用连接池连接数据库
conn= DBCPUtils.getConnection();
//创建sql语句执行平台
String sql="select ename from employee";
ps=conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()){
String ename=rs.getString("ename");
System.out.println("员工姓名为 "+ename);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DBCPUtils.close(conn,ps,rs);
}
}
}
(4)区别使用驱动连接数据库
驱动连接:
package JDBCTest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class InsertTest {
public static void main(String[] args) throws Exception {
//1,注册驱动,加载驱动程序 ,通过Class的静态方法,注册mysql驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接Connection对象
String url="jdbc:mysql://localhost:3306/db_neu?characterEncoding=utf-8";
Connection con = DriverManager.getConnection(url, "root", "root");
//打印连接对象,测试由谁提供 com.mysql.jdbc.JDBC4Connection@4b9af9a9
System.out.println(con);
//3,获取语句执行平台对象 Statement
Statement stt = con.createStatement();
//3.1通过executeUpdate()方法,创建一张表
String sql="INSERT INTO jdbc_user(id,username,PASSWORD,birthday) VALUES (6,'test4','456','199-02-03')";
int rows= stt.executeUpdate(sql);
if (rows>0){
System.out.println("插入成功!");
}
//关闭流 先开后关
stt.close();
con.close();
}
}
Connection con = DriverManager.getConnection(url, “root”, “root”);
是使用驱动包的类进行连接。
而使用连接池进行连接,是通过类BasicDataSource进行连接,是从数据库池里获取连接的。
(5)常见的配置项
三、C3P0连接池的使用和测试
C3P0是一个开源的JDBC连接池,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、 Spring等。
(1)连接准备
(2)编码
package C3P0;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class C3P0Utils {
//创建对象连接数据库
//ComboPooledDataSource dataSource=new ComboPooledDataSource();
public static final ComboPooledDataSource datasource2=new ComboPooledDataSource("mysql");
//创建实现连接的成员方法
public static Connection getConnection() throws SQLException {
return datasource2.getConnection();
}
//归还资源到数据库连接池中
//5,创建释放资源的方法
public static void close(Connection conn, Statement stt){
if (conn!=null&&stt!=null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
stt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//重载
public static void close(Connection conn, Statement stt, ResultSet rs){
if (conn!=null&&stt!=null&&rs!=null) {
try {
conn.close();
stt.close();
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
package C3P0;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class C3P0Test {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
//创建连接
try {
conn = C3P0Utils.getConnection();
String sql="select * from employee where ename = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,"李白");
rs = ps.executeQuery();
while(rs.next()){
int eid=rs.getInt("eid");
String ename=rs.getString("ename");
int age=rs.getInt("age");
String sex=rs.getString("sex");
System.out.println("信息:"+ename+" "+eid+" "+age+" "+sex);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
C3P0Utils.close(conn,ps,rs);
}
}
}
四、Druid连接池的使用和测试
Druid(德鲁伊)是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。
(1)连接准备
(2)编码实现
package Druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DruidUtils {
//1,定义一个常量
public static DataSource dataSource;
static {
try {
//2,创建属性集对象,加载配置文件
Properties properties=new Properties();
//3,加载配置文件信息,通过反射使用类加载器获取文件中的信息
InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
//4,加载文件到Properties属性集中
properties.load(inputStream);
//5,通过工厂类获取连接池对象
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//6创建建立连接的方法
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
return null;
}
}
//7,创建释放资源的方法
public static void close(Connection conn, Statement stt){
if (conn!=null&&stt!=null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
stt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//重载
public static void close(Connection conn, Statement stt, ResultSet rs){
if (conn!=null&&stt!=null&&rs!=null) {
try {
conn.close();
stt.close();
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
(3)测试
package Druid;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DruidTest {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//获取连接
conn=DruidUtils.getConnection();
String sql="select ename from employee where salary between 3000 and 5000";
//创建执行sql语句的平台
ps=conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()){
String ename=rs.getString("ename");
System.out.println(ename);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DruidUtils.close(conn,ps,rs);
}
}
}
输出结果
五、DBUtils工具类
(1)简介
使用JDBC我们发现冗余的代码太多了,为了简化开发 我们选择使用 DbUtils
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
(2)使用方式
DBUtils就是JDBC的简化开发工具包。需要项目导入commons-dbutils-1.6.jar。
(3)Dbutils核心功能介绍
QueryRunner 中提供对sql语句操作的API.
2. ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
3. DbUtils类,他就是一个工具类,定义了关闭资源与事务处理相关方法.六、案例相关知识
(1)表和类之间的关系
整个表可以看做是一个类
表中的一行记录,对应一个类的实例(对象)
表中的一列,对应类中的一个成员属性
(2)JavaBean组件
1) JavaBean 就是一个类, 开发中通常用于封装数据,有一下特点
1. 需要实现 序列化接口, Serializable (暂时可以省略)
2. 提供私有字段: private 类型 变量名;
3. 提供 getter 和 setter
4. 提供 空参构造
2)创建Employee类和数据库的employee表对应- 创建一个 entity包,专门用来存放 JavaBean类
```java
package entity;
import javax.xml.crypto.Data; import java.io.Serializable;
public class Employee implements Serializable { private static final long serialVersionUID = 8241123515628108345L; private int eid; private String ename; private int age; private String sex; private double salary; private Data empdate;
public Employee() {
}
public Employee(int eid, String ename, int age, String sex, double salary, Data empdate) {
this.eid = eid;
this.ename = ename;
this.age = age;
this.sex = sex;
this.salary = salary;
this.empdate = empdate;
}
public int getEid() {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Data getEmpdate() {
return empdate;
}
public void setEmpdate(Data empdate) {
this.empdate = empdate;
}
@Override
public String toString() {
return "Employee{" +
"eid=" + eid +
", ename='" + ename + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", salary=" + salary +
", empdate=" + empdate +
'}';
}
}
<a name="s3Shs"></a>
# 七、使用DBUtils完成CRUD操作
<a name="H5Xqq"></a>
## (1)QueryRunner核心类
构造方法 :
1. QueryRunner()
1. QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection 常用方法
1. update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作
1. query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作
<a name="jcSMv"></a>
## (2)QueryRunner的创建
手动模式、自动模式,自动模式要传入数据库连接池的连接源(datasource)
```java
//手动模式
QueryRunner qr=new QueryRunner();
//自动模式
QueryRunner queryRunner=new QueryRunner(DruidUtils.getDataSource());
public static DataSource getDataSource(){
return dataSource;
}
(3)使用QueryRunner实现插入操作
package TestDBUtils;
import Druid.DruidUtils;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.SQLException;
public class DBUtilsTestDemo02 {
@Test
public void insert() throws SQLException {
//1,创建QueryRunner对象
QueryRunner qr=new QueryRunner();
//2,编写占位符方式 sql语句
String sql="insert into employee (eid,ename,age,sex,salary,empdate) values (?,?,?,?,?,?)";
//3,设置占位符的参数
Object [] params={null,"林一",18,"男",10000,"1999-02-01"};
//4,建立连接
Connection conn= DruidUtils.getConnection();
int update = qr.update(conn, sql, params);
//5,释放资源
DbUtils.close(conn);
}
}
(4)使用QueryRunner实现修改和删除
@Test
public void update() throws SQLException {
//1,创建QueryRunner对象 自动模式
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
//2,写sql语句
String sql="update employee set salary=? where ename=?";
Object [] params={15000,"林一"};
//执行sql语句
qr.update(sql,params);
}
@Test
public void delete() throws SQLException {
//1,创建QueryRunner对象
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
//2,写sql语句
String sql="delete from employee where eid=?";
//3,执行sql语句
qr.update(sql,1);
}
(5)使用QueryRunner实现查询操作
package TestDBUtils;
import Druid.DruidUtils;
import entity.Employee;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.sql.Array;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DBUtilsTestDemo03 {
/**
* 查询id为5的员工信息
* @throws SQLException
*/
@Test
public void query() throws SQLException {
//创建QueryRunner对象
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
//创建sql语句 查询id为5的数据信息
String sql="select * from employee where eid=?";
//执行sql语句并返回结果集 ArrayHandler()
Object[] query = qr.query(sql, new ArrayHandler(), 5);
System.out.println(Arrays.toString(query));
}
/**
* 查询所有员工的信息
* @throws SQLException
*/
@Test
public void queryList() throws SQLException {
//创建QueryRunner类
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
//创建sql语句并返回结果集
String sql="select * from employee";
//执行sql语句并放在List中 ArrayListHandler
List<Object[]> query = qr.query(sql, new ArrayListHandler());
//遍历集合获取数据
for (Object[] list2:query) {
System.out.println(Arrays.toString(list2));
}
}
/**
* 查询id为3的员工信息,并把数据封装到javaBean中
* @throws SQLException
*/
@Test
public void queryByIdForJavaBean() throws SQLException {
//创建QueryRunner对象
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
//创建sql语句
String sql="select * from employee where eid=?";
//执行语句,封装到javaBean中
Employee query = qr.query(sql, new BeanHandler<Employee>(Employee.class), 3);
System.out.println(query);
}
/** 查询薪资大于 3000 的所员工信息,
* 封装到JavaBean中再封装到List集合中
* * BeanListHandler 将结果集的每一条和数据封装到 JavaBean中 再将JavaBean 放到list集合中 * */
@Test
public void queryBySalaryForListJavaBean() throws SQLException {
//创建QueryRunner对象
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
String sql="select * from employee where salary>?";
List<Employee> query = qr.query(sql, new BeanListHandler<Employee>(Employee.class), 3000);
for (Employee list3:query){
System.out.println(list3);
}
}
/** 查询姓名是 张百万的员工信息,将结果封装到Map集合中 *
* MapHandler 将结果集的第一条记录封装到
* Map<String,Object>中 * key对应的是 列名 value对应的是 列的值 * */
@Test
public void queryByEnameFroMap() throws SQLException {
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
String sql="select * from employee where ename=?";
Map<String, Object> map = qr.query(sql, new MapHandler(), "林一");
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String,Object> entry:entries)
{
System.out.print(entry.getKey()+"="+entry.getValue()+" ");
}
}
/** 查询所有员工的薪资总额 * ScalarHandler 用于封装单个的数据 * */
@Test
public void querySalarySum() throws SQLException {
QueryRunner qr=new QueryRunner(DruidUtils.getDataSource());
String sql="select sum(salary) from employee";
Double query = (Double) qr.query(sql, new ScalarHandler<>());
System.out.println(query);
}
}
八、批处理
(1)什么是批处理
- 批处理(batch) 操作数据库
- 批处理指的是一次操作中执行多条SQL语句,批处理相比于一次一次执行效率会提高很多。
- 当向数据库中添加大量的数据时,需要用到批处理。
- 举例: 送货员的工作:
- 未使用批处理的时候,送货员每次只能运送 一件货物给商家;
- 使用批处理,则是送货员将所有要运送的货物, 都用车带到发放处派给客户。
九、批处理的实现
Statement和PreparedStatement都支持批处理操作,这里我们介绍一下PreparedStatement的批处理方式:1) 要用到的方法
2) mysql 批处理是默认关闭的,所以需要加一个参数才打开mysql 数据库批处理,在url中添加
rewriteBatchedStatements=true
例如: url=jdbc:mysql://127.0.0.1:3306/db5?characterEncoding=UTF-8&rewriteBatchedStatements=true
3) 创建一张表
CREATE TABLE testBatch ( id INT PRIMARY KEY AUTO_INCREMENT, uname VARCHAR(50) )4) 测试向表中插入 1万条数据
```java package TestBath;
import Druid.DruidUtils; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;
public class BathTest { public static void main(String[] args) throws SQLException { //获取连接 Connection con= DruidUtils.getConnection(); //创建执行连接的平台 PreparedStatement ps = con.prepareStatement(“insert into testBatch(uname) values(?)”);
//批量处理一万次插入操作
for (int i =1 ; i <=10000 ; i++) {
ps.setString(1,"小强"+i);
//添加到批处理中
ps.addBatch();
}
long l = System.currentTimeMillis();
//执行批处理操作
ps.executeBatch();
long l1 = System.currentTimeMillis();
System.out.println("插入1000条数据使用了:"+(l1-l)+"毫秒!");
}
}
<a name="QmOUh"></a>
# 十、MySql元数据
<a name="JXFei"></a>
## (1)什么是元数据
除了表之外的数据都是元数据,可以分为三类
1. **查询结果信息:** UPDATE 或 DELETE语句 受影响的记录数。
1. **数据库和数据表的信息: **包含了数据库及数据表的结构信息。
1. **MySQL服务器信息: **包含了数据库服务器的当前状态,版本号等。
<a name="jmtyQ"></a>
## (2)常用命令
-- 1.查看服务器当前状态 <br />show status; 查看服务器的状态信息<br /><br />-- 2.查看MySQl的版本信息 <br />select version(); 获取mysql服务器的版本信息<br /><br />-- 3.查询表中的详细信息 <br />show columns from table_name; 显示表的字段信息等,和desc table_name一样<br /><br />-- 4.显示数据表的详细索引信息 <br />show index from table_name; 显示数据表的详细索引信息,包括PRIMARY KEY(主键)<br />-- 5.列出所有数据库 <br />show databases:列出所有数据库 <br />-- 6.显示当前数据库的所有表 <br />show tables : 显示当前数据库的所有表 <br />-- 7.获取当前的数据库名<br />select database(): 获取当前的数据库名
<a name="t2CiR"></a>
## 十一、通过JDBC获取元数据
通过JDBC 也可以获取到元数据,比如数据库的相关信息,或者当我们使用程序查询一个不熟悉的表时, 我们可以通过获取元素据信息,了解表中有多少个字段,字段的名称 和 字段的类型
<a name="n3CEo"></a>
## (1)常用类介绍
JDBC描述元数据的类<br /><br />获取元数据对象的方法 : getMetaData () <br />connection 连接对象, 调用 getMetaData () 方法,获取的是DatabaseMetaData 数据库元数据对象 <br />PrepareStatement 预处理对象调用 getMetaData () , 获取的是ResultSetMetaData , 结果集元数据对象
<a name="BBJvs"></a>
## (2)DatabaseMetaData的常用方法

<a name="c8adK"></a>
## (3)ResultSetMetaData的常用方法

```java
package com.lagou.testmetadata;
import com.lagou.utils.DruidUtils;
import org.junit.Test;
import java.sql.*;
public class TestMetaData {
//1.获取数据库相关的元数据信息 使用DatabaseMetaData
@Test
public void testDataBaseMetaData() throws SQLException {
//1.获取数据库连接对象 connection
Connection connection = DruidUtils.getConnection();
//2.获取代表数据库的 元数据对象 DatabaseMetaData
DatabaseMetaData metaData = connection.getMetaData();
//3.获取数据库相关的元数据信息
String url = metaData.getURL();
System.out.println("数据库URL: " + url);
String userName = metaData.getUserName();
System.out.println("当前用户: " + userName );
String productName = metaData.getDatabaseProductName();
System.out.println("数据库产品名: " + productName);
String version = metaData.getDatabaseProductVersion();
System.out.println("数据库版本: " + version);
String driverName = metaData.getDriverName();
System.out.println("驱动名称: " + driverName);
//判断当前数据库是否只允许只读
boolean b = metaData.isReadOnly(); //如果是 true 就表示 只读
if(b){
System.out.println("当前数据库只允许读操作!");
}else{
System.out.println("不是只读数据库");
}
connection.close();
}
//获取结果集中的元数据信息
@Test
public void testResultSetMetaData() throws SQLException {
//1.获取连接
Connection con = DruidUtils.getConnection();
//2.获取预处理对象
PreparedStatement ps = con.prepareStatement("select * from employee");
ResultSet resultSet = ps.executeQuery();
//3.获取结果集元素据对象
ResultSetMetaData metaData = ps.getMetaData();
//1.获取当前结果集 共有多少列
int count = metaData.getColumnCount();
System.out.println("当前结果集中共有: " + count + " 列");
//2.获结果集中 列的名称 和 类型
for (int i = 1; i <= count; i++) {
String columnName = metaData.getColumnName(i);
System.out.println("列名: "+ columnName);
String columnTypeName = metaData.getColumnTypeName(i);
System.out.println("类型: " +columnTypeName);
}
//释放资源
DruidUtils.close(con,ps,resultSet);
}
}




(第二个)

