hsweb 的系列学习——hsweb-easy-orm 分析

1,177 阅读12分钟
原文链接: zhuanlan.zhihu.com

对于此orm框架的封装,首先要看的便是:hsweb-easy-orm-core

整体思路:因为是为动态表单设计的orm框架,所以要有为映射包装的PO类和反映到表元素的元数据类MetaData,

以及对这些bean进行操作的各种周边(最多的也就是curd的细节分拆)


一,映射包装的PO类

列的设定

我们的curd操作的基本元素首先是表,而我们操作的铁定就是po类,表中的基本元素首先是列,列包含两个属性,名字和字段类型

那么对于这个orm框架中的体现就是:

package org.hsweb.ezorm.core.param;
/**
 * @author zhouhao
 * @since 1.1
 */
public class Column {
    private String name;
    private String type;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public Column type(String type) {
        this.type = type;
        return this;
    }
    public static Column build(String name) {
        Column column = new Column();
        column.setName(name);
        return column;
    }
}

此处单独定义了ColumnType,暂时未见使用

package org.hsweb.ezorm.core.param;
/**
 * @author zhouhao
 * @since 1.1
 */
public interface ColumnType {
    String def = "";
}

SQL的参数设定

对列的一系列的操作其实是操作字段及所涉及的数据,那么我们所要设定的地方有:

通过参考一个sql语句可以知道,操作一个字段往往会涉及到where后面的条件,以及要处理的字段如in{...}不处理的字段 not in{...} 具体代码里面的体现就是:

首先对条件类型的设定:

/*
 * Copyright 2016 http://github.com/hs-web
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.hsweb.ezorm.core.param;
/**
 * 查询条件类型,用于动态指定查询条件
 *
 * @author zhouhao
 * @since 1.0
 */
public interface TermType {
    /**
     * ==
     *
     * @since 1.0
     */
    String eq      = "eq";
    /**
     * !=
     *
     * @since 1.0
     */
    String not     = "not";
    /**
     * like
     *
     * @since 1.0
     */
    String like    = "like";
    /**
     * not like
     *
     * @since 1.0
     */
    String nlike   = "nlike";
    /**
     * >
     *
     * @since 1.0
     */
    String gt      = "gt";
    /**
     * <
     *
     * @since 1.0
     */
    String lt      = "lt";
    /**
     * >=
     *
     * @since 1.0
     */
    String gte     = "gte";
    /**
     * <=
     *
     * @since 1.0
     */
    String lte     = "lte";
    /**
     * in
     *
     * @since 1.0
     */
    String in      = "in";
    /**
     * notin
     *
     * @since 1.0
     */
    String nin     = "nin";
    /**
     * =''
     *
     * @since 1.0
     */
    String empty   = "empty";
    /**
     * !=''
     *
     * @since 1.0
     */
    String nempty  = "nempty";
    /**
     * is null
     *
     * @since 1.0
     */
    String isnull  = "isnull";
    /**
     * not null
     *
     * @since 1.0
     */
    String notnull = "notnull";
    /**
     * between
     *
     * @since 1.0
     */
    String btw     = "btw";
    /**
     * not between
     *
     * @since 1.0
     */
    String nbtw    = "nbtw";
    /**
     * 此类型将直接执行sql.在类型是从客户端参数中获取的场景中,应该屏蔽此类型
     *
     * @see SqlTerm
     * @since 1.0
     * @deprecated 此属性已弃用,如果想直接拼接sql,请使用 {@link SqlTerm}
     */
    @Deprecated
    String func = "func";
}

其次对于条件的设定:

package org.hsweb.ezorm.core.param;
import java.util.LinkedList;
import java.util.List;
/**
 * 执行条件
 */
public class Term implements Cloneable {
    /**
     * 字段
     */
    private String column;
    /**
     * 值
     */
    private Object value;
    /**
     * 链接类型
     */
    private Type type = Type.and;
    /**
     * 条件类型
     */
    private String termType = TermType.eq;
    /**
     * 嵌套的条件
     */
    private List<Term> terms = new LinkedList<>();
    public Term or(String term, Object value) {
        return or(term, TermType.eq,value);
    }
    public Term and(String term, Object value) {
        return and(term, TermType.eq,value);
    }
    public Term or(String term, String termType, Object value) {
        Term queryTerm = new Term();
        queryTerm.setTermType(termType);
        queryTerm.setColumn(term);
        queryTerm.setValue(value);
        queryTerm.setType(Type.or);
        terms.add(queryTerm);
        return this;
    }
    public Term and(String term, String termType, Object value) {
        Term queryTerm = new Term();
        queryTerm.setTermType(termType);
        queryTerm.setColumn(term);
        queryTerm.setValue(value);
        queryTerm.setType(Type.and);
        terms.add(queryTerm);
        return this;
    }
    public Term nest() {
        return nest(null, null);
    }
    public Term orNest() {
        return orNest(null, null);
    }
    public Term nest(String term, Object value) {
        Term queryTerm = new Term();
        queryTerm.setType(Type.and);
        queryTerm.setColumn(term);
        queryTerm.setValue(value);
        terms.add(queryTerm);
        return queryTerm;
    }
    public Term orNest(String term, Object value) {
        Term queryTerm = new Term();
        queryTerm.setType(Type.or);
        queryTerm.setColumn(term);
        queryTerm.setValue(value);
        terms.add(queryTerm);
        return queryTerm;
    }
    public String getColumn() {
        return column;
    }
    public void setColumn(String column) {
        if (column == null) return;
        if (column.contains("$")) {
            String tmp[] = column.split("[$]");
            setTermType(tmp[1]);
            column = tmp[0];
        }
        this.column = column;
    }
    public Object getValue() {
        return value;
    }
    public void setValue(Object value) {
        this.value = value;
    }
    public Type getType() {
        return type;
    }
    public void setType(Type type) {
        this.type = type;
    }
    public String getTermType() {
        return termType.toLowerCase();
    }
    public void setTermType(String termType) {
        this.termType = termType;
    }
    public List<Term> getTerms() {
        return terms;
    }
    public void setTerms(List<Term> terms) {
        this.terms = terms;
    }
    public Term addTerm(Term term) {
        terms.add(term);
        return this;
    }
    @Override
    public Term clone() {
        Term term = new Term();
        term.setColumn(column);
        term.setValue(value);
        term.setTermType(termType);
        term.setType(type);
        terms.forEach(t -> term.addTerm(t.clone()));
        return term;
    }
    public enum Type {
        or, and;
        public static Type fromString(String str) {
            try {
                return Type.valueOf(str.toLowerCase());
            } catch (Exception e) {
                return and;
            }
        }
    }
}

将各种条件用po来表达出来并进行封装

最后对于SQL参数对象的设定:

package org.hsweb.ezorm.core.param;
import java.util.*;
import java.util.stream.Collectors;
/**
 * SQL参数对象
 *
 * @author zhouhao
 * @since 1.0
 */
public class Param implements Cloneable {
    /**
     * 条件
     */
    protected List<Term> terms = new LinkedList<>();
    /**
     * 指定要处理的字段
     */
    protected Set<String> includes = new LinkedHashSet<>();
    /**
     * 指定不处理的字段
     */
    protected Set<String> excludes = new LinkedHashSet<>();
    public <T extends Param> T or(String column, Object value) {
        return or(column, TermType.eq, value);
    }
    public <T extends Param> T and(String column, Object value) {
        return and(column, TermType.eq, value);
    }
    public <T extends Param> T or(String column, String termType, Object value) {
        Term term = new Term();
        term.setTermType(termType);
        term.setColumn(column);
        term.setValue(value);
        term.setType(Term.Type.or);
        terms.add(term);
        return (T) this;
    }
    public <T extends Param> T and(String column, String termType, Object value) {
        Term term = new Term();
        term.setTermType(termType);
        term.setColumn(column);
        term.setValue(value);
        term.setType(Term.Type.and);
        terms.add(term);
        return (T) this;
    }
    public Term nest() {
        return nest(null, null);
    }
    public Term orNest() {
        return orNest(null, null);
    }
    public Term nest(String termString, Object value) {
        Term term = new Term();
        term.setColumn(termString);
        term.setValue(value);
        term.setType(Term.Type.and);
        terms.add(term);
        return term;
    }
    public Term orNest(String termString, Object value) {
        Term term = new Term();
        term.setColumn(termString);
        term.setValue(value);
        term.setType(Term.Type.or);
        terms.add(term);
        return term;
    }
    public <T extends Param> T includes(String... fields) {
        includes.addAll(Arrays.asList(fields));
        return (T) this;
    }
    public <T extends Param> T excludes(String... fields) {
        excludes.addAll(Arrays.asList(fields));
        includes.removeAll(Arrays.asList(fields));
        return (T) this;
    }
    public <T extends Param> T where(String key, Object value) {
        and(key, value);
        return (T) this;
    }
    public <T extends Param> T where(String key, String termType, Object value) {
        and(key, termType, value);
        return (T) this;
    }
    public Set<String> getIncludes() {
        if (includes == null) includes = new LinkedHashSet<>();
        return includes;
    }
    public Set<String> getExcludes() {
        if (excludes == null) excludes = new LinkedHashSet<>();
        return excludes;
    }
    public void setIncludes(Set<String> includes) {
        this.includes = includes;
    }
    public void setExcludes(Set<String> excludes) {
        this.excludes = excludes;
    }
    public List<Term> getTerms() {
        return terms;
    }
    public void setTerms(List<Term> terms) {
        this.terms = terms;
    }
    public <T extends Param> T addTerm(Term term) {
        terms.add(term);
        return (T) this;
    }
    @Override
    public Param clone() {
        Param param = new Param();
        param.setExcludes(new LinkedHashSet<>(excludes));
        param.setIncludes(new LinkedHashSet<>(includes));
        List<Term> terms = this.terms.stream().map(term -> term.clone()).collect(Collectors.toList());
        param.setTerms(terms);
        return param;
    }
}

这里通过LinkedList 来将条件都包装到一起 ,通过LinkedHashSet来包装要处理的字段

由Param衍生出来的专门对查询(如分页)和更新参数的额外封装:

&amp;amp;amp;amp;lt;img src="https://pic3.zhimg.com/v2-01b95d6278dacbc0b1229db005101492_b.png" data-rawwidth="330" data-rawheight="122" class="content_image" width="330"&amp;amp;amp;amp;gt;

查询往往会涉及到排序,这里对排序先做下封装:

package org.hsweb.ezorm.core.param;
/**
 * 排序
 *
 * @author zhouhao
 * @since 1.0
 */
public class Sort extends Column {
    private String order = "asc";
    private transient QueryParam queryParam;
    public String getOrder() {
        return order;
    }
    public void setOrder(String order) {
        this.order = order;
    }
    public Sort() {
    }
    public Sort(QueryParam queryParam, String name) {
        this.queryParam = queryParam;
        setName(name);
    }
    public QueryParam asc() {
        this.order = "asc";
        return queryParam;
    }
    public QueryParam desc() {
        this.order = "desc";
        return queryParam;
    }
    public Sort and(String field) {
        return queryParam.orderBy(field);
    }
    @Override
    public int hashCode() {
        return String.valueOf(getName()).concat(order).hashCode();
    }
    @Override
    public boolean equals(Object obj) {
        return obj != null && this.hashCode() == obj.hashCode();
    }
}

QueryParam: 排序字段同样LinkedList存储

package org.hsweb.ezorm.core.param;
import java.io.Serializable;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * Created by 浩 on 2016-01-16 0016.
 */
public class QueryParam extends Param implements Serializable, Cloneable {
    private static final long serialVersionUID = 7941767360194797891L;
    /**
     * 是否进行分页,默认为true
     */
    private boolean paging = true;
    /**
     * 第几页 从0开始
     */
    private int pageIndex = 0;
    /**
     * 每页显示记录条数
     */
    private int pageSize = 25;
    /**
     * 排序字段
     *
     * @since 1.0
     */
    private List<Sort> sorts = new LinkedList<>();
    private boolean forUpdate = false;
    public QueryParam select(String... fields) {
        return this.includes(fields);
    }
    public Sort orderBy(String column) {
        Sort sort = new Sort(this, column);
        sorts.add(sort);
        return sort;
    }
    public <Q extends QueryParam> Q doPaging(int pageIndex) {
        this.pageIndex = pageIndex;
        this.paging = true;
        return (Q) this;
    }
    public <Q extends QueryParam> Q doPaging(int pageIndex, int pageSize) {
        this.pageIndex = pageIndex;
        this.pageSize = pageSize;
        this.paging = true;
        return (Q) this;
    }
    public <Q extends QueryParam> Q rePaging(int total) {
        paging = true;
        // 当前页没有数据后跳转到最后一页
        if (this.getPageIndex() != 0 && (pageIndex * pageSize) >= total) {
            int tmp = total / this.getPageSize();
            pageIndex = total % this.getPageSize() == 0 ? tmp - 1 : tmp;
        }
        return (Q) this;
    }
    public boolean isPaging() {
        return paging;
    }
    public void setPaging(boolean paging) {
        this.paging = paging;
    }
    public int getPageIndex() {
        return pageIndex;
    }
    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public List<Sort> getSorts() {
        return sorts;
    }
    public void setSorts(List<Sort> sorts) {
        this.sorts = sorts;
    }
    public void setForUpdate(boolean forUpdate) {
        this.forUpdate = forUpdate;
    }
    public boolean isForUpdate() {
        return forUpdate;
    }
    @Override
    public QueryParam clone() {
        QueryParam sqlParam = new QueryParam();
        sqlParam.setExcludes(new LinkedHashSet<>(excludes));
        sqlParam.setIncludes(new LinkedHashSet<>(includes));
        List<Term> terms = this.terms.stream().map(Term::clone).collect(Collectors.toList());
        sqlParam.setTerms(terms);
        sqlParam.setPageIndex(pageIndex);
        sqlParam.setPageSize(pageSize);
        sqlParam.setPaging(paging);
        sqlParam.setSorts(sorts);
        sqlParam.setForUpdate(forUpdate);
        return sqlParam;
    }
}

UpdateParam:

package org.hsweb.ezorm.core.param;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
 * Created by zhouhao on 16-4-19.
 */
public class UpdateParam<T> extends Param {
    private T data;
    public UpdateParam() {
    }
    public UpdateParam(T data) {
        this.data = data;
    }
    public <C extends UpdateParam<T>> C set(T data) {
        this.data = data;
        return (C) this;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    @Override
    public UpdateParam clone() {
        UpdateParam<T> param = new UpdateParam<>();
        param.setData(data);
        param.setExcludes(new LinkedHashSet<>(excludes));
        param.setIncludes(new LinkedHashSet<>(includes));
        List<Term> terms = this.terms.stream().map(Term::clone).collect(Collectors.toList());
        param.setTerms(terms);
        return param;
    }
}

对更新数据map类型包装的数据做扩展:

package org.hsweb.ezorm.core.param;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by zhouhao on 16-4-21.
 */
public class UpdateMapParam extends UpdateParam<Map<String, Object>> {
    public UpdateMapParam() {
        this(new HashMap<>());
    }
    public UpdateMapParam(Map<String, Object> data) {
        setData(data);
    }
    public UpdateMapParam set(String key, Object value) {
        this.getData().put(key, value);
        return this;
    }
}

表插入数据的封装

InsertParam:

package org.hsweb.ezorm.core.param;
public class InsertParam<T> {
    private T data;
    public InsertParam() {
    }
    public InsertParam(T data) {
        this.data = data;
    }
    public InsertParam<T> value(T data) {
        this.data = data;
        return this;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public static <T> InsertParam<T> build(T data) {
        return new InsertParam<>(data);
    }
}

和更新针对map数据类型衍生一样:

package org.hsweb.ezorm.core.param;
import java.util.HashMap;
import java.util.Map;
public class InsertParamMapParam extends InsertParam<Map<String, Object>> {
    @Override
    public Map<String, Object> getData() {
        if (super.getData() == null) setData(new HashMap<>());
        return super.getData();
    }
    public InsertParamMapParam value(String property, Object value) {
        getData().put(property, value);
        return this;
    }
    public InsertParamMapParam values(Map<String, Object> values) {
        getData().putAll(values);
        return this;
    }
}

二,反映到表元素的元数据类MetaData

PO转表元素数据

OptionConverter:选项映射器

package org.hsweb.ezorm.core;
/**
 * 选项映射器,当一个字段持有映射器时.
 * <ul>
 * <li>
 * 在查询时,会追加一个名为{@link OptionConverter#getFieldName()}的字段为{@link OptionConverter#converterValue(Object)} 的值
 * </li>
 * <li>
 * 在修改或者插入时,验证器会首先通过 {@link OptionConverter#converterData(Object)}来获取一个结果.
 * 如果返回null.则调用{@link OptionConverter#converterValue(Object)} ,并将值放入数据库.
 * 如果继续返回null,则会抛出验证器异常,提示值不再选项范围中
 * </li>
 * </ul>
 * Created by zhouhao on 16-6-4.
 */
public interface OptionConverter {
    /**
     * 获取所有选项
     *
     * @return 选项
     */
    Object getOptions();
    /**
     * 获取转换后的字段名称
     *
     * @return 转换后的字段名称
     */
    String getFieldName();
    /**
     * 将提交的数据,转换为目标数据
     *
     * @param value 提交的数据
     * @return 转换结果
     */
    Object converterData(Object value);
    /**
     * 将数据库的数据,转换为目标数据
     *
     * @param data 数据库数据
     * @return 转换结果
     */
    Object converterValue(Object data);
}

PropertyWrapper:属性包装

package org.hsweb.ezorm.core;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
public interface PropertyWrapper extends Serializable {
    <T> T getValue();
    String toString();
    int toInt();
    double toDouble();
    boolean isTrue();
    Date toDate();
    Date toDate(String format);
    Map<String, Object> toMap();
    List<Map> toList();
    <T> T toBean(Class<T> type);
    <T> List<T> toBeanList(Class<T> type);
    boolean isNullOrEmpty();
    boolean valueTypeOf(Class<?> type);
}

对PropertyWrapper的简单实现:

package org.hsweb.ezorm.core;
import com.alibaba.fastjson.JSON;
import org.hsweb.commons.ClassUtils;
import org.hsweb.commons.DateTimeUtils;
import org.hsweb.commons.StringUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * Created by zhouhao on 16-6-4.
 */
public class SimplePropertyWrapper implements PropertyWrapper {
    private Object value;
    public SimplePropertyWrapper(Object value) {
        this.value = value;
    }
    @Override
    public <T> T getValue() {
        return (T) value;
    }
    @Override
    public int toInt() {
        return StringUtils.toInt(value);
    }
    @Override
    public double toDouble() {
        return StringUtils.toDouble(value);
    }
    @Override
    public boolean isTrue() {
        return StringUtils.isTrue(value);
    }
    @Override
    public Date toDate() {
        if (value instanceof Date) return ((Date) value);
        return DateTimeUtils.formatUnknownString2Date(toString());
    }
    @Override
    public Date toDate(String format) {
        if (value instanceof Date) return ((Date) value);
        return DateTimeUtils.formatDateString(toString(), format);
    }
    @Override
    public <T> T toBean(Class<T> type) {
        if (valueTypeOf(type)) return ((T) getValue());
        return JSON.parseObject(toString(), type);
    }
    @Override
    public List<Map> toList() {
        return toBeanList(Map.class);
    }
    @Override
    public Map<String, Object> toMap() {
        return toBean(Map.class);
    }
    @Override
    public <T> List<T> toBeanList(Class<T> type) {
        if (getValue() instanceof List) return ((List) getValue());
        return JSON.parseArray(toString(), type);
    }
    @Override
    public boolean isNullOrEmpty() {
        return StringUtils.isNullOrEmpty(value);
    }
    @Override
    public boolean valueTypeOf(Class<?> type) {
        if (value == null) return false;
        return ClassUtils.instanceOf(value.getClass(), type);
    }
    @Override
    public String toString() {
        return String.valueOf(value);
    }
}

ValueConverter:数据转换

package org.hsweb.ezorm.core;
public interface ValueConverter {
    Object getData(Object value);
    Object getValue(Object data);
}

由其所衍生的类:

&amp;amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-4ec05f2a743ce8c0e17e13b5fd9ba621_b.png" data-rawwidth="408" data-rawheight="366" class="content_image" width="408"&amp;amp;amp;amp;gt;

&amp;amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-812d845b09f5ce8ac0f400050b6de9c9_b.png" data-rawwidth="330" data-rawheight="259" class="content_image" width="330"&amp;amp;amp;amp;gt;这里只看其中一两个即可: 这里只看其中一两个即可:

ClobValueConverter:

package org.hsweb.ezorm.rdb.meta.converter;
import org.hsweb.ezorm.core.ValueConverter;
import java.io.Reader;
import java.sql.Clob;
public class ClobValueConverter implements ValueConverter {
    @Override
    public Object getData(Object value) {
        return value;
    }
    @Override
    public Object getValue(Object data) {
        if (data instanceof Clob) {
            Clob clobData = ((Clob) data);
            try (Reader reader = clobData.getCharacterStream()) {
                char[] chars = new char[(int) clobData.length()];
                reader.read(chars);
                data = new String(chars);
            } catch (Exception ignored) {
            }
        }
        return data;
    }
}

BooleanValueConverter:

package org.hsweb.ezorm.rdb.meta.converter;
import org.hsweb.ezorm.core.ValueConverter;
public class BooleanValueConverter implements ValueConverter {
    @Override
    public Object getData(Object value) {
        return value;
    }
    @Override
    public Object getValue(Object data) {
        if (null == data) return false;
        if (data instanceof Boolean) return data;
        return "1".equals(String.valueOf(data)) || "true".equals(String.valueOf(data));
    }
}

对象包装ObjectWrapper:

/*
 * Copyright 2016 http://github.com/hs-web
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.hsweb.ezorm.core;
import java.util.List;
/**
 * 对象包装器,在执行查询时,通过包装器对查询结果进行初始化
 *
 * @author zhouhao
 * @since 1.0
 */
public interface ObjectWrapper<T> {
    /**
     * 执行初始化,在sql执行后,包装结果前,将调用此方法,传入查询的列
     *
     * @param columns 列集合
     */
    default void setUp(List<String> columns) {
    }
    <C extends T> Class<C> getType();
    /**
     * 创建对象实例
     *
     * @return 对象实例
     */
    T newInstance();
    /**
     * 向实例中填充一个属性值
     *
     * @param instance 实例对象
     * @param index    当前实例的索引
     * @param attr     属性名称
     * @param value    属性值
     */
    void wrapper(T instance, int index, String attr, Object value);
    /**
     * 当一个实例被填充完成后调用,已进行其他操作
     *
     * @param instance 实例对象
     */
    void done(T instance);
}

其衍生的类:

&amp;amp;amp;amp;lt;img src="https://pic4.zhimg.com/v2-33ef1b86b40fb30c78a355163beb83a3_b.png" data-rawwidth="856" data-rawheight="629" class="origin_image zh-lightbox-thumb" width="856" data-original="https://pic4.zhimg.com/v2-33ef1b86b40fb30c78a355163beb83a3_r.png"&amp;amp;amp;amp;gt;

触发:Trigger:

package org.hsweb.ezorm.core;


import java.util.Map;

public interface Trigger {

    void execute(Map<String, Object> context);

    String select_before       = "select.before";
    String select_wrapper_each = "select.wrapper.each";
    String select_wrapper_done = "select.wrapper.done";
    String select_done         = "select.done";
    String insert_before       = "insert.before";
    String insert_done         = "insert.done";
    String update_before       = "update.before";
    String update_done         = "update.done";
    String delete_before       = "delete.before";
    String delete_done         = "delete.done";
}

定义TableMetaData

package org.hsweb.ezorm.core.meta;
import org.hsweb.ezorm.core.ObjectWrapper;
import org.hsweb.ezorm.core.PropertyWrapper;
import org.hsweb.ezorm.core.Trigger;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
 * @author zhouhao
 */
public interface TableMetaData extends Serializable {
    String getName();
    String getComment();
    String getAlias();
    <T extends DatabaseMetaData> T getDatabaseMetaData();
    <T extends ColumnMetaData> Set<T> getColumns();
    <T extends ColumnMetaData> T getColumn(String name);
    <T extends ColumnMetaData> T findColumn(String name);
    <T> ObjectWrapper<T> getObjectWrapper();
    PropertyWrapper getProperty(String property);
    PropertyWrapper getProperty(String property, Object defaultValue);
    PropertyWrapper setProperty(String property, Object value);
    void on(String name, Trigger trigger);
    void on(String name, Map<String, Object> triggerContext);
    boolean triggerIsSupport(String name);
}

里面包含有表名字,注释,别名,然后就是表所属数据库的元数据信息,表包含列的元数据信息,以及对象的包装,属性的包装,见上面对象包装,属性的包装,以及通过on()方法对Trigger使用


定义DatabaseMetaData

package org.hsweb.ezorm.core.meta;
import org.hsweb.ezorm.core.ObjectWrapperFactory;
import org.hsweb.ezorm.core.ValidatorFactory;
public interface DatabaseMetaData {
    ObjectWrapperFactory getObjectWrapperFactory();
    ValidatorFactory getValidatorFactory();
    <T extends TableMetaData> T getTableMetaData(String name);
}

个人认为,其实这里表达的就是衔接的意思,ObjectWrapper和TableMetaData信息的对应(等以后有新的理解了再来修改的)

ValidatorFactory

package org.hsweb.ezorm.core;
import org.hsweb.ezorm.core.meta.TableMetaData;
public interface ValidatorFactory {
    Validator createValidator(TableMetaData tableMetaData);//源码里暂时未使用到该接口方法定义
}

Validator其实是对INSERT, UPDATE操作和相应数据进行下验证

package org.hsweb.ezorm.core;
public interface Validator {
    boolean validate(Object data, Operation operation);
    enum Operation {
        INSERT, UPDATE
    }
}

定义ColumnMetaData

package org.hsweb.ezorm.core.meta;
import org.hsweb.ezorm.core.OptionConverter;
import org.hsweb.ezorm.core.PropertyWrapper;
import org.hsweb.ezorm.core.ValueConverter;
import java.io.Serializable;
import java.util.Set;
public interface ColumnMetaData extends Serializable, Cloneable {
    String getName();
    String getAlias();
    String getComment();
    Class getJavaType();
    <T extends TableMetaData> T getTableMetaData();
    ValueConverter getValueConverter();
    OptionConverter getOptionConverter();
    Set<String> getValidator();
    PropertyWrapper getProperty(String property);
    PropertyWrapper getProperty(String property, Object defaultValue);
    PropertyWrapper setProperty(String property, Object value);
    <T extends ColumnMetaData> T clone();
}

里面包含有表名字,注释,别名,然后就是列所属表的元数据信息,表包含列的元数据信息,以及值的转换,选项的转换,属性的包装,见上面数据转换,属性的包装小节,以及通过clone()方法返回相应的ColumnMetaData的实现。




因篇幅有点长,增删改查等相关操作在下一篇中说
原文链接:hsweb的系列学习——hsweb-easy-orm分析