1. 测试preparedStatement
  1. public void testPreparedStatement(){
  2. Connection connection=null;
  3. PreparedStatement preparedStatement=null;
  4. try{
  5. connection =JDBCTools.getConnection();
  6. String sql="insert into customers(name,email,birth) "+
  7. "values(?,?,?)";
  8. preparedStatement=connection.prepareStatement(sql);
  9. preparedStatement.setString(1, "ATGUIGU");
  10. preparedStatement.setString(2, "simleint@163.com");
  11. preparedStatement.setDate(3, new Date(new java.util.Date().getTime()));
  12. preparedStatement.executeUpdate();
  13. }catch(Exception e){
  14. e.printStackTrace();
  15. }finally{
  16. JDBCTools.release(null, preparedStatement, connection);
  17. }
  18. }
  1. 测试结果集元数据: 利用SQL进行查询,得到结果集。
  1. 利用反射创建实体对象,获取结果集的列的别名。
  1. 在获取结果集的每一列的值,结合3得到一个Map,键的别名,值:列的值。</span>
  1. 再利用反射为2的对应的属性赋值:属性为Map的键,值为Map的值。</span>
 
  1. public void testResultSetMetaData(){
  2. Customer customer=null;
  3. Connection conn=null;
  4. PreparedStatement preparedStatement=null;
  5. ResultSet rs=null;
  6. try{
  7. String sql="select ID id,NAME name,EMAIL email,BIRTH birth from customers";
  8. conn=JDBCTools.getConnection();
  9. preparedStatement=conn.prepareStatement(sql);
  10. 1得到rs
  11. rs=preparedStatement.executeQuery();
  12. Map<String,Object>values=
  13. new HashMap<String,Object>();
  14. //2得到结果集ResultSetMetaData对象。
  15. ResultSetMetaData rsmd=rs.getMetaData();
  16. while(rs.next()){
  17. for(int i=0;i<rsmd.getColumnCount();i++){
  18. String columnLabel=rsmd.getColumnLabel(i+1);
  19. Object columnValue=rs.getObject(columnLabel);
  20. values.put(columnLabel,columnValue);
  21. }
  22. }
  23. System.out.println(values);
  24. Class clazz=Customer.class;
  25. Object object=clazz.newInstance();
  26. for(Map.Entry<String, Object>entry:values.entrySet()){
  27. String fieldName=entry.getKey();
  28. Object fieldValue=entry.getValue();
  29. System.out.println(fieldName+" :"+fieldValue);
  30. ReflectionUtils.setFieldValue(object,fieldName,fieldValue);
  31. }
  32. }catch(Exception e){
  33. e.printStackTrace();
  34. }finally{
  35. JDBCTools.release(rs,preparedStatement,conn);
  36. }
  37. }

抽取出泛型方法:

  1. public void testGet(){
  2. String sql="select ID id,NAME name,EMAIL email,BIRTH birth "+"From customers";
  3. Customer customer=get(Customer.class,sql);
  4. System.out.println(customer);
  5. }
  6. public <T> T get(Class<T> clazz,String sql,Object...args){
  7. T entity=null;
  8. Connection conn=null;
  9. PreparedStatement preparedStatement=null;
  10. ResultSet rs=null;
  11. try{
  12. conn=JDBCTools.getConnection();
  13. preparedStatement=conn.prepareStatement(sql);
  14. for(int i=0;i<args.length;i++)
  15. {
  16. preparedStatement.setObject(i+1, args[i]);
  17. }
  18. //1得到rs
  19. rs=preparedStatement.executeQuery();
  20. //2得到结果集ResultSetMetaData对象。
  21. ResultSetMetaData rsmd=rs.getMetaData();
  22. //3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值
  23. Map<String,Object>values=
  24. new HashMap<String,Object>();
  25. //处理结果集。
  26. while(rs.next()){
  27. for(int i=0;i<rsmd.getColumnCount();i++){
  28. String columnLabel=rsmd.getColumnLabel(i+1);
  29. Object columnValue=rs.getObject(columnLabel);
  30. values.put(columnLabel,columnValue);
  31. }
  32. }
  33. //5若Map不为空利用反射创建clazz对应的对象。
  34. if(values.size()>0){
  35. entity=clazz.newInstance();
  36. for(Map.Entry<String, Object>entry:values.entrySet()){
  37. String fieldName=entry.getKey();
  38. Object fieldValue=entry.getValue();
  39. ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);
  40. }
  41. }
  42. }catch(Exception e){
  43. e.printStackTrace();
  44. }finally{
  45. JDBCTools.release(rs,preparedStatement,conn);
  46. }
  47. return entity;
  48. }

其中JDBCTools.java为:

  1. /*
  2. * 操作JDBC的工具类,其中封装了一些工具方法
  3. * 通过读取配置文件从数据库服务器获取一个连接*/
  4. public class JDBCTools {
  5. public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException{
  6. //1.准备连接数据库的4个字符串。
  7. //1)z创建jdbc.properties对象。
  8. Properties properties=new Properties();
  9. //2)加载对应的输入流。
  10. InputStream in=JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");
  11. //3)加载2)对应的输入流
  12. properties.load(in);
  13. //4)具体决定user,password等4个字符串。
  14. String user=properties.getProperty("user");
  15. String password=properties.getProperty("password");
  16. String driver=properties.getProperty("driverClass");
  17. String jdbcUrl=properties.getProperty("jdbcUrl");
  18. //2.加载数据库驱动(对应的Driver实现类中有注册驱动的静态代码块)
  19. Class.forName(driver);
  20. //3.通过DriverManager的getConnection()方法获取数据库连接。
  21. return DriverManager.getConnection(jdbcUrl,user,password);
  22. }
  23. /*
  24. *关闭Statement,Connection */
  25. public static void  release(ResultSet rs,Statement statement,Connection conn){
  26. if(rs!=null){
  27. try {
  28. rs.close();
  29. } catch (SQLException e) {
  30. // TODO Auto-generated catch block
  31. e.printStackTrace();
  32. }
  33. }
  34. if(statement!=null){
  35. try{
  36. statement.close();
  37. }catch(Exception e2){
  38. e2.printStackTrace();
  39. }
  40. }
  41. if(conn!=null){
  42. try{
  43. conn.close();
  44. }catch(Exception e2){
  45. e2.printStackTrace();
  46. }
  47. }
  48. }
  49. public static void update(String sql) throws SQLException{
  50. Connection conn=null;
  51. Statement statement=null;
  52. try{
  53. conn=JDBCTools.getConnection();
  54. statement=conn.createStatement();
  55. statement.executeUpdate(sql);
  56. }catch(Exception e){
  57. e.printStackTrace();
  58. }finally{
  59. JDBCTools.release(null,statement, conn);
  60. }
  61. }
  62. public static void update(String sql,Object...args) throws IOException, ClassNotFoundException{
  63. Connection conn=null;
  64. PreparedStatement pstmt=null;
  65. try{
  66. conn=JDBCTools.getConnection();
  67. pstmt=conn.prepareStatement(sql);
  68. for(int i=0;i<args.length;i++){
  69. pstmt.setObject(i+1,args[i]);
  70. }
  71. pstmt.executeUpdate();
  72. }catch(SQLException e){
  73. System.out.println("使用预编译语句更新数据操作发生异常");
  74. }
  75. }
  76. /*
  77. * 1ResultSetMetaData是描述ResultSet的元数据的对象,即从中可以获取到结果集中有多少列,列名是多少。。。
  78. * 2得到ResultSetNataData对象:调用ResultSet的getMetaData()方法
  79. * ResultSetMetaData有哪些方法。
  80. * int getColumnCount():SQL语句中包含哪些列。
  81. * String getColumnLable(int column)获取指定的列的别名,其中索引从1开始。*/
  82. public <T> T get(Class<T> clazz,String sql,Object...args){
  83. /*
  84. * 1先利用SQL进行查询得到结果集
  85. * 2利用反射创建实体类的对象
  86. * 3获取结果集的列的别名:idcard。。。
  87. * 4获取结果集的每一列的值,结合3得到一个Map。键:列的别名,值:列的值
  88. * 5再利用反射为2的对应的属性赋值。*/
  89. T entity=null;
  90. Connection conn=null;
  91. PreparedStatement preparedStatement=null;
  92. ResultSet rs=null;
  93. try{
  94. conn=JDBCTools.getConnection();
  95. preparedStatement=conn.prepareStatement(sql);
  96. for(int i=0;i<args.length;i++)
  97. {
  98. preparedStatement.setObject(i+1, args[i]);
  99. }
  100. //1得到rs
  101. rs=preparedStatement.executeQuery();
  102. //2得到结果集ResultSetMetaData对象。
  103. ResultSetMetaData rsmd=rs.getMetaData();
  104. //3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值
  105. Map<String,Object>values=
  106. new HashMap<String,Object>();
  107. //处理结果集。
  108. while(rs.next()){
  109. for(int i=0;i<rsmd.getColumnCount();i++){
  110. String columnLabel=rsmd.getColumnLabel(i+1);
  111. Object columnValue=rs.getObject(columnLabel);
  112. values.put(columnLabel,columnValue);
  113. }
  114. }
  115. //5若Map不为空利用反射创建clazz对应的对象。
  116. if(values.size()>0){
  117. entity=clazz.newInstance();
  118. for(Map.Entry<String, Object>entry:values.entrySet()){
  119. String fieldName=entry.getKey();
  120. Object fieldValue=entry.getValue();
  121. ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);
  122. }
  123. }
  124. }catch(Exception e){
  125. e.printStackTrace();
  126. }finally{
  127. JDBCTools.release(rs,preparedStatement,conn);
  128. }
  129. return entity;
  130. }
  131. public Customer getCustomer(String sql,Object...args){
  132. Customer customer=null;
  133. Connection conn=null;
  134. PreparedStatement preparedStatement=null;
  135. ResultSet rs=null;
  136. try{
  137. conn=JDBCTools.getConnection();
  138. preparedStatement=conn.prepareStatement(sql);
  139. for(int i=0;i<args.length;i++)
  140. {
  141. preparedStatement.setObject(i+1, args[i]);
  142. }
  143. rs=preparedStatement.executeQuery();
  144. if(rs.next()){
  145. customer=new Customer();
  146. customer.setId(rs.getInt(1));
  147. customer.setName(rs.getString(2));
  148. customer.setEmail(rs.getString(3));
  149. customer.setBirth(rs.getDate(4));
  150. }
  151. }catch(Exception e){
  152. e.printStackTrace();
  153. }finally{
  154. JDBCTools.release(rs,preparedStatement,conn);
  155. }
  156. return customer;
  157. }
  158. }

ReflectionUtils.java为:

  1. package com.atguigu.jdbc;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Modifier;
  6. import java.lang.reflect.ParameterizedType;
  7. import java.lang.reflect.Type;
  8. /**
  9. * 反射的 Utils 函数集合
  10. * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
  11. * @author Administrator
  12. *
  13. */
  14. public class ReflectionUtils {
  15. /**
  16. * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
  17. * 如: public EmployeeDao extends BaseDao<Employee, String>
  18. * @param clazz
  19. * @param index
  20. * @return
  21. */
  22. @SuppressWarnings("unchecked")
  23. public static Class getSuperClassGenricType(Class clazz, int index){
  24. Type genType = clazz.getGenericSuperclass();
  25. if(!(genType instanceof ParameterizedType)){
  26. return Object.class;
  27. }
  28. Type [] params = ((ParameterizedType)genType).getActualTypeArguments();
  29. if(index >= params.length || index < 0){
  30. return Object.class;
  31. }
  32. if(!(params[index] instanceof Class)){
  33. return Object.class;
  34. }
  35. return (Class) params[index];
  36. }
  37. /**
  38. * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
  39. * 如: public EmployeeDao extends BaseDao<Employee, String>
  40. * @param <T>
  41. * @param clazz
  42. * @return
  43. */
  44. @SuppressWarnings("unchecked")
  45. public static<T> Class<T> getSuperGenericType(Class clazz){
  46. return getSuperClassGenricType(clazz, 0);
  47. }
  48. /**
  49. * 循环向上转型, 获取对象的 DeclaredMethod
  50. * @param object
  51. * @param methodName
  52. * @param parameterTypes
  53. * @return
  54. */
  55. public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){
  56. for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
  57. try {
  58. //superClass.getMethod(methodName, parameterTypes);
  59. return superClass.getDeclaredMethod(methodName, parameterTypes);
  60. } catch (NoSuchMethodException e) {
  61. //Method 不在当前类定义, 继续向上转型
  62. }
  63. //..
  64. }
  65. return null;
  66. }
  67. /**
  68. * 使 filed 变为可访问
  69. * @param field
  70. */
  71. public static void makeAccessible(Field field){
  72. if(!Modifier.isPublic(field.getModifiers())){
  73. field.setAccessible(true);
  74. }
  75. }
  76. /**
  77. * 循环向上转型, 获取对象的 DeclaredField
  78. * @param object
  79. * @param filedName
  80. * @return
  81. */
  82. public static Field getDeclaredField(Object object, String filedName){
  83. for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
  84. try {
  85. return superClass.getDeclaredField(filedName);
  86. } catch (NoSuchFieldException e) {
  87. //Field 不在当前类定义, 继续向上转型
  88. }
  89. }
  90. return null;
  91. }
  92. /**
  93. * 直接调用对象方法, 而忽略修饰符(private, protected)
  94. * @param object
  95. * @param methodName
  96. * @param parameterTypes
  97. * @param parameters
  98. * @return
  99. * @throws InvocationTargetException
  100. * @throws IllegalArgumentException
  101. */
  102. public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
  103. Object [] parameters) throws InvocationTargetException{
  104. Method method = getDeclaredMethod(object, methodName, parameterTypes);
  105. if(method == null){
  106. throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
  107. }
  108. method.setAccessible(true);
  109. try {
  110. return method.invoke(object, parameters);
  111. } catch(IllegalAccessException e) {
  112. System.out.println("不可能抛出的异常");
  113. }
  114. return null;
  115. }
  116. /**
  117. * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
  118. * @param object
  119. * @param fieldName
  120. * @param value
  121. */
  122. public static void setFieldValue(Object object, String fieldName, Object value){
  123. Field field = getDeclaredField(object, fieldName);
  124. if (field == null)
  125. throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
  126. makeAccessible(field);
  127. try {
  128. field.set(object, value);
  129. } catch (IllegalAccessException e) {
  130. System.out.println("不可能抛出的异常");
  131. }
  132. }
  133. /**
  134. * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
  135. * @param object
  136. * @param fieldName
  137. * @return
  138. */
  139. public static Object getFieldValue(Object object, String fieldName){
  140. Field field = getDeclaredField(object, fieldName);
  141. if (field == null)
  142. throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
  143. makeAccessible(field);
  144. Object result = null;
  145. try {
  146. result = field.get(object);
  147. } catch (IllegalAccessException e) {
  148. System.out.println("不可能抛出的异常");
  149. }
  150. return result;
  151. }
  152. }

Customer类为:

  1. package com.atguigu.jdbc;
  2. import java.sql.Date;
  3. public class Customer {
  4. private int id;
  5. private String name;
  6. private String email;
  7. private Date birth;
  8. public int getId() {
  9. return id;
  10. }
  11. public void setId(int id) {
  12. this.id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. public String getEmail() {
  21. return email;
  22. }
  23. public void setEmail(String email) {
  24. this.email = email;
  25. }
  26. public Date getBirth() {
  27. return birth;
  28. }
  29. public void setBirth(Date birth) {
  30. this.birth = birth;
  31. }
  32. public Customer(){}
  33. public Customer(int id, String name, String email, Date birth) {
  34. super();
  35. this.id = id;
  36. this.name = name;
  37. this.email = email;
  38. this.birth = birth;
  39. }
  40. public String toString() {
  41. return "Customer [id=" + id + ", name=" + name + ", email=" + email
  42. + ", birth=" + birth + "]";
  43. }
  44. }

JDBC连接数据库反射实现O/R映射的更多相关文章

  1. JDBC与反射

    什么是JDBC Java定义了一套关于连接使用数据库的规范(接口)叫做JDBC,许多数据库厂商实现了这个规范,所以我们可以通过Java提供的接口编程,使得我们更换数据库的时候不用修改原来的代码,只需要 ...

  2. JDBC连接数据库经验技巧(转)

    Java数据库连接(JDBC)由一组用 Java 编程语言编写的类和接口组成.JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序.然而各个开 ...

  3. 006开源O/R映射框架内容回顾

    Hibernate是一个O/R映射框架(也称为ORM) 从ORM词来看,O---Object(对象模型):R--- Relational(关联模型),可以做对象和关联的一种映射,当然这只是部分功能,一 ...

  4. 001---Hibernate简介( 开源O/R映射框架)

    该系列教程是使用hibernate3,hibernate4和3有区别(集成spring,使用等),请注意 001---Hibernate简介(开源O/R映射框架) ORM(Object Relatio ...

  5. (转)完整java开发中JDBC连接数据库代码和步骤

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...

  6. 转 JDBC连接数据库(二)——连接池

    https://www.cnblogs.com/xiaotiaosi/p/6398371.html 数据库保持长连接,不过一直都是idle,除非有用户激活连接,这样后果是无法删除用户,但是不影响数据库 ...

  7. JDBC连接数据库步骤及Class.forName()(转)

    JDBC连接数据库 JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java DataBase Connectivity,java数据库连接)是一种 ...

  8. 【Mybatis源码解析】- JDBC连接数据库的原理和操作

    JDBC连接数据库的原理和操作 JDBC即Java DataBase Connectivity,java数据库连接:JDBC 提供的API可以让JAVA通过API方式访问关系型数据库,执行SQL语句, ...

  9. JDBC基础篇(MYSQL)——通过JDBC连接数据库的三种方式

    package day01_jdbc; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManage ...

随机推荐

  1. (转)Mysql主从复制搭建及详解

    http://www.cnblogs.com/kevingrace/p/6256603.html---------Mysql主从同步(1)-主从/主主环境部署梳理 原文:http://blog.csd ...

  2. Eclipse 安装spring插件spring tool suite(STS)

    安装方法有2种,一种是在线安装,比较方便,但耗时较长,一种是离线安装,步骤复杂一些,但耗时少,下面请看详细步骤. 方法一:在线安装     1:打开eclipse菜单Help>Eclise Ma ...

  3. vue下拉搜索

    vue版本是1.0.21 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  4. C 标准库 - string.h之memcpy使用

    memcpy Copy block of memory Copies the values of num bytes from the location pointed to by source di ...

  5. PHP之string之trim()函数使用

    trim (PHP 4, PHP 5, PHP 7) trim - Strip whitespace (or other characters) from the beginning and end ...

  6. HTTPS 使用成本

    HTTPS 目前唯一的问题就是它还没有得到大规模应用,受到的关注和研究都比较少.至于使用成本和额外开销,完全不用太过担心. 一般来讲,使用 HTTPS 前大家可能会非常关注如下问题: 证书费用以及更新 ...

  7. CNN理解与实现

    CNN理解与实现 组成部分 Convolution Layer Pool Layer: Max-pooling layer Average-pooling layer Full Connected(F ...

  8. js判断向量叉点 并求出交点坐标

     代码如下可以直接运行,判断向量相交并求出交点坐标 <!DOCTYPE html> <html> <head> <meta http-equiv=" ...

  9. [javaSE] GUI(图形用户界面)

    java为gui提供的对象都在java.Awt和javax.Swing包中 Awt:抽象窗口工具包,依赖平台,调用系统的本地方法 Swing:完全由java实现的轻量级工具库 eclipse官方封装了 ...

  10. 一:SpringCloud

    一:前提知识+相关说明 前提知识:springmvc+spring/springboot+mybatis+maven+git...... cloud技术的五大神兽: 面试题: 什么是微服务? 微服务之 ...