关于java:30个类手写Spring核心原理之自定义ORM上6

12次阅读

共计 17950 个字符,预计需要花费 45 分钟才能阅读完成。

本文节选自《Spring 5 外围原理》

1 实现思路概述

1.1 从 ResultSet 说起

说到 ResultSet,有 Java 开发教训的“小伙伴”天然最相熟不过了,不过我置信对于大多数人来说也算是“最相熟的陌生人”。从 ResultSet 取值操作大家都会,比方:


private static List<Member> select(String sql) {List<Member> result = new ArrayList<>();
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
        //1. 加载驱动类
        Class.forName("com.mysql.jdbc.Driver");
        //2. 建设连贯
        con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/gp-vip-spring-db-demo", "root","123456");
        //3. 创立语句集
        pstm =  con.prepareStatement(sql);
        //4. 执行语句集
        rs = pstm.executeQuery();
        while (rs.next()){Member instance = new Member();
            instance.setId(rs.getLong("id"));
            instance.setName(rs.getString("name"));
            instance.setAge(rs.getInt("age"));
            instance.setAddr(rs.getString("addr"));
            result.add(instance);
        }
        //5. 获取后果集
    }catch (Exception e){e.printStackTrace();
    }
    //6. 敞开后果集、敞开语句集、敞开连贯
    finally {
        try {rs.close();
            pstm.close();
            con.close();}catch (Exception e){e.printStackTrace();
        }
    }
    return result;
}

以上咱们在没有应用框架以前的惯例操作。随着业务和开发量的减少,在数据长久层这样的反复代码呈现频次十分高。因而,咱们就想到将非功能性代码和业务代码进行拆散。咱们首先想到将 ResultSet 封装数据的代码逻辑拆散,减少一个 mapperRow() 办法,专门解决对后果的封装,代码如下:


private static List<Member> select(String sql) {List<Member> result = new ArrayList<>();
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
        //1. 加载驱动类
        Class.forName("com.mysql.jdbc.Driver");
        //2. 建设连贯
        con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/gp-vip-spring-db-demo", "root","123456");
        //3. 创立语句集
        pstm =  con.prepareStatement(sql);
        //4. 执行语句集
        rs = pstm.executeQuery();
        while (rs.next()){Member instance = mapperRow(rs,rs.getRow());
            result.add(instance);
        }
        //5. 获取后果集
    }catch (Exception e){e.printStackTrace();
    }
    //6. 敞开后果集、敞开语句集、敞开连贯
    finally {
        try {rs.close();
            pstm.close();
            con.close();}catch (Exception e){e.printStackTrace();
        }
    }
    return result;
}

private static Member mapperRow(ResultSet rs, int i) throws Exception {Member instance = new Member();
    instance.setId(rs.getLong("id"));
    instance.setName(rs.getString("name"));
    instance.setAge(rs.getInt("age"));
    instance.setAddr(rs.getString("addr"));
    return instance;
}

但在实在的业务场景中,这样的代码逻辑反复率切实太高,下面的革新只能利用 Member 类,换一个实体类又要从新封装,聪慧的程序员必定不会通过纯体力劳动给每一个实体类写一个 mapperRow() 办法,肯定会想到代码复用计划。咱们无妨来做这样一个革新。
先创立 Member 类:


package com.gupaoedu.vip.orm.demo.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

@Entity
@Table(name="t_member")
@Data
public class Member implements Serializable {
    @Id private Long id;
    private String name;
    private String addr;
    private Integer age;

    @Override
    public String toString() {
        return "Member{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", addr='" + addr + '\'' +
                ", age=" + age +
                '}';
    }
}

优化 JDBC 操作:


public static void main(String[] args) {Member condition = new Member();
    condition.setName("Tom");
    condition.setAge(19);
    List<?> result =  select(condition);
    System.out.println(Arrays.toString(result.toArray()));
}

private static List<?> select(Object condition) {List<Object> result = new ArrayList<>();

    Class<?> entityClass = condition.getClass();

    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
        //1. 加载驱动类
        Class.forName("com.mysql.jdbc.Driver");
        //2. 建设连贯
        con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/gp-vip-spring-db-demo? characterEncoding=UTF-8&rewriteBatchedStatements=true","root","123456");

        // 依据类名找属性名
        Map<String,String> columnMapper = new HashMap<String,String>();
        // 依据属性名找字段名
        Map<String,String> fieldMapper = new HashMap<String,String>();
        Field[] fields =  entityClass.getDeclaredFields();
        for (Field field : fields) {field.setAccessible(true);
            String fieldName = field.getName();
            if(field.isAnnotationPresent(Column.class)){Column column = field.getAnnotation(Column.class);
                String columnName = column.name();
                columnMapper.put(columnName,fieldName);
                fieldMapper.put(fieldName,columnName);
            }else {
                // 默认就是字段名、属性名统一
                columnMapper.put(fieldName, fieldName);
                fieldMapper.put(fieldName,fieldName);
            }
        }

        //3. 创立语句集
        Table table = entityClass.getAnnotation(Table.class);
        String sql = "select * from" + table.name();

        StringBuffer where = new StringBuffer("where 1=1");
        for (Field field : fields) {Object value =field.get(condition);
            if(null != value){if(String.class == field.getType()) {where.append("and" + fieldMapper.get(field.getName()) + "='" + value + "'");
                }else{where.append("and" + fieldMapper.get(field.getName()) + "=" + value + "");
                }
                // 其余的在这里就不一一列举,前面咱们手写 ORM 框架时会欠缺
            }
        }
        System.out.println(sql + where.toString());
        pstm =  con.prepareStatement(sql + where.toString());

        //4. 执行语句集
        rs = pstm.executeQuery();

        // 元数据?// 保留了解决真正数值以外的所有附加信息
        int columnCounts = rs.getMetaData().getColumnCount();
        while (rs.next()){Object instance = entityClass.newInstance();
            for (int i = 1; i <= columnCounts; i++) {
                // 实体类属性名,对应数据库表的字段名
                // 能够通过反射机制拿到实体类的所有字段

                // 从 rs 中获得以后这个游标下的类名
                String columnName = rs.getMetaData().getColumnName(i);
                // 有可能是公有的
                Field field = entityClass.getDeclaredField(columnMapper.get(columnName));
                field.setAccessible(true);
                field.set(instance,rs.getObject(columnName));
            }

            result.add(instance);

        }

        //5. 获取后果集
    }catch (Exception e){e.printStackTrace();
    }
    //6. 敞开后果集、敞开语句集、敞开连贯
    finally {
        try {rs.close();
            pstm.close();
            con.close();}catch (Exception e){e.printStackTrace();
        }
    }

    return result;
}

下面奇妙地利用反射机制读取 Class 信息和 Annotation 信息,将数据库表中的列和类中的字段进行关联映射并赋值,以缩小反复代码。

1.2 为什么须要 ORM 框架

通过后面的解说,咱们曾经理解 ORM 框架的根本实现原理。ORM 是指对象关系映射(Object Relation Mapping),映射的不只是对象值,还有对象与对象之间的关系,例如一对多、多对多、一对一这样的表关系。当初市面上 ORM 框架也十分多,有大家所熟知的 Hibernate、Spring JDBC、MyBatis、JPA 等。在这里做一个简略的总结,如下表所示。

名称 特色 形容
Hibernate 全自动(挡) 不须要写一句 SQL
MyBatis 半自动(挡) 手自一体,反对简略的映射,简单关系须要本人写 SQL
Spring JDBC 纯手动(挡) 所有的 SQL 都要本人写,它帮咱们设计了一套规范流程

既然市面上有这么多抉择,我为什么还要本人写 ORM 框架呢?
这得从我的一次空降负责架构师的教训说起。空降面临最大的难题就是如何获得团队“小伙伴们”的信赖。过后,团队总共就 8 人,每个人的程度参差不齐,甚至有些人还没接触过 MySQL,诸如 Redis 等缓存中间件更不用说了。根本只会应用 Hibernate 的 CRUD,而且曾经影响到了零碎性能。因为工期缓和,没有工夫和精力给团队做零碎培训,也为了兼顾可控性,于是就产生了自研 ORM 框架的想法。我做了这样的顶层设计,以升高团队“小伙伴们”的存息老本,顶层接口对立参数、对立返回值,具体如下。

(1)规定查询方法的接口模型为:


/**
 * 获取列表
 * @param queryRule 查问条件
 * @return
 */
List<T> select(QueryRule queryRule) throws Exception;

/**
 * 获取分页后果
 * @param queryRule 查问条件
 * @param pageNo 页码
 * @param pageSize 每页条数
 * @return
 */
Page<?> select(QueryRule queryRule,int pageNo,int pageSize) throws Exception;

/**
 * 依据 SQL 获取列表
 * @param sql SQL 语句
 * @param args 参数
 * @return
 */
List<Map<String,Object>> selectBySql(String sql, Object... args) throws Exception;

/**
 * 依据 SQL 获取分页
 * @param sql SQL 语句
 * @param pageNo 页码
 * @param pageSize 每页条数
 * @return
 */
Page<Map<String,Object>> selectBySqlToPage(String sql, Object [] param, int pageNo, int pageSize) throws Exception;

(2)规定删除办法的接口模型为:


/**
 * 删除一条记录
 * @param entity entity 中的 ID 不能为空,如果 ID 为空,其余条件不能为空,都为空不予执行
 * @return
 */
boolean delete(T entity) throws Exception;

/**
 * 批量删除
 * @param list
 * @return 返回受影响的行数
 * @throws Exception
 */
int deleteAll(List<T> list) throws Exception;

(3)规定插入方法的接口模型为:


/**
 * 插入一条记录并返回插入后的 ID
 * @param entity 只有 entity 不等于 null,就执行插入
 * @return
 */
PK insertAndReturnId(T entity) throws Exception;

/**
 * 插入一条记录自增 ID
 * @param entity
 * @return
 * @throws Exception
 */
boolean insert(T entity) throws Exception;

/**
 * 批量插入
 * @param list
 * @return 返回受影响的行数
 * @throws Exception
 */
int insertAll(List<T> list) throws Exception;

(4)规定批改办法的接口模型为:


/**
 *  批改一条记录
 * @param entity entity 中的 ID 不能为空,如果 ID 为空,其余条件不能为空,都为空不予执行
 * @return
 * @throws Exception
 */
boolean update(T entity) throws Exception;

利用这套根底的 API,前面我又基于 Redis、MongoDB、ElasticSearch、Hive、HBase 各封装了一套,以此来升高团队的学习老本,也大大晋升了程序的可控性,更不便对立监控。

2 搭建基础架构

2.1 Page

定义 Page 类的次要目标是为前面的分页查问对立返回后果做顶层反对,其次要性能包含分页逻辑的封装、分页数据。


package javax.core.common;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 分页对象,蕴含当前页数据及分页信息,如总记录数
 * 可能反对和 JQuery EasyUI 间接对接,可能反对和 BootStrap Table 间接对接
 */
public class Page<T> implements Serializable {

   private static final long serialVersionUID = 1L;
   private static final int DEFAULT_PAGE_SIZE = 20;

   private int pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数

   private long start; // 当前页第一条数据在 List 中的地位,从 0 开始

   private List<T> rows; // 当前页中寄存的记录,类型个别为 List

   private long total; // 总记录数

   /**
    * 构造方法,只结构空页
    */
   public Page() {this(0, 0, DEFAULT_PAGE_SIZE, new ArrayList<T>());
   }

   /**
    * 默认构造方法
    * 
    * @param start 本页数据在数据库中的起始地位
    * @param totalSize 数据库中总记录条数
    * @param pageSize 本页容量
    * @param rows 本页蕴含的数据
    */
   public Page(long start, long totalSize, int pageSize, List<T> rows) {
      this.pageSize = pageSize;
      this.start = start;
      this.total = totalSize;
      this.rows = rows;
   }

   /**
    * 取总记录数
    */
   public long getTotal() {return this.total;}
   
   public void setTotal(long total) {this.total = total;}

   /**
    * 取总页数
    */
   public long getTotalPageCount() {if (total % pageSize == 0){return total / pageSize;}else{return total / pageSize + 1;}
   }

   /**
    * 取每页数据容量
    */
   public int getPageSize() {return pageSize;}

   /**
    * 取当前页中的记录
    */
   public List<T> getRows() {return rows;}
   
   public void setRows(List<T> rows) {this.rows = rows;}

   /**
    * 取该页的以后页码,页码从 1 开始
    */
   public long getPageNo() {return start / pageSize + 1;}

   /**
    * 该页是否有下一页
    */
   public boolean hasNextPage() {return this.getPageNo() < this.getTotalPageCount() - 1;}

   /**
    * 该页是否有上一页
    */
   public boolean hasPreviousPage() {return this.getPageNo() > 1;
   }

   /**
    * 获取任意一页第一条数据在数据集中的地位,每页条数应用默认值
    * 
    * @see #getStartOfPage(int,int)
    */
   protected static int getStartOfPage(int pageNo) {return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
   }

   /**
    * 获取任意一页第一条数据在数据集中的地位
    * 
    * @param pageNo 从 1 开始的页号
    * @param pageSize 每页记录条数
    * @return 该页第一条数据
    */
   public static int getStartOfPage(int pageNo, int pageSize) {return (pageNo - 1) * pageSize;
   }

}

2.2 ResultMsg

ResultMsg 类次要是为对立返回后果做的顶层设计,次要包含状态码、后果阐明内容和返回数据。


package javax.core.common;

import java.io.Serializable;

// 底层设计
public class ResultMsg<T> implements Serializable {

   private static final long serialVersionUID = 2635002588308355785L;

   private int status; // 状态码,零碎的返回码
   private String msg;  // 状态码的解释
   private T data;  // 放任意后果

   public ResultMsg() {}
   
   public ResultMsg(int status) {this.status = status;}

   public ResultMsg(int status, String msg) {
      this.status = status;
      this.msg = msg;
   }
   
   public ResultMsg(int status, T data) {
      this.status = status;
      this.data = data;
   }

   public ResultMsg(int status, String msg, T data) {
      this.status = status;
      this.msg = msg;
      this.data = data;
   }

   public int getStatus() {return status;}

   public void setStatus(int status) {this.status = status;}

   public String getMsg() {return msg;}

   public void setMsg(String msg) {this.msg = msg;}

   public T getData() {return data;}

   public void setData(T data) {this.data = data;}

}

2.3 BaseDao

作为所有 BaseDao 长久化框架的顶层接口,次要定义增、删、改、查对立的参数列表和返回值。


package javax.core.common.jdbc;

import com.gupaoedu.vip.orm.framework.QueryRule;

import javax.core.common.Page;
import java.util.List;
import java.util.Map;

public interface BaseDao<T,PK> {
    /**
     * 获取列表
     * @param queryRule 查问条件
     * @return
     */
    List<T> select(QueryRule queryRule) throws Exception;

    /**
     * 获取分页后果
     * @param queryRule 查问条件
     * @param pageNo 页码
     * @param pageSize 每页条数
     * @return
     */
    Page<?> select(QueryRule queryRule,int pageNo,int pageSize) throws Exception;

    /**
     * 依据 SQL 获取列表
     * @param sql SQL 语句
     * @param args 参数
     * @return
     */
    List<Map<String,Object>> selectBySql(String sql, Object... args) throws Exception;

    /**
     * 依据 SQL 获取分页
     * @param sql SQL 语句
     * @param pageNo 页码
     * @param pageSize 每页条数
     * @return
     */
    Page<Map<String,Object>> selectBySqlToPage(String sql, Object [] param, int pageNo, int pageSize) throws Exception;

    /**
     * 删除一条记录
     * @param entity entity 中的 ID 不能为空,如果 ID 为空,其余条件不能为空,都为空则不予执行
     * @return
     */
    boolean delete(T entity) throws Exception;

    /**
     * 批量删除
     * @param list
     * @return 返回受影响的行数
     * @throws Exception
     */
    int deleteAll(List<T> list) throws Exception;

    /**
     * 插入一条记录并返回插入后的 ID
     * @param entity 只有 entity 不等于 null,就执行插入操作
     * @return
     */
    PK insertAndReturnId(T entity) throws Exception;

    /**
     * 插入一条记录自增 ID
     * @param entity
     * @return
     * @throws Exception
     */
    boolean insert(T entity) throws Exception;

    /**
     * 批量插入
     * @param list
     * @return 返回受影响的行数
     * @throws Exception
     */
    int insertAll(List<T> list) throws Exception;

    /**
     *  批改一条记录
     * @param entity entity 中的 ID 不能为空,如果 ID 为空,其余条件不能为空,都为空则不予执行
     * @return
     * @throws Exception
     */
    boolean update(T entity) throws Exception;
}

2.4 QueryRule

如果用 QueryRule 类来构建查问条件,用户在做条件查问时不须要手写 SQL,实现业务代码与 SQL 解耦。


package com.gupaoedu.vip.orm.framework;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * QueryRule,次要性能用于结构查问条件
 */
public final class QueryRule implements Serializable
{
   private static final long serialVersionUID = 1L;
   public static final int ASC_ORDER = 101;
   public static final int DESC_ORDER = 102;
   public static final int LIKE = 1;
   public static final int IN = 2;
   public static final int NOTIN = 3;
   public static final int BETWEEN = 4;
   public static final int EQ = 5;
   public static final int NOTEQ = 6;
   public static final int GT = 7;
   public static final int GE = 8;
   public static final int LT = 9;
   public static final int LE = 10;
   public static final int ISNULL = 11;
   public static final int ISNOTNULL = 12;
   public static final int ISEMPTY = 13;
   public static final int ISNOTEMPTY = 14;
   public static final int AND = 201;
   public static final int OR = 202;
   private List<Rule> ruleList = new ArrayList<Rule>();
   private List<QueryRule> queryRuleList = new ArrayList<QueryRule>();
   private String propertyName;

   private QueryRule() {}

   private QueryRule(String propertyName) {this.propertyName = propertyName;}

   public static QueryRule getInstance() {return new QueryRule();
   }
   
   /**
    * 增加升序规定
    * @param propertyName
    * @return
    */
   public QueryRule addAscOrder(String propertyName) {this.ruleList.add(new Rule(ASC_ORDER, propertyName));
      return this;
   }

   /**
    * 增加降序规定
    * @param propertyName
    * @return
    */
   public QueryRule addDescOrder(String propertyName) {this.ruleList.add(new Rule(DESC_ORDER, propertyName));
      return this;
   }

   public QueryRule andIsNull(String propertyName) {this.ruleList.add(new Rule(ISNULL, propertyName).setAndOr(AND));
      return this;
   }

   public QueryRule andIsNotNull(String propertyName) {this.ruleList.add(new Rule(ISNOTNULL, propertyName).setAndOr(AND));
      return this;
   }

   public QueryRule andIsEmpty(String propertyName) {this.ruleList.add(new Rule(ISEMPTY, propertyName).setAndOr(AND));
      return this;
   }

   public QueryRule andIsNotEmpty(String propertyName) {this.ruleList.add(new Rule(ISNOTEMPTY, propertyName).setAndOr(AND));
      return this;
   }

   public QueryRule andLike(String propertyName, Object value) {this.ruleList.add(new Rule(LIKE, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }

   public QueryRule andEqual(String propertyName, Object value) {this.ruleList.add(new Rule(EQ, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }

   public QueryRule andBetween(String propertyName, Object... values) {this.ruleList.add(new Rule(BETWEEN, propertyName, values).setAndOr(AND));
      return this;
   }

   public QueryRule andIn(String propertyName, List<Object> values) {this.ruleList.add(new Rule(IN, propertyName, new Object[] {values}).setAndOr(AND));
      return this;
   }

   public QueryRule andIn(String propertyName, Object... values) {this.ruleList.add(new Rule(IN, propertyName, values).setAndOr(AND));
      return this;
   }
   
   public QueryRule andNotIn(String propertyName, List<Object> values) {this.ruleList.add(new Rule(NOTIN, propertyName, new Object[] {values}).setAndOr(AND));
      return this;
   }

   public QueryRule orNotIn(String propertyName, Object... values) {this.ruleList.add(new Rule(NOTIN, propertyName, values).setAndOr(OR));
      return this;
   }
   

   public QueryRule andNotEqual(String propertyName, Object value) {this.ruleList.add(new Rule(NOTEQ, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }

   public QueryRule andGreaterThan(String propertyName, Object value) {this.ruleList.add(new Rule(GT, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }

   public QueryRule andGreaterEqual(String propertyName, Object value) {this.ruleList.add(new Rule(GE, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }

   public QueryRule andLessThan(String propertyName, Object value) {this.ruleList.add(new Rule(LT, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }

   public QueryRule andLessEqual(String propertyName, Object value) {this.ruleList.add(new Rule(LE, propertyName, new Object[] {value}).setAndOr(AND));
      return this;
   }
   
   
   public QueryRule orIsNull(String propertyName) {this.ruleList.add(new Rule(ISNULL, propertyName).setAndOr(OR));
      return this;
   }

   public QueryRule orIsNotNull(String propertyName) {this.ruleList.add(new Rule(ISNOTNULL, propertyName).setAndOr(OR));
      return this;
   }

   public QueryRule orIsEmpty(String propertyName) {this.ruleList.add(new Rule(ISEMPTY, propertyName).setAndOr(OR));
      return this;
   }

   public QueryRule orIsNotEmpty(String propertyName) {this.ruleList.add(new Rule(ISNOTEMPTY, propertyName).setAndOr(OR));
      return this;
   }

   public QueryRule orLike(String propertyName, Object value) {this.ruleList.add(new Rule(LIKE, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }

   public QueryRule orEqual(String propertyName, Object value) {this.ruleList.add(new Rule(EQ, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }

   public QueryRule orBetween(String propertyName, Object... values) {this.ruleList.add(new Rule(BETWEEN, propertyName, values).setAndOr(OR));
      return this;
   }

   public QueryRule orIn(String propertyName, List<Object> values) {this.ruleList.add(new Rule(IN, propertyName, new Object[] {values}).setAndOr(OR));
      return this;
   }

   public QueryRule orIn(String propertyName, Object... values) {this.ruleList.add(new Rule(IN, propertyName, values).setAndOr(OR));
      return this;
   }

   public QueryRule orNotEqual(String propertyName, Object value) {this.ruleList.add(new Rule(NOTEQ, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }

   public QueryRule orGreaterThan(String propertyName, Object value) {this.ruleList.add(new Rule(GT, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }

   public QueryRule orGreaterEqual(String propertyName, Object value) {this.ruleList.add(new Rule(GE, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }

   public QueryRule orLessThan(String propertyName, Object value) {this.ruleList.add(new Rule(LT, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }

   public QueryRule orLessEqual(String propertyName, Object value) {this.ruleList.add(new Rule(LE, propertyName, new Object[] {value}).setAndOr(OR));
      return this;
   }
   

   public List<Rule> getRuleList() {return this.ruleList;}

   public List<QueryRule> getQueryRuleList() {return this.queryRuleList;}

   public String getPropertyName() {return this.propertyName;}

   protected class Rule implements Serializable {
      private static final long serialVersionUID = 1L;
      private int type;  // 规定的类型
      private String property_name;
      private Object[] values;
      private int andOr = AND;

      public Rule(int paramInt, String paramString) {
         this.property_name = paramString;
         this.type = paramInt;
      }

      public Rule(int paramInt, String paramString,
            Object[] paramArrayOfObject) {
         this.property_name = paramString;
         this.values = paramArrayOfObject;
         this.type = paramInt;
      }
      
      public Rule setAndOr(int andOr){
         this.andOr = andOr;
         return this;
      }
      
      public int getAndOr(){return this.andOr;}

      public Object[] getValues() {return this.values;}

      public int getType() {return this.type;}

      public String getPropertyName() {return this.property_name;}
   }
}

2.5 Order

Order 类次要用于封装排序规定,代码如下:


package com.gupaoedu.vip.orm.framework;

/**
 * SQL 排序组件
 */
public class Order {
   private boolean ascending; // 升序还是降序
   private String propertyName; // 哪个字段升序,哪个字段降序
   
   public String toString() {return propertyName + '' + (ascending ?"asc":"desc");
   }

   /**
    * Constructor for Order.
    */
   protected Order(String propertyName, boolean ascending) {
      this.propertyName = propertyName;
      this.ascending = ascending;
   }

   /**
    * Ascending order
    *
    * @param propertyName
    * @return Order
    */
   public static Order asc(String propertyName) {return new Order(propertyName, true);
   }

   /**
    * Descending order
    *
    * @param propertyName
    * @return Order
    */
   public static Order desc(String propertyName) {return new Order(propertyName, false);
   }
}

因篇幅起因,具体的操作类下一篇持续。

关注微信公众号『Tom 弹架构』回复“Spring”可获取残缺源码。

本文为“Tom 弹架构”原创,转载请注明出处。技术在于分享,我分享我高兴!如果您有任何倡议也可留言评论或私信,您的反对是我保持创作的能源。关注微信公众号『Tom 弹架构』可获取更多技术干货!

原创不易,保持很酷,都看到这里了,小伙伴记得点赞、珍藏、在看,一键三连加关注!如果你感觉内容太干,能够分享转发给敌人滋润滋润!

正文完
 0