Search in sources :

Example 1 with NutMappingField

use of org.nutz.dao.impl.entity.field.NutMappingField in project nutz by nutzam.

the class NutStatement method getAdapterBy.

protected ValueAdaptor getAdapterBy(Object value) {
    if (value == null)
        return Jdbcs.Adaptor.asNull;
    if (expert == null)
        return Jdbcs.getAdaptorBy(value);
    NutMappingField mf = new NutMappingField(entity);
    mf.setType(value.getClass());
    Jdbcs.guessEntityFieldColumnType(mf);
    return expert.getAdaptor(mf);
}
Also used : NutMappingField(org.nutz.dao.impl.entity.field.NutMappingField)

Example 2 with NutMappingField

use of org.nutz.dao.impl.entity.field.NutMappingField in project nutz by nutzam.

the class EntityHolder method makeEntity.

@SuppressWarnings({ "rawtypes", "unchecked" })
public <T extends Map<String, ?>> Entity<T> makeEntity(String tableName, T map) {
    final NutEntity<T> en = new NutEntity(map.getClass());
    en.setTableName(tableName);
    en.setViewName(tableName);
    boolean check = false;
    for (Entry<String, ?> entry : map.entrySet()) {
        String key = entry.getKey();
        // 是实体补充描述吗?
        if (key.startsWith("#")) {
            en.getMetas().put(key.substring(1), entry.getValue().toString());
            continue;
        } else // 以 "." 开头的字段,不是实体字段
        if (key.startsWith(".")) {
            continue;
        }
        // 是实体字段
        Object value = entry.getValue();
        Mirror<?> mirror = Mirror.me(value);
        NutMappingField ef = new NutMappingField(en);
        if (key.startsWith("+")) {
            ef.setAsAutoIncreasement();
            if (mirror != null && mirror.isIntLike())
                ef.setAsId();
            key = key.substring(1);
        }
        if (key.startsWith("!")) {
            ef.setAsNotNull();
            key = key.substring(1);
        }
        if (key.startsWith("*")) {
            key = key.substring(1);
            if (mirror != null && mirror.isIntLike())
                ef.setAsId();
            else
                ef.setAsName();
        }
        ef.setName(key);
        ef.setType(null == value ? Object.class : value.getClass());
        ef.setColumnName(key);
        // 猜测一下数据库类型
        Jdbcs.guessEntityFieldColumnType(ef);
        ef.setAdaptor(expert.getAdaptor(ef));
        if (mirror != null)
            ef.setType(mirror.getType());
        // 这里比较纠结,回设的时候应该用什么呢?
        ef.setInjecting(new InjectToMap(key));
        ef.setEjecting(new EjectFromMap(entry.getKey()));
        if (ef.isAutoIncreasement() && ef.isId() && expert.isSupportAutoIncrement() && !expert.isSupportGeneratedKeys()) {
            en.addAfterInsertMacro(expert.fetchPojoId(en, ef));
        }
        en.addMappingField(ef);
        if (mirror != null && !check)
            check = mirror.isEnum();
    }
    en.checkCompositeFields(null);
    // 最后在数据库中验证一下实体各个字段
    if (check)
        connCallback.invoke(new ConnCallback() {

            public void invoke(Connection conn) throws Exception {
                expert.setupEntityField(conn, en);
            }
        });
    // 搞定返回
    return en;
}
Also used : ConnCallback(org.nutz.dao.ConnCallback) NutEntity(org.nutz.dao.impl.entity.NutEntity) Connection(java.sql.Connection) NutMappingField(org.nutz.dao.impl.entity.field.NutMappingField) InjectToMap(org.nutz.lang.inject.InjectToMap) EjectFromMap(org.nutz.lang.eject.EjectFromMap)

Example 3 with NutMappingField

use of org.nutz.dao.impl.entity.field.NutMappingField in project nutz by nutzam.

the class AnnotationEntityMaker method make.

public <T> Entity<T> make(Class<T> type) {
    NutEntity<T> en = _createNutEntity(type);
    TableInfo ti = _createTableInfo(type);
    // 全局
    if (null != expert.getConf()) {
        for (String key : expert.getConf().keySet()) en.getMetas().put(key, expert.getConf().get(key));
    }
    // 当前表
    if (null != ti.annMeta) {
        Map<String, Object> map = Lang.map(ti.annMeta.value());
        for (Entry<String, Object> entry : map.entrySet()) {
            en.getMetas().put(entry.getKey(), entry.getValue().toString());
        }
    }
    /*
         * 获得表名以及视图名称及注释
         */
    String tableName = null;
    if (null == ti.annTable) {
        tableName = Daos.getTableNameMaker().make(type);
        if (null == ti.annView)
            log.warnf("No @Table found, fallback to use table name='%s' for type '%s'", tableName, type.getName());
    } else {
        tableName = ti.annTable.value().isEmpty() ? Daos.getTableNameMaker().make(type) : ti.annTable.value();
        if (!ti.annTable.prefix().isEmpty()) {
            tableName = ti.annTable.prefix() + tableName;
        }
        if (!ti.annTable.suffix().isEmpty()) {
            tableName = tableName + ti.annTable.suffix();
        }
    }
    String viewName = null;
    if (null == ti.annView) {
        viewName = tableName;
    } else {
        viewName = ti.annView.value().isEmpty() ? Daos.getViewNameMaker().make(type) : ti.annView.value();
        if (!ti.annView.prefix().isEmpty()) {
            viewName = ti.annView.prefix() + viewName;
        }
        if (!ti.annView.suffix().isEmpty()) {
            viewName = viewName + ti.annView.suffix();
        }
    }
    en.setTableName(tableName);
    en.setViewName(viewName);
    boolean hasTableComment = null != ti.tableComment;
    String tableComment = hasTableComment ? Strings.isBlank(ti.tableComment.value()) ? type.getName() : ti.tableComment.value() : null;
    en.setHasTableComment(hasTableComment);
    en.setTableComment(tableComment);
    /*
         * 获取所有的数据库字段
         */
    // 字段里面是不是有声明过 '@Column' @Comment
    boolean shouldUseColumn = false;
    boolean hasColumnComment = false;
    for (Field field : en.getMirror().getFields()) {
        if (shouldUseColumn && hasColumnComment) {
            break;
        }
        if (!shouldUseColumn && null != field.getAnnotation(Column.class)) {
            shouldUseColumn = true;
        }
        if (!hasColumnComment && null != field.getAnnotation(Comment.class)) {
            hasColumnComment = true;
        }
    }
    en.setHasColumnComment(hasColumnComment);
    /*
         * 循环获取实体字段
         */
    List<MappingInfo> infos = new ArrayList<MappingInfo>();
    List<LinkInfo> ones = new ArrayList<LinkInfo>();
    List<LinkInfo> manys = new ArrayList<LinkInfo>();
    List<LinkInfo> manymanys = new ArrayList<LinkInfo>();
    String[] _tmp = ti.annPK == null ? null : ti.annPK.value();
    List<String> pks = _tmp == null ? new ArrayList<String>() : Arrays.asList(_tmp);
    // 循环所有的字段,查找有没有数据库映射字段
    for (Field field : en.getMirror().getFields()) {
        // '@One'
        if (null != field.getAnnotation(One.class)) {
            ones.add(_Infos.createLinkInfo(field));
        } else // '@Many'
        if (null != field.getAnnotation(Many.class)) {
            manys.add(_Infos.createLinkInfo(field));
        } else // '@ManyMany'
        if (null != field.getAnnotation(ManyMany.class)) {
            manymanys.add(_Infos.createLinkInfo(field));
        } else // 应该忽略
        if ((Modifier.isTransient(field.getModifiers()) && null == field.getAnnotation(Column.class)) || (shouldUseColumn && (null == field.getAnnotation(Column.class) && null == field.getAnnotation(Id.class) && null == field.getAnnotation(Name.class))) && !pks.contains(field.getName())) {
            continue;
        } else // '@Column'
        {
            infos.add(_Infos.createMappingInfo(ti.annPK, field));
        }
    }
    // 循环所有方法,查找有没有虚拟数据库映射字段
    for (Method method : en.getType().getMethods()) {
        // '@One'
        if (null != method.getAnnotation(One.class)) {
            ones.add(_Infos.createLinkInfo(method));
        } else // '@Many'
        if (null != method.getAnnotation(Many.class)) {
            manys.add(_Infos.createLinkInfo(method));
        } else // '@ManyMany'
        if (null != method.getAnnotation(ManyMany.class)) {
            manymanys.add(_Infos.createLinkInfo(method));
        } else // 应该忽略
        if (null == method.getAnnotation(Column.class) && null == method.getAnnotation(Id.class) && null == method.getAnnotation(Name.class)) {
            continue;
        } else // '@Column'
        {
            infos.add(_Infos.createMapingInfo(ti.annPK, method));
        }
    }
    // 给字段排序一下, fix issue #29
    List<MappingInfo> tmp = new ArrayList<MappingInfo>(infos.size());
    MappingInfo miId = null;
    MappingInfo miName = null;
    // wjw(2017-04-10),add,version
    MappingInfo miVersion = null;
    for (MappingInfo mi : infos) {
        if (mi.annId != null) {
            if (miId != null) {
                throw new DaoException("Allows only a single @Id ! " + type);
            }
            miId = mi;
        } else if (mi.annName != null) {
            if (miName != null) {
                throw new DaoException("Allows only a single @Name ! " + type);
            }
            miName = mi;
        } else {
            // wjw(2017-04-10),add,version
            if (mi.annColumn != null && mi.annColumn.version()) {
                if (miVersion != null) {
                    throw new DaoException("Allows only a single @Version ! " + type);
                }
                miVersion = mi;
            }
            tmp.add(mi);
        }
    }
    if (miName != null)
        tmp.add(0, miName);
    if (miId != null)
        tmp.add(0, miId);
    infos = tmp;
    // 映射字段搞完了? 我看看你到底有没有字段!!
    if (infos.isEmpty())
        throw Lang.makeThrow(IllegalArgumentException.class, "Pojo(%s) without any Mapping Field!!", type);
    /*
         * 解析所有映射字段
         */
    for (MappingInfo info : infos) {
        NutMappingField ef = new NutMappingField(en);
        _evalMappingField(ef, info);
        en.addMappingField(ef);
    }
    // 保存一下,这样别的实体映射到这里时会用的到
    holder.set(en);
    try {
        // 一对一 '@One'
        for (LinkInfo li : ones) {
            en.addLinkField(new OneLinkField(en, holder, li));
        }
        // 一对多 '@Many'
        for (LinkInfo li : manys) {
            en.addLinkField(new ManyLinkField(en, holder, li));
        }
        // 多对多 '@ManyMany'
        for (LinkInfo li : manymanys) {
            en.addLinkField(new ManyManyLinkField(en, holder, li));
        }
        // 检查复合主键
        en.checkCompositeFields(null == ti.annPK ? null : ti.annPK.value());
        /*
			 * 交付给 expert 来检查一下数据库一致性
			 */
        if (null != datasource && null != expert) {
            _checkupEntityFieldsWithDatabase(en);
        }
        /*
			 * 检查字段宏
			 */
        _evalFieldMacro(en, infos);
        /*
			 * 解析实体索引
			 */
        if (null != ti.annIndexes)
            _evalEntityIndexes(en, ti.annIndexes);
    } catch (RuntimeException e) {
        holder.remove(en);
        throw e;
    } catch (Throwable e) {
        holder.remove(en);
        throw Lang.wrapThrow(e);
    }
    // 处理Pojo拦截器
    if (NutConf.DAO_USE_POJO_INTERCEPTOR && ti.annTable != null) {
        PojoInterceptor pint = Mirror.me(ti.annTable.interceptor()).born();
        pint.setupEntity(en, expert);
        en.setInterceptor(pint);
    }
    // 搞定收工,哦耶 ^_^
    en.setComplete(true);
    return en;
}
Also used : One(org.nutz.dao.entity.annotation.One) ManyMany(org.nutz.dao.entity.annotation.ManyMany) ArrayList(java.util.ArrayList) DaoException(org.nutz.dao.DaoException) ManyManyLinkField(org.nutz.dao.impl.entity.field.ManyManyLinkField) ManyLinkField(org.nutz.dao.impl.entity.field.ManyLinkField) Name(org.nutz.dao.entity.annotation.Name) NutMappingField(org.nutz.dao.impl.entity.field.NutMappingField) OneLinkField(org.nutz.dao.impl.entity.field.OneLinkField) NutMappingField(org.nutz.dao.impl.entity.field.NutMappingField) MappingField(org.nutz.dao.entity.MappingField) ManyManyLinkField(org.nutz.dao.impl.entity.field.ManyManyLinkField) ManyLinkField(org.nutz.dao.impl.entity.field.ManyLinkField) EntityField(org.nutz.dao.entity.EntityField) Field(java.lang.reflect.Field) Column(org.nutz.dao.entity.annotation.Column) TableInfo(org.nutz.dao.impl.entity.info.TableInfo) ManyManyLinkField(org.nutz.dao.impl.entity.field.ManyManyLinkField) LinkInfo(org.nutz.dao.impl.entity.info.LinkInfo) Method(java.lang.reflect.Method) OneLinkField(org.nutz.dao.impl.entity.field.OneLinkField) PojoInterceptor(org.nutz.dao.interceptor.PojoInterceptor) Id(org.nutz.dao.entity.annotation.Id) MappingInfo(org.nutz.dao.impl.entity.info.MappingInfo)

Example 4 with NutMappingField

use of org.nutz.dao.impl.entity.field.NutMappingField in project nutz by nutzam.

the class AnnotationEntityMaker method _evalFieldMacro.

private void _evalFieldMacro(Entity<?> en, List<MappingInfo> infos) {
    for (MappingInfo info : infos) {
        // '@Prev' : 预设值
        if (null != info.annPrev) {
            boolean flag = en.addBeforeInsertMacro(__macro(en.getField(info.name), _annToFieldMacroInfo(info.annPrev.els(), info.annPrev.value())));
            if (flag && null != info.annId && info.annId.auto()) {
                log.debugf("Field(%s#%s) autoset as @Id(auto=false)", en.getType().getName(), info.name);
                ((NutMappingField) en.getField(info.name)).setAutoIncreasement(false);
            }
        }
        // '@Next' : 后续获取
        if (null != info.annNext && en.addAfterInsertMacro(__macro(en.getField(info.name), _annToFieldMacroInfo(info.annNext.els(), info.annNext.value())))) {
            continue;
        } else // '@Id' : 的自动后续获取
        if (null != info.annId && info.annId.auto() && en.getField(info.name).isAutoIncreasement()) {
            if (!expert.isSupportAutoIncrement() || !expert.isSupportGeneratedKeys())
                en.addAfterInsertMacro(expert.fetchPojoId(en, en.getField(info.name)));
        }
    }
}
Also used : MappingInfo(org.nutz.dao.impl.entity.info.MappingInfo) NutMappingField(org.nutz.dao.impl.entity.field.NutMappingField)

Example 5 with NutMappingField

use of org.nutz.dao.impl.entity.field.NutMappingField in project nutz by nutzam.

the class MapEntityMaker method make.

@SuppressWarnings({ "unchecked", "rawtypes" })
public <T extends Map<String, ?>> Entity<T> make(String tableName, T map) {
    final NutEntity<T> en = new NutEntity(map.getClass());
    en.setTableName(tableName);
    en.setViewName(tableName);
    boolean check = false;
    for (Entry<String, ?> entry : map.entrySet()) {
        String key = entry.getKey();
        // 是实体补充描述吗?
        if (key.startsWith("#")) {
            en.getMetas().put(key.substring(1), entry.getValue().toString());
            continue;
        } else // 以 "." 开头的字段,不是实体字段
        if (key.startsWith(".")) {
            continue;
        }
        // 是实体字段
        Object value = entry.getValue();
        Mirror<?> mirror = Mirror.me(value);
        NutMappingField ef = new NutMappingField(en);
        while (true) {
            if (key.startsWith("+")) {
                ef.setAsAutoIncreasement();
                if (mirror != null && mirror.isIntLike())
                    ef.setAsId();
                key = key.substring(1);
            } else if (key.startsWith("!")) {
                ef.setAsNotNull();
                key = key.substring(1);
            } else if (key.startsWith("*")) {
                key = key.substring(1);
                if (mirror != null && mirror.isIntLike())
                    ef.setAsId();
                else
                    ef.setAsName();
            } else {
                break;
            }
        }
        ef.setName(key);
        String columnName = key;
        // 强制大写?
        if (Daos.FORCE_UPPER_COLUMN_NAME) {
            ef.setColumnName(columnName.toUpperCase());
        } else {
            ef.setColumnName(columnName);
        }
        // 强制包裹?
        if (Daos.FORCE_WRAP_COLUMN_NAME) {
            ef.setColumnNameInSql(expert.wrapKeyword(columnName, true));
        } else if (Daos.CHECK_COLUMN_NAME_KEYWORD) {
            ef.setColumnNameInSql(expert.wrapKeyword(columnName, false));
        }
        // 类型是啥呢?
        if (map.containsKey("." + key + ".type")) {
            ef.setType((Class) map.get("." + key + ".type"));
        } else {
            ef.setType(null == value ? Object.class : value.getClass());
        }
        // ColType是啥呢?
        if (map.containsKey("." + key + ".coltype")) {
            ef.setColumnType((ColType) map.get("." + key + ".coltype"));
        } else {
            // 猜测一下数据库类型
            Jdbcs.guessEntityFieldColumnType(ef);
        }
        // 适配器类型是啥呢?
        if (map.containsKey("." + key + ".adaptor")) {
            ef.setAdaptor((ValueAdaptor) map.get("." + key + ".adaptor"));
        } else {
            ef.setAdaptor(expert.getAdaptor(ef));
        }
        // 字段长度是多少呢
        if (map.containsKey("." + key + ".width")) {
            Object w = map.get("." + key + ".width");
            if (null != w && (w instanceof Integer)) {
                ef.setWidth((Integer) w);
            }
        }
        // 这里比较纠结,回设的时候应该用什么呢?
        ef.setInjecting(new InjectToMap(key));
        ef.setEjecting(new EjectFromMap(entry.getKey()));
        if (ef.isAutoIncreasement() && ef.isId() && expert.isSupportAutoIncrement() && !expert.isSupportGeneratedKeys()) {
            en.addAfterInsertMacro(expert.fetchPojoId(en, ef));
        }
        en.addMappingField(ef);
        if (mirror != null && !check)
            check = mirror.isEnum();
    }
    en.checkCompositeFields(null);
    // 最后在数据库中验证一下实体各个字段
    if (check) {
        Connection conn = null;
        try {
            try {
                conn = dataSource.getConnection();
                expert.setupEntityField(conn, en);
            } finally {
                if (conn != null)
                    conn.close();
            }
        } catch (SQLException e) {
            log.debug(e.getMessage(), e);
        }
    }
    // 搞定返回
    return en;
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) NutMappingField(org.nutz.dao.impl.entity.field.NutMappingField) InjectToMap(org.nutz.lang.inject.InjectToMap) EjectFromMap(org.nutz.lang.eject.EjectFromMap)

Aggregations

NutMappingField (org.nutz.dao.impl.entity.field.NutMappingField)5 Connection (java.sql.Connection)2 MappingInfo (org.nutz.dao.impl.entity.info.MappingInfo)2 EjectFromMap (org.nutz.lang.eject.EjectFromMap)2 InjectToMap (org.nutz.lang.inject.InjectToMap)2 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 ConnCallback (org.nutz.dao.ConnCallback)1 DaoException (org.nutz.dao.DaoException)1 EntityField (org.nutz.dao.entity.EntityField)1 MappingField (org.nutz.dao.entity.MappingField)1 Column (org.nutz.dao.entity.annotation.Column)1 Id (org.nutz.dao.entity.annotation.Id)1 ManyMany (org.nutz.dao.entity.annotation.ManyMany)1 Name (org.nutz.dao.entity.annotation.Name)1 One (org.nutz.dao.entity.annotation.One)1 NutEntity (org.nutz.dao.impl.entity.NutEntity)1 ManyLinkField (org.nutz.dao.impl.entity.field.ManyLinkField)1