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 ...
随机推荐
- 【JAVA-WEB】在url上追加sessionid
HttpSession session = request.getSession(); url = url+";jsessionid="+session.getId();
- 配置tomcat-users
<role rolename="admin-gui"/><role rolename="admin-script"/><role ...
- javascript的HelloWorld
javascript:边解释边执行.是一种解释型语言. defer属性,延迟执行代码,(整个页面加载完之后,window.onload) 代码: <!DOCTYPE HTML PUBLIC &q ...
- IPC之binder机制
我们知道,在Android系统中,每一个应用程序都运行在独立的进程中,这也保证了当其中一个程序出现异常而不会影响另一个应用程序的正常运转.在许多情况下,我们activity都会与各种系统的servic ...
- Java网络编程(一)
Java网络编程: 1.1: 网络编程:对于我这个“研究不深”的网络菜鸟来说,我觉得网络编程就是实现计算机与计算机之间通信的编程.写些能够实现计算机与计算机之间的通信就行了(目前来说). 1.2:一台 ...
- Ambari集群里操作时典型权限问题put: `/home/bigdata/1.txt': No such file or directory的解决方案(图文详解)
不多说,直接上干货! 问题详情 明明put该有的文件在,可是怎么提示的是文件找不到的错误呢? 我就纳闷了put: `/home/bigdata/1.txt': No such file or dire ...
- push到github报错解决方法
在push代码到远程仓库时,报了如下的错误: $ git push -u origin master To https://github.com/11pdg/group-buy.git ! [reje ...
- 【LeetCode题解】530_二分搜索树的最小绝对值差
目录 [LeetCode题解]530_二分搜索树的最小绝对值差 描述 方法一.中序遍历二分搜索树 思路 Java 代码 Python 代码 [LeetCode题解]530_二分搜索树的最小绝对值差 描 ...
- [PY3]——函数——生成器(yield关键字)
函数—生成器篇 1. 认识和区分可迭代or生成器 1.1 可迭代对象 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象 当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代 ...
- 阿里云 ECS服务器安装流程
1. 挂载硬盘 2. 上传文件 3 .vncserver unset DISPLAY who -u export DISPLAY= xhost + 4. java /etc/profile expor ...