zoukankan      html  css  js  c++  java
  • Java进阶笔记(一):自定义持久层框架

    一、相关概念

    什么是持久层:

    可以长时间保存数据的设备,如硬盘等。

    什么是持久层框架:

    可以操作持久层数据的一套可复用的相互协作的类(代码)。

    JDBC:

    Java数据库连接(Java Database Connectivity,简称JDBC),是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

    对象/关系数据库映射(ORM):

    ORM全称Object Relation Mapping(对象-关系映射),一种程序设计技术,通过在对象与关系型数据库之间建立映射,达到操作对象来操作数据库的效果。

    Mybatis:

    基于ORM的半自动轻量级持久层框架,可以定制化SQL,因此是半自动,不过可以进行SQL优化获得性能提升。

    Hibernate:

    全自动化的ORM框架,无需编写SQL语句,只需要设计好对象之间的关系,配置好xml文件;数据库,表,表之间的关系,都是自动生成。

    二、概要

    学到了如何自己写一个持久层框架,核心是对JDBC的封装,简要步骤如下:

    在resources文件夹下新建xml,将jdbc信息、sql语句写入,在程序中使用dom4j读取;

    使用工厂模式,编写SQLSessionFactory类,获取SqlSession对象;

    使用动态代理和反射,获取Mapper对象的代理,通过代理对象执行sql。

    三、遇到的知识点

    1.new PropertyDescriptor()的用法:

    下方代码是自定义持久层部分代码,当执行select语句后返回resultSet时。

    //这个mappedStatement是自定义的一个类,从xml中用dom4j获取了resultType的值填入了这个类的变量中,然后这里用get方法得到resultType。
    String resultType = mappedStatement.getResultType();
    //应该先判空,这里省略了。
    Class<?> resultTypeClass = Class.forName(resultType);
    //返回用的list
    ArrayList<Object> al = new ArrayList<>();
    //执行sql后返回的结果集有下一个时
    while(resultSet.next()){
      //实现resultType用的一个对象
      Object o = resultTypeClass.newInstance();
      //元数据
      ResultSetMetaData metaData = resultSet.getMetaData();
      //遍历列
      for(int i = 1; i <= metaData.getColumnCount(); i++){
        //字段名(数据库的列名,从1开始)
    	String columnName = metaData.getColumnName(i);
    	//字段的值(数据库中对应列的值)
    	Object value = resultSet.getObject(columnName);
    	//使用内省,传入参数名与对象名,获得相关方法
    	PropertyDescriptor pd = new PropertyDescriptor(columnName, resultTypeClass);
    	//获取写方法
    	Method writeMethod = pd.getWriteMethod();
    	//将值写入对象o
    	writeMethod.invoke(o,value);
    	
      }
      //将一个结果对象放入结果list中
      al.add(o);
    }
    //返回select结果
    return (List<E>)al;

    2.getDeclaredField()方法的用法:

    下方代码是自定义持久层部分代码,当执行sql语句前、处理ParameterType与#{}参数时。

    //从自定义对象中获取ParamterType的值(从xml中用dom4j解析出来、存入自定义对象中的)
    String paramterType = mappedStatement.getParamterType();
    //获取类对象,同上,这个方法中处理了一下null
    Class<?> paramtertypeClass = getClassType(paramterType);
    //使用boundSql获取parameterMappingList,这是mybatis中处理#{}参数的类
    //一个装有sql语句中的参数的list,例如#{id}中的id。
    List<ParameterMapping> parameterMappingList = boundSql.getParameterMappingList();
    for (int i=0; i<parameterMappingList.size(); i++){
      ParameterMapping parameterMapping = parameterMappingList.get(i);
      //这个content指的是变量名,例如#{id}中的"id"这个字符串
      String content = parameterMapping.getContent();
      //然后获得这个类中字符串为content的变量对象
      Field declaredField = paramtertypeClass.getDeclaredField(content);
      //设置为允许访问私有成员模式
      declaredField.setAccessible(true);
      //这个params[i]是由Object ... 的形式传入的,取得第i个对象,例如User对象
      //然后从User对象中获取到变量为"id"的值(与content对应)(传入的params[0]表示User对象)
      Object o = declaredField.get(params[0]);
      //这里是jdbc替换sql中的"?"参数的方法,将第i+1个"?"替换为对应的值
      //从1开始,所以为i+1
      //顺序按照parameterMappingList的顺序排好了,不会乱
      preparedStatement.setObject(i+1,o);
    }
    
    //从mybatis中拿了4个文件,放到了utils目录下,分别是:【GenericTokenParser】、【ParameterMapping】、【ParameterMappingTokenHandler】、【TokenHandler】
    
  • 相关阅读:
    hdu 4135 Co-prime (容斥定理)
    hdu 1509 Windows Message Queue (优先队列)
    poj 2104 K-th Number (划分树)
    hdu 1556 Color the ball (树状数组)
    海量大数据大屏分析展示一步到位:DataWorks数据服务对接DataV最佳实践
    使用MaxCompute Java SDK运行安全相关命令
    使用MaxCompute Java SDK 执行任务卡住了,怎么办?
    老代码多=过度耦合=if else?阿里巴巴工程师这样捋直老代码
    日志服务Python消费组实战(三):实时跨域监测多日志库数据
    如何限制用户仅通过HTTPS方式访问OSS?
  • 原文地址:https://www.cnblogs.com/codeToSuccess/p/13906211.html
Copyright © 2011-2022 走看看