JDBC连接数据库反射实现O/R映射
- 测试preparedStatement
- public void testPreparedStatement(){
- Connection connection=null;
- PreparedStatement preparedStatement=null;
- try{
- connection =JDBCTools.getConnection();
- String sql="insert into customers(name,email,birth) "+
- "values(?,?,?)";
- preparedStatement=connection.prepareStatement(sql);
- preparedStatement.setString(1, "ATGUIGU");
- preparedStatement.setString(2, "simleint@163.com");
- preparedStatement.setDate(3, new Date(new java.util.Date().getTime()));
- preparedStatement.executeUpdate();
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- JDBCTools.release(null, preparedStatement, connection);
- }
- }
- 测试结果集元数据: 利用SQL进行查询,得到结果集。
- 利用反射创建实体对象,获取结果集的列的别名。
- 在获取结果集的每一列的值,结合3得到一个Map,键的别名,值:列的值。</span>
- 再利用反射为2的对应的属性赋值:属性为Map的键,值为Map的值。</span>
- public void testResultSetMetaData(){
- Customer customer=null;
- Connection conn=null;
- PreparedStatement preparedStatement=null;
- ResultSet rs=null;
- try{
- String sql="select ID id,NAME name,EMAIL email,BIRTH birth from customers";
- conn=JDBCTools.getConnection();
- preparedStatement=conn.prepareStatement(sql);
- 1得到rs
- rs=preparedStatement.executeQuery();
- Map<String,Object>values=
- new HashMap<String,Object>();
- //2得到结果集ResultSetMetaData对象。
- ResultSetMetaData rsmd=rs.getMetaData();
- while(rs.next()){
- for(int i=0;i<rsmd.getColumnCount();i++){
- String columnLabel=rsmd.getColumnLabel(i+1);
- Object columnValue=rs.getObject(columnLabel);
- values.put(columnLabel,columnValue);
- }
- }
- System.out.println(values);
- Class clazz=Customer.class;
- Object object=clazz.newInstance();
- for(Map.Entry<String, Object>entry:values.entrySet()){
- String fieldName=entry.getKey();
- Object fieldValue=entry.getValue();
- System.out.println(fieldName+" :"+fieldValue);
- ReflectionUtils.setFieldValue(object,fieldName,fieldValue);
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- JDBCTools.release(rs,preparedStatement,conn);
- }
- }
抽取出泛型方法:
- public void testGet(){
- String sql="select ID id,NAME name,EMAIL email,BIRTH birth "+"From customers";
- Customer customer=get(Customer.class,sql);
- System.out.println(customer);
- }
- public <T> T get(Class<T> clazz,String sql,Object...args){
- T entity=null;
- Connection conn=null;
- PreparedStatement preparedStatement=null;
- ResultSet rs=null;
- try{
- conn=JDBCTools.getConnection();
- preparedStatement=conn.prepareStatement(sql);
- for(int i=0;i<args.length;i++)
- {
- preparedStatement.setObject(i+1, args[i]);
- }
- //1得到rs
- rs=preparedStatement.executeQuery();
- //2得到结果集ResultSetMetaData对象。
- ResultSetMetaData rsmd=rs.getMetaData();
- //3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值
- Map<String,Object>values=
- new HashMap<String,Object>();
- //处理结果集。
- while(rs.next()){
- for(int i=0;i<rsmd.getColumnCount();i++){
- String columnLabel=rsmd.getColumnLabel(i+1);
- Object columnValue=rs.getObject(columnLabel);
- values.put(columnLabel,columnValue);
- }
- }
- //5若Map不为空利用反射创建clazz对应的对象。
- if(values.size()>0){
- entity=clazz.newInstance();
- for(Map.Entry<String, Object>entry:values.entrySet()){
- String fieldName=entry.getKey();
- Object fieldValue=entry.getValue();
- ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);
- }
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- JDBCTools.release(rs,preparedStatement,conn);
- }
- return entity;
- }
其中JDBCTools.java为:
- /*
- * 操作JDBC的工具类,其中封装了一些工具方法
- * 通过读取配置文件从数据库服务器获取一个连接*/
- public class JDBCTools {
- public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException{
- //1.准备连接数据库的4个字符串。
- //1)z创建jdbc.properties对象。
- Properties properties=new Properties();
- //2)加载对应的输入流。
- InputStream in=JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");
- //3)加载2)对应的输入流
- properties.load(in);
- //4)具体决定user,password等4个字符串。
- String user=properties.getProperty("user");
- String password=properties.getProperty("password");
- String driver=properties.getProperty("driverClass");
- String jdbcUrl=properties.getProperty("jdbcUrl");
- //2.加载数据库驱动(对应的Driver实现类中有注册驱动的静态代码块)
- Class.forName(driver);
- //3.通过DriverManager的getConnection()方法获取数据库连接。
- return DriverManager.getConnection(jdbcUrl,user,password);
- }
- /*
- *关闭Statement,Connection */
- public static void release(ResultSet rs,Statement statement,Connection conn){
- if(rs!=null){
- try {
- rs.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if(statement!=null){
- try{
- statement.close();
- }catch(Exception e2){
- e2.printStackTrace();
- }
- }
- if(conn!=null){
- try{
- conn.close();
- }catch(Exception e2){
- e2.printStackTrace();
- }
- }
- }
- public static void update(String sql) throws SQLException{
- Connection conn=null;
- Statement statement=null;
- try{
- conn=JDBCTools.getConnection();
- statement=conn.createStatement();
- statement.executeUpdate(sql);
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- JDBCTools.release(null,statement, conn);
- }
- }
- public static void update(String sql,Object...args) throws IOException, ClassNotFoundException{
- Connection conn=null;
- PreparedStatement pstmt=null;
- try{
- conn=JDBCTools.getConnection();
- pstmt=conn.prepareStatement(sql);
- for(int i=0;i<args.length;i++){
- pstmt.setObject(i+1,args[i]);
- }
- pstmt.executeUpdate();
- }catch(SQLException e){
- System.out.println("使用预编译语句更新数据操作发生异常");
- }
- }
- /*
- * 1ResultSetMetaData是描述ResultSet的元数据的对象,即从中可以获取到结果集中有多少列,列名是多少。。。
- * 2得到ResultSetNataData对象:调用ResultSet的getMetaData()方法
- * ResultSetMetaData有哪些方法。
- * int getColumnCount():SQL语句中包含哪些列。
- * String getColumnLable(int column)获取指定的列的别名,其中索引从1开始。*/
- public <T> T get(Class<T> clazz,String sql,Object...args){
- /*
- * 1先利用SQL进行查询得到结果集
- * 2利用反射创建实体类的对象
- * 3获取结果集的列的别名:idcard。。。
- * 4获取结果集的每一列的值,结合3得到一个Map。键:列的别名,值:列的值
- * 5再利用反射为2的对应的属性赋值。*/
- T entity=null;
- Connection conn=null;
- PreparedStatement preparedStatement=null;
- ResultSet rs=null;
- try{
- conn=JDBCTools.getConnection();
- preparedStatement=conn.prepareStatement(sql);
- for(int i=0;i<args.length;i++)
- {
- preparedStatement.setObject(i+1, args[i]);
- }
- //1得到rs
- rs=preparedStatement.executeQuery();
- //2得到结果集ResultSetMetaData对象。
- ResultSetMetaData rsmd=rs.getMetaData();
- //3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值
- Map<String,Object>values=
- new HashMap<String,Object>();
- //处理结果集。
- while(rs.next()){
- for(int i=0;i<rsmd.getColumnCount();i++){
- String columnLabel=rsmd.getColumnLabel(i+1);
- Object columnValue=rs.getObject(columnLabel);
- values.put(columnLabel,columnValue);
- }
- }
- //5若Map不为空利用反射创建clazz对应的对象。
- if(values.size()>0){
- entity=clazz.newInstance();
- for(Map.Entry<String, Object>entry:values.entrySet()){
- String fieldName=entry.getKey();
- Object fieldValue=entry.getValue();
- ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);
- }
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- JDBCTools.release(rs,preparedStatement,conn);
- }
- return entity;
- }
- public Customer getCustomer(String sql,Object...args){
- Customer customer=null;
- Connection conn=null;
- PreparedStatement preparedStatement=null;
- ResultSet rs=null;
- try{
- conn=JDBCTools.getConnection();
- preparedStatement=conn.prepareStatement(sql);
- for(int i=0;i<args.length;i++)
- {
- preparedStatement.setObject(i+1, args[i]);
- }
- rs=preparedStatement.executeQuery();
- if(rs.next()){
- customer=new Customer();
- customer.setId(rs.getInt(1));
- customer.setName(rs.getString(2));
- customer.setEmail(rs.getString(3));
- customer.setBirth(rs.getDate(4));
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- JDBCTools.release(rs,preparedStatement,conn);
- }
- return customer;
- }
- }
ReflectionUtils.java为:
- package com.atguigu.jdbc;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.lang.reflect.Modifier;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- /**
- * 反射的 Utils 函数集合
- * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
- * @author Administrator
- *
- */
- public class ReflectionUtils {
- /**
- * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
- * 如: public EmployeeDao extends BaseDao<Employee, String>
- * @param clazz
- * @param index
- * @return
- */
- @SuppressWarnings("unchecked")
- public static Class getSuperClassGenricType(Class clazz, int index){
- Type genType = clazz.getGenericSuperclass();
- if(!(genType instanceof ParameterizedType)){
- return Object.class;
- }
- Type [] params = ((ParameterizedType)genType).getActualTypeArguments();
- if(index >= params.length || index < 0){
- return Object.class;
- }
- if(!(params[index] instanceof Class)){
- return Object.class;
- }
- return (Class) params[index];
- }
- /**
- * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
- * 如: public EmployeeDao extends BaseDao<Employee, String>
- * @param <T>
- * @param clazz
- * @return
- */
- @SuppressWarnings("unchecked")
- public static<T> Class<T> getSuperGenericType(Class clazz){
- return getSuperClassGenricType(clazz, 0);
- }
- /**
- * 循环向上转型, 获取对象的 DeclaredMethod
- * @param object
- * @param methodName
- * @param parameterTypes
- * @return
- */
- public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){
- for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
- try {
- //superClass.getMethod(methodName, parameterTypes);
- return superClass.getDeclaredMethod(methodName, parameterTypes);
- } catch (NoSuchMethodException e) {
- //Method 不在当前类定义, 继续向上转型
- }
- //..
- }
- return null;
- }
- /**
- * 使 filed 变为可访问
- * @param field
- */
- public static void makeAccessible(Field field){
- if(!Modifier.isPublic(field.getModifiers())){
- field.setAccessible(true);
- }
- }
- /**
- * 循环向上转型, 获取对象的 DeclaredField
- * @param object
- * @param filedName
- * @return
- */
- public static Field getDeclaredField(Object object, String filedName){
- for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
- try {
- return superClass.getDeclaredField(filedName);
- } catch (NoSuchFieldException e) {
- //Field 不在当前类定义, 继续向上转型
- }
- }
- return null;
- }
- /**
- * 直接调用对象方法, 而忽略修饰符(private, protected)
- * @param object
- * @param methodName
- * @param parameterTypes
- * @param parameters
- * @return
- * @throws InvocationTargetException
- * @throws IllegalArgumentException
- */
- public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
- Object [] parameters) throws InvocationTargetException{
- Method method = getDeclaredMethod(object, methodName, parameterTypes);
- if(method == null){
- throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
- }
- method.setAccessible(true);
- try {
- return method.invoke(object, parameters);
- } catch(IllegalAccessException e) {
- System.out.println("不可能抛出的异常");
- }
- return null;
- }
- /**
- * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
- * @param object
- * @param fieldName
- * @param value
- */
- public static void setFieldValue(Object object, String fieldName, Object value){
- Field field = getDeclaredField(object, fieldName);
- if (field == null)
- throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
- makeAccessible(field);
- try {
- field.set(object, value);
- } catch (IllegalAccessException e) {
- System.out.println("不可能抛出的异常");
- }
- }
- /**
- * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
- * @param object
- * @param fieldName
- * @return
- */
- public static Object getFieldValue(Object object, String fieldName){
- Field field = getDeclaredField(object, fieldName);
- if (field == null)
- throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
- makeAccessible(field);
- Object result = null;
- try {
- result = field.get(object);
- } catch (IllegalAccessException e) {
- System.out.println("不可能抛出的异常");
- }
- return result;
- }
- }
Customer类为:
- package com.atguigu.jdbc;
- import java.sql.Date;
- public class Customer {
- private int id;
- private String name;
- private String email;
- private Date birth;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getEmail() {
- return email;
- }
- public void setEmail(String email) {
- this.email = email;
- }
- public Date getBirth() {
- return birth;
- }
- public void setBirth(Date birth) {
- this.birth = birth;
- }
- public Customer(){}
- public Customer(int id, String name, String email, Date birth) {
- super();
- this.id = id;
- this.name = name;
- this.email = email;
- this.birth = birth;
- }
- public String toString() {
- return "Customer [id=" + id + ", name=" + name + ", email=" + email
- + ", birth=" + birth + "]";
- }
- }
JDBC连接数据库反射实现O/R映射的更多相关文章
- JDBC与反射
什么是JDBC Java定义了一套关于连接使用数据库的规范(接口)叫做JDBC,许多数据库厂商实现了这个规范,所以我们可以通过Java提供的接口编程,使得我们更换数据库的时候不用修改原来的代码,只需要 ...
- JDBC连接数据库经验技巧(转)
Java数据库连接(JDBC)由一组用 Java 编程语言编写的类和接口组成.JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序.然而各个开 ...
- 006开源O/R映射框架内容回顾
Hibernate是一个O/R映射框架(也称为ORM) 从ORM词来看,O---Object(对象模型):R--- Relational(关联模型),可以做对象和关联的一种映射,当然这只是部分功能,一 ...
- 001---Hibernate简介( 开源O/R映射框架)
该系列教程是使用hibernate3,hibernate4和3有区别(集成spring,使用等),请注意 001---Hibernate简介(开源O/R映射框架) ORM(Object Relatio ...
- (转)完整java开发中JDBC连接数据库代码和步骤
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...
- 转 JDBC连接数据库(二)——连接池
https://www.cnblogs.com/xiaotiaosi/p/6398371.html 数据库保持长连接,不过一直都是idle,除非有用户激活连接,这样后果是无法删除用户,但是不影响数据库 ...
- JDBC连接数据库步骤及Class.forName()(转)
JDBC连接数据库 JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java DataBase Connectivity,java数据库连接)是一种 ...
- 【Mybatis源码解析】- JDBC连接数据库的原理和操作
JDBC连接数据库的原理和操作 JDBC即Java DataBase Connectivity,java数据库连接:JDBC 提供的API可以让JAVA通过API方式访问关系型数据库,执行SQL语句, ...
- JDBC基础篇(MYSQL)——通过JDBC连接数据库的三种方式
package day01_jdbc; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManage ...
随机推荐
- (转)Mysql主从复制搭建及详解
http://www.cnblogs.com/kevingrace/p/6256603.html---------Mysql主从同步(1)-主从/主主环境部署梳理 原文:http://blog.csd ...
- Eclipse 安装spring插件spring tool suite(STS)
安装方法有2种,一种是在线安装,比较方便,但耗时较长,一种是离线安装,步骤复杂一些,但耗时少,下面请看详细步骤. 方法一:在线安装 1:打开eclipse菜单Help>Eclise Ma ...
- vue下拉搜索
vue版本是1.0.21 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- C 标准库 - string.h之memcpy使用
memcpy Copy block of memory Copies the values of num bytes from the location pointed to by source di ...
- PHP之string之trim()函数使用
trim (PHP 4, PHP 5, PHP 7) trim - Strip whitespace (or other characters) from the beginning and end ...
- HTTPS 使用成本
HTTPS 目前唯一的问题就是它还没有得到大规模应用,受到的关注和研究都比较少.至于使用成本和额外开销,完全不用太过担心. 一般来讲,使用 HTTPS 前大家可能会非常关注如下问题: 证书费用以及更新 ...
- CNN理解与实现
CNN理解与实现 组成部分 Convolution Layer Pool Layer: Max-pooling layer Average-pooling layer Full Connected(F ...
- js判断向量叉点 并求出交点坐标
代码如下可以直接运行,判断向量相交并求出交点坐标 <!DOCTYPE html> <html> <head> <meta http-equiv=" ...
- [javaSE] GUI(图形用户界面)
java为gui提供的对象都在java.Awt和javax.Swing包中 Awt:抽象窗口工具包,依赖平台,调用系统的本地方法 Swing:完全由java实现的轻量级工具库 eclipse官方封装了 ...
- 一:SpringCloud
一:前提知识+相关说明 前提知识:springmvc+spring/springboot+mybatis+maven+git...... cloud技术的五大神兽: 面试题: 什么是微服务? 微服务之 ...