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. JS框架设计之命名空间设计一种子模块

    命名空间 1.种子模块作为一个框架的最开始,除了负责初始化框架的最基础部分. 2.种子模块作为框架的最开始,那么什么是种子框架的最开始呢?答案是IIFE(立即调用函数表达式); IIFE(立即调用函数 ...

  2. php 如何匹配中文或英文姓名

    这几天在做项目的用户注册时,想限制用户使用一些比较奇怪的字符作为名字,即使用中文或者英文名字. 查了一些资料,例如:网友挥得更高的百度空间 写下了以下函数. //验证名字和密码 if (!preg_m ...

  3. accessToken的使用

    1.accessToken是啥,干嘛用? 形象解释:申请调兵-->皇帝同意-->兵符-->开始调兵 拿到用户在第三方平台的唯一的标识; 获取用户的nickname,头像,邮箱等其他信 ...

  4. guava学习:guava集合类型-Bimap

    学习guava让我惊喜的第二个接口就是:Bimap BiMap是一种特殊的映射其保持映射,同时确保没有重复的值是存在于该映射和一个值可以安全地用于获取键背面的倒数映射. 最近开发过程中,经常会有这种根 ...

  5. MySQL Group Replication 介绍

    2016-12-12,一个重要的日子,mysql5.7.17 GA版发布,正式推出Group Replication(组复制) 插件,通过这个插件增强了MySQL原有的高可用方案(原有的Replica ...

  6. 如何创建一个基于Node的HTTP服务器

    首先创建一个HTTP服务器. var http = require('http'); function serve(request,response) { console.log(request.me ...

  7. Postgresql 连接更新

    update dbo.m_role_fun a set role_code = b.rsc from (select rsc, fun_code from dbo.m_fun) b where a.f ...

  8. 什么是SSH

    SSH不仅实现了视图.控制器与模型的彻底分离,而且还实现了业务逻辑层与持久层的分离,耦合度降低,系统的灵活性更好,可复用性高 官方的说法:SSH是 struts+spring+hibernate的一个 ...

  9. 清空控件的TeXt属性

    foreach (Control item in groupBox1.Controls) { if (item is TextBox) //判断控件是不是TextBox { item.Text = & ...

  10. 数据集DataSet

    ADO.NET数据访问技术的一个突出的特点就是支持离线访问,而实现这种离线访问技术的核心就是DateSet对象,该对象通过将数据驻留在内存来实现离线访问. DataSet对象由一组DataTable对 ...