Java JDBC 学习
来源:互联网 发布:洛阳正扬软件 编辑:程序博客网 时间:2024/06/03 13:47
说明
本篇文章重点介绍了使用JDBC API对数据库进行增删改查、执行存储过程中使用到的类和常用方法,不常用的并没有介绍,只能算作是对JDBC这部分知识的一个入门。还介绍了第三方数据库连接池DBCP和C3P0的代码实现。Java JDBC对数据库进行操作可分为四个步骤:
- 加载并注册驱动
- 获取Connection
- 操作数据库
- 关闭连接释放JDBC和数据库资源
这里主要介绍步骤2、3涉及到类和相关方法。在正式开始介绍之前我们需要了解一下SQL语言的分类。
SQL语言的分类
在使用JDBC API执行DQL总是返回一个结果集对象(ResultSet),执行DML总是返回受影响的行数,其它的语言大多数情况下返回0。
Connection的获取
获取Connection可以从实现了DataSource接口的数据库连接池获取,也可以通过DriverManager获取。我们先介绍一下java.slq.Conection接口,然后介绍通过连接池和DriverManager获取数据库连接。
java.sql.Connection接口
作用:代表与特定数据库的连接(会话),在连接上执行SQL并返回结果。
常用方法如下:
Statement createStatement() throws SQLException创建一个Statement对象来将不带参数占位符的SQL发送到数据库执行。
PreparedStatement prepareStatement(String sql) throws SQLException创建一个PreparedStatement对象将带参数占位符的SQL发送到数据库执行。PreperedStatement会预编译SQL,如果一个SQL需要重复执行多次使用PreparedStatement会提高执行效率。
CallableStatement prepareCall(String sql) throws SQLException创建一个CallableStatement对象用于调用数据库的存储过程。
通过java.sql.DriverManager类获取Connection
作用:用于管理一组JDBC驱动程序。我们来看一下DriverManager的经典应用:
//加载mysql驱动类,并调用DriverManager.registerDriver()向DriverManager注册驱动实例
mysql url 事例:"jdbc:mysql://localhost:3306/jiemian_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true";
oracle url 事例:jdbc:oracle:thin:@192.168.9.87:1521:jrdb
代码:
//加载mysql驱动类,并调用DriverManager.registerDriver()向DriverManager注册驱动实例
Class.forName(DBInfo.DIRVERCLASSNAME);Connection conn = DriverManager.getConnection(DBInfo.URL, DBInfo.USERNAME, DBInfo.PASSWORD);我们可以在通过调用Class.forName("oracle的JDBC驱动")代码,向DriverManager注册oracle驱动实例,这样我们向DriverManger注册了mysql和oracle驱动实例,我们通过调用DriverManager.getConnection()会根据传入的url找到合适的驱动。JDBC规定URL的格式为jdbc:subprotocol:subname。
mysql url 事例:"jdbc:mysql://localhost:3306/jiemian_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true";
oracle url 事例:jdbc:oracle:thin:@192.168.9.87:1521:jrdb
代码:
/** * 通过java.sql.DriverManager获取Connection * @author Administrator * */public class ConnectionByDriverManager {public static Connection getConnection() throws Exception{Connection conn = null;try {//加载mysql驱动类,之后创建mysql创建实例,并向ManagerDrivers注册该实例 Class.forName(DBInfo.DIRVERCLASSNAME);conn = DriverManager.getConnection(DBInfo.URL, DBInfo.USERNAME, DBInfo.PASSWORD);System.out.println(conn!=null);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();throw e;}return conn;}public static void main(String [] args){try {Connection conn = ConnectionByDriverManager.getConnection();conn.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
通过C3P0连接池获取Connection
spring框架使用的就是C3P0实现的数据库连接池。
package com.zhangxy.jdbcAPITest;import java.sql.Connection;import java.sql.SQLException;import com.mchange.v2.c3p0.ComboPooledDataSource;/** * 第三方数据库驱动C3P0实现的数据库连接池 * Spring的数据库连接池是使用C3P0实现的 * @author Administrator * */public class C3P0Pool {private static ComboPooledDataSource cpds=null;static {//C3P0读取指定目录下的c3p0-config.xml文件来实现连接池的配置//这里是编译后class所有在路径String path = C3P0Pool.class.getResource("").getFile()+"c3p0-config.xml";//System.out.println("path:"+path);//设置c3p0-config.xml文件读取的路径,如果不设置默认读取src目录下的c3p0-config.xml文件System.setProperty("com.mchange.v2.c3p0.cfg.xml",path);//ComboPooledDataSource(String configName),configName代表c3p0-config.xml文件中指定的named-config节点下的连接池初始化参数//如果不指定,将读取defalut-config节点下的连接池初始化参数cpds = new ComboPooledDataSource();}public static Connection getConnection() throws SQLException{return cpds.getConnection();}public static void main(String [] args){SQLException e1 = null;try {Connection conn = C3P0Pool.getConnection();conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke1=e;e.printStackTrace();}System.out.println("连接是否成功:"+(e1==null));}}
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?><c3p0-config> <default-config> <property name="jdbcUrl"> jdbc:mysql://localhost:3306/jiemian_db </property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">123456</property> <property name="checkoutTimeout">3000</property> <property name="idleConnectionTestPeriod">30</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> <named-config name="test_db"><property name="jdbcUrl">jdbc:oracle:thin:@10.110.26.26:1521:crmdb4</property><property name="driverClass">oracle.jdbc.driver.OracleDriver</property><property name="user">dbmarketadm</property><property name="password">qwer5678</property><property name="checkoutTimeout">3000</property><property name="idleConnectionTestPeriod">30</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></named-config></c3p0-config>
c3p0读取c3p0-config参考:http://blog.csdn.net/soyuone/article/details/51554263
通过DBCP连接池获取Connection
package com.zhangxy.jdbcAPITest;import java.io.File;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.SQLException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.apache.commons.dbcp.BasicDataSource;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;/** * 通过DBCP创建连接池 * DBCP并没有带有像C3P0一样可以从XML文件读取初始化连接池的配置,但是这里通过反射自己实现了这个功能 * @author Administrator * */public class DBCPPool {private static final String DBCP_CONFIG_PATH = DBCPPool.class.getResource("").getFile()+"dbcp-config.xml";private static BasicDataSource baseDs=null; static {init();}public static void init(){try {Class<?> clazz = Class.forName("org.apache.commons.dbcp.BasicDataSource");Object inst = clazz.newInstance();List<FieldInfo> list = getConfig();for(Iterator<FieldInfo> it = list.iterator();it.hasNext();){FieldInfo fieldInfo = it.next();String fName = fieldInfo.getName();String fValue = fieldInfo.getValue();String methodName = "set"+fName.substring(0,1).toUpperCase()+fName.substring(1, fName.length());Field properties = clazz.getDeclaredField(fName);Method method = clazz.getDeclaredMethod(methodName, properties.getType());method.invoke(inst, FieldInfo.getTrueTypeValue(fValue,properties.getType()));}baseDs = (BasicDataSource) inst;} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchFieldException e) {// TODO Auto-generated catch blocke.printStackTrace();} }private static List<FieldInfo> getConfig(){List<FieldInfo> list = new ArrayList<FieldInfo>();File file = new File(DBCP_CONFIG_PATH);SAXReader reader = new SAXReader();try {Document doc = reader.read(file);Element rootEl = doc.getRootElement();for(Iterator<Element> it = rootEl.element("default-config").elementIterator("property");it.hasNext();){Element propertyEl = it.next();FieldInfo fieldInfo = new FieldInfo();fieldInfo.setName(propertyEl.attributeValue("name"));fieldInfo.setType(propertyEl.attributeValue("type"));fieldInfo.setValue(propertyEl.getTextTrim());//System.out.println(fieldInfo.toString());list.add(fieldInfo);}} catch (DocumentException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}public static Connection getConnection() throws SQLException{return baseDs.getConnection();}public static void main(String [] args){//Object obj = 12;//System.out.print((obj instanceof String));try {Connection conn = DBCPPool.getConnection();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}class FieldInfo{private String name;private String value;private String type;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}public String getType() {return type;}public void setType(String type) {this.type = type;}@Overridepublic String toString() {return "name:"+getName()+" type:"+getType()+" value:"+getValue();}public static Object getTrueTypeValue(String value, Class<?> type){if(type == int.class||type==Integer.class){return Integer.valueOf(value);}else if(type==long.class||type==Long.class){return Long.valueOf(value);}else if(type==boolean.class||type==Boolean.class){return Boolean.valueOf(value);}return value;}}dbcp-config.xml
<?xml version="1.0" encoding="UTF-8"?><dbcp-config> <default-config> <property type="string" name="url"> jdbc:mysql://localhost:3306/jiemian_db </property> <property name="driverClassName">com.mysql.jdbc.Driver</property> <property name="username">root</property> <property name="password">123456</property> <property name="initialSize">30</property> <property name="maxActive">20</property> <property name="maxIdle">10</property> <property name="minIdle">5</property> <property name="maxWait">3000</property> </default-config> </dbcp-config>
第三方连接池都实现了javax.sql.DataSource接口
作用:用于获取DataSource代表的物理数据库的连接(Conection对象)。该工厂用于提供到此 DataSource 对象所表示的物理数据源的连接。作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。实现 DataSource 接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API 的命名服务中注册。
DataSource 接口由驱动程序供应商实现。共有三种类型的实现:
- 基本实现 - 生成标准的 Connection 对象
- 连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。
- 分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。
通过 DataSource 对象访问的驱动程序本身不会向 DriverManager 注册。通过查找操作获取 DataSource 对象,然后使用该对象创建 Connection 对象。使用基本的实现,通过 DataSource 对象获取的连接与通过 DriverManager 设施获取的连接相同。
Connection getConnection() throws SQLException尝试建立与此 DataSource 对象所表示的数据源的连接。
Connection getConnection(String username, String password)throws SQLException尝试建立与此 DataSource 对象所表示的数据源的连接。
对数据库操作(增删改查)
对数据库进行操作有这么几个常用的接口和类:java.sql.Statement接口、java.sql.PreparedStatement接口(派生自Statemment接口)、java.sql.ResultSet接口,下面分别介绍。
java.sql.Statement接口
作用:用于执行静态SQL语句并返回生成结果集对象或者是受影响的行数。
方法:
方法:
1,int executeUpdate(String sql) throws SQLException用于执行DML和DDL语言,对于DML语句返回受影响的行数,DDL语句返回0.
2,ResultSet executeQuery(String sql) throws SQLException用于执行DQL语句,返回一个结果集对象。即使没有查询到结果也不会返回一个null,而是返回一个empty的ResultSet对象。
3,boolean execute() throws SQLException执行指定的SQL语句,该语句可以是任何类型。返回true表示执行SQL是一个结果集,可以通过getResultSet()获取。false表示执行SQL是一个受影响的计数(通常执行的是DML语句)或无返回结果(通常执行的是DDL语句),可以通过getUpdateCount()获取。
4,boolean getMoreResults() throws SQLException移动到当前Statement对象的下一个结果集。返回true表示表示当前位置是一个ResultSet对象,可以通过getResultSet()获取 。返回false表示当期是一个计数或没有更多结果,可以通过getUpdateCount()获取。如下表达式为true表示么有更多结果集:(statement.getMoreResultSets()==false && statement.getUpdateCount()==-1)
5,ResultSet getResultSet() throws SQLException以ResultSet对象方式获取当前结果。
6,int getUpdateCount() throws SQLException以受影响的行数方式获取当前结果。如果当前结果集为ResultSet形式或没有更多结果返回-1.
java.sql.PreparedStatement接口,派生自Statemment接口
作用:表示执行预编译的SQL语句返回生成结果集对象或者是受y影响的行数。
方法:
方法:
1,void setString(int parameterIndex,String x) throws SQLExceptionPreparedStatement接口有很多setXXXXX(index,x)方法,作用是给参数占位符设置java中类型的值。这里已setString()方法作为说明,index为参数占位符在SQL语句中的位置,从1开始,x代表要设置的值。
java.sql.ResultSet接口
作用:表示结果集,通常由执行select语句生产。 当我们查询得到一个ResultSet对象,这个对象不是在客户端的内存中存储所有查询到的数据,而是和数据库查询的表有个连接,调用next()遍历ResultSet是从数据库实时获取需要的列值。
1,boolean first() throws SQLException将光标移动到ResutSet对象的第一行。如果光标有效返回true,否则返回false
2,boolean next() throws SQLException将光标移动到下一行,如果存在下一行返回true,否则返回false。while(resultSet.next())可遍历ResultSet对象。一开始光标是在结果集第一行之前的,首次调用next()会将光标移动到第一行。当next()返回false光标在最后一行之后。
对数据库进行增删改查操作综合事例
package com.zhangxy.jdbcAPITest;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class OPStudent {public static void closeAll(Connection conn, Statement state, ResultSet rs){try {if(conn!=null&&!conn.isClosed()){conn.close();}if(state!=null&&!state.isClosed()){state.close();}if(rs!=null&&!rs.isClosed()){rs.close();}} catch (SQLException e) {e.printStackTrace();}}/** * 创建Student表 */public static void createStudentTable(Connection conn){Statement state = null;try {String dropTabSql = "drop table if exists student",createTabSql = "create table student(NO char(20),name varchar(20),primary key(NO))";state = conn.createStatement();//执行两条DDL语句,一下两行码执行时,没有抛出SQLException则证明执行成功state.executeUpdate(dropTabSql);state.executeUpdate(createTabSql);System.out.println("createStudentTable:成功。");} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{closeAll(conn,state,null);}}/** * 向Student表插入数据 * @param conn */public static void insertStudent(Connection conn){PreparedStatement pState = null;int c = 0;try {pState = conn.prepareStatement("insert into student(no,name) values(?,?)");pState.setString(1, "120000");pState.setString(2, "张三");c = pState.executeUpdate();System.out.println("insert into 受影响行数:"+c);pState.clearParameters();pState.setString(1, "130000");pState.setString(2, "李四");c = pState.executeUpdate();System.out.println("insert into 受影响行数:"+c);//如执行SQL条数很多建议使用批处理} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{closeAll(conn,pState,null);}}/** * 查询Student表数据 * @param conn */public static void queryStudent(Connection conn){Statement state = null;try {boolean isEmptyRs = true;state = conn.createStatement();ResultSet rs = state.executeQuery("select * from student");while (rs.next()) {isEmptyRs = false;String no = rs.getString("no");String name = rs.getString("name");System.out.println("no:"+no+" name:"+name);}//如果只想判断ResultSet是否是empty,不想遍历,可以使用一下代码//isEmptyRs=!rs.next();//光标移动到结果集的第一行,成功返回true,否则false//rs.previous();//光标移动到结果集第一行之前的位置System.out.println("查询没有结果:"+isEmptyRs);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{closeAll(conn,state,null);}}/** * 根据no更新Student表(使用参数占位符) * @param conn * @param no * @return */public static int updStudentByNo(Connection conn, String no, String name){int count=0;String sql = "update student t set t.name=? where t.no=?";try {PreparedStatement pState = conn.prepareStatement(sql);pState.setString(1, name);pState.setString(2, no);count = pState.executeUpdate();System.out.println(String.format("update student by no:[%s] name:[%s] 受营销的函数[%d]",no,name,count));} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return count;}public static void main(String [] args){try {createStudentTable( DBCPPool.getConnection() );insertStudent( DBCPPool.getConnection() );queryStudent( DBCPPool.getConnection() );updStudentByNo( DBCPPool.getConnection(), "120000", "abcefg");queryStudent( DBCPPool.getConnection() );} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
JDBC API执行数据库的存储过程
JDBC API执行数据库存储过程主要涉及到java.sql.CallableStatement接口。
java.sql.CallableStatement接口
作用:用于调用存储过程。
调用存储过程的参数可以使用参数占位符.给存储过程的in参数传入值时,使用CallableStatement对象的set方法(例如pState.setString(1,"abc"))。给存储过程的out参数传入值时,使用CallabelStatement对象的registerOutParameter()方法向CallableStatement对象注册out参数,执行完存储过程之后,调用get方法获取返回的out参数。
JDBC API对调用的存储过程进行了转移,转义后对所有关系行数据库都能使用统一的方式调用存储过程,兼容所有数据库。义语法有一个包含结果参数的形式和一个不包含结果参数的形式。
包含结果参数的:{?= call <procedure-name>[(<arg1>,<arg2>, ...)]},我在开发中使用的Mysql数据库,Mysql数据库的存储过程应该不能返回值(return 值),返回的值都是通过out参数带出,或者是使用select语句返回结果集。不知道其它数据库能不能返回一个值。
不包含结果参数的:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
调用存储过程的参数可以使用参数占位符.给存储过程的in参数传入值时,使用CallableStatement对象的set方法(例如pState.setString(1,"abc"))。给存储过程的out参数传入值时,使用CallabelStatement对象的registerOutParameter()方法向CallableStatement对象注册out参数,执行完存储过程之后,调用get方法获取返回的out参数。
JDBC API对调用的存储过程进行了转移,转义后对所有关系行数据库都能使用统一的方式调用存储过程,兼容所有数据库。义语法有一个包含结果参数的形式和一个不包含结果参数的形式。
包含结果参数的:{?= call <procedure-name>[(<arg1>,<arg2>, ...)]},我在开发中使用的Mysql数据库,Mysql数据库的存储过程应该不能返回值(return 值),返回的值都是通过out参数带出,或者是使用select语句返回结果集。不知道其它数据库能不能返回一个值。
不包含结果参数的:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
执行数据库存储过程代码事例
package com.zhangxy.jdbcAPITest;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;/** * 利用CallableStatement调用数据库存储过程 * @author Administrator * */public class CallableStatementTest {/** * 调用带输入参数和输出参数的存储过程DROP PROCEDURE IF EXISTS `getsum`;DELIMITER ;;CREATE DEFINER = `root`@`localhost` PROCEDURE `getsum`(IN s1 int, IN s2 int, OUT r int)BEGINset r = s1+s2;END;;DELIMITER */public static void callOne(){Connection conn = null;try {conn = DBCPPool.getConnection();String sql="{call getsum(?,?,?)}"; CallableStatement cState = conn.prepareCall(sql); cState.setInt(1, 100); cState.setInt(2, 200); cState.registerOutParameter(3, java.sql.Types.INTEGER); cState.executeUpdate(); int result = cState.getInt(3); System.out.println("调用 getsum 存储过程结果为:"+result);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(conn!=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}/** * 调用返回结果集的存储过程 * DROP PROCEDURE IF EXISTS `getstudent`;DELIMITER ;;CREATE DEFINER = `root`@`localhost` PROCEDURE `getstudent`(IN no int)BEGINselect * from student t where t.no=no;END;;DELIMITER ; */public static void call2(){Connection conn = null;try {conn = C3P0Pool.getConnection();CallableStatement pState = conn.prepareCall("{call getstudent(?)}");pState.setInt(1, 120000);ResultSet rs = pState.executeQuery();System.out.println("调用 getstudent 存储过程的结果为:");while(rs.next()){System.out.println("name:"+rs.getString("name"));}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(conn!=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}/** * 调用数据库函数 hello DROP FUNCTION IF EXISTS `hello`;CREATE DEFINER = `root`@`localhost` FUNCTION `hello`(s CHAR(20))RETURNS char(50)RETURN CONCAT('Hello, ',s,'!'); */public static void callFunction(){Connection conn = null;try {conn = C3P0Pool.getConnection();PreparedStatement pState = conn.prepareStatement("select hello(?) as v");pState.setString(1, "abc");ResultSet rs = pState.executeQuery();while(rs.next()){System.out.println("调用数据库函数 hello 返回结果:"+rs.getString("v"));}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String [] args){callOne();call2();callFunction();}}
java.sql.ResultSetMetaData,(20170807补充)
ResultSetMetaData类可用于获取ResultSet对象中列的类型和属性信息对象。我们可以通过rs.getMetaData()对象来获取ResultSetMetaData对象。其实能去了解这个类是因为对一个问题的思考:我们使用java的ORM框架时,都需要创建一个对应的JavaBean来映射表的结构,发现myBatis从数据库中返回的可以不是一个JavaBean,而是一个Map或JSONObject,这这个两个对象的Key值都是和表字段名称一样的。感觉JDBC应该提供了响应的API来读取ResultSet对象列类型和属性的类,结果顺藤摸瓜就找到了ResultSetDetaData类。下面介绍一下此类常用的API。
- 获取指定位置的列所在表的名称。column参数为列所在的位置。注意这个位置是从1开始,而不是0。ResultSetMateData对象的所有方法参数列的位置都是从1开始。
String getTableName(int column) throws SQLException
- 返回ResultSet中的列数。
int getColumnCount() throws SQLException
- 按照指定的位置获取列的名称。
String getColumnName(int column) throws SQLException
- 按照指定的位置返回列在数据库中的类型。
String getColumnTypeName(int column) throws SQLException
- 按照指定的位置返回列对应的java.sql.Types类中的类型。
int getColumnType(int column) throws SQLException
- 按照指定的位置返回列对应java编程语言中类的完全限定名称。
String getColumnClassName(int column) throws SQLException
- 指定列在表结构上是否可以为null。
int isNullable(int column) throws SQLException
- 按照指定列的位置返回该列的别名,通常由as指定。如果没有指定别名,此方法的返回值将和getColumnName()方法相同。
String getColumnLabel(int column) throws SQLException
下面给出一个综合事例:
public static void testResultSetMateData(Connection conn) {String sql = "select CONVERT(NO,SIGNED) no, NAME from student s where 1=2";//String sql = "select t.act_id from dbmarketadm.mk_actrecord_info t where t.act_id in ('201707285002064064')";Statement smt = null;ResultSet rs = null;java.sql.ResultSetMetaData rsmd = null;try {smt = conn.createStatement();rs = smt.executeQuery(sql);conn.getMetaData();rsmd = rs.getMetaData();String tableName = rsmd.getTableName(2);int columnCount = rsmd.getColumnCount();System.out.println("表名:" + tableName + ",查询结果为:" + columnCount);for (int i = 1; i <= columnCount; i++) {System.out.println("列名称:" + rsmd.getColumnName(i) + ",数据库类型:" + rsmd.getColumnTypeName(i) + ",sql数据库类型:"+ rsmd.getColumnType(i) + ",列别名(as):" + rsmd.getColumnLabel(i) + ",列是否为null:"+ rsmd.isNullable(i) + ",列类型对于的java类型:" + rsmd.getColumnClassName(i));}} catch (SQLException e) {e.printStackTrace();} finally {if (rs != null) {try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (smt != null) {try {smt.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
输出结果:
表名:student,查询结果为:2列名称:no,数据库类型:BIGINT,sql数据库类型:-5,列别名(as):no,列是否为null:0,列类型对于的java类型:java.lang.Long列名称:name,数据库类型:VARCHAR,sql数据库类型:12,列别名(as):NAME,列是否为null:1,列类型对于的java类型:java.lang.String
1 0
- JAVA JDBC 学习 笔记
- JAVA JDBC学习笔记
- Java JDBC学习
- java jdbc 学习
- Java JDBC 学习笔记
- Java JDBC学习笔记
- Java---JDBC学习
- Java学习之JDBC
- Java的JDBC学习
- Java之jdbc学习
- JDBC-----JAVA 学习笔记
- Java JDBC 学习
- java学习【JDBC入门】
- Java学习之jdbc
- Java JDBC学习
- 个人学习-java-jdbc学习
- Java JDBC 操作学习【转帖】
- Java学习大全 之 JDBC
- nyoj 1058 部分和问题(dfs+剪枝)
- 处女作,谈谈JavaScript里面的闭包吧!
- PHPExcel导出excel入门实例教程
- Bootstrap 菜单
- Java程序编译
- Java JDBC 学习
- Intel Media SDK之开发资源汇总(含Windows和Linux)
- PHP中的trait,interface和abstract
- 关于框架的相关问题
- Sticks
- Java开源工具iText生成PDF文件
- linux相关命令应用
- git push 每次都需要输入用户名和密码
- 直播主流的协议