001// ______________________________________________________
002// Generated by sql2java - https://github.com/10km/sql2java-2-6-7 (custom branch) 
003// modified by guyadong from
004// sql2java original version https://sourceforge.net/projects/sql2java/ 
005// JDBC driver used at code generation time: com.mysql.jdbc.Driver
006// template: bean.java.vm
007// ______________________________________________________
008package net.gdface.facelog.db;
009import java.io.Serializable;
010import java.util.List;
011import java.util.Objects;
012
013import com.facebook.swift.codec.ThriftStruct;
014import com.facebook.swift.codec.ThriftField;
015import com.facebook.swift.codec.ThriftField.Requiredness;
016import io.swagger.annotations.ApiModel;
017import io.swagger.annotations.ApiModelProperty;
018/**
019 * FeatureBean is a mapping of fl_feature Table.
020 * <br>Meta Data Information (in progress):
021 * <ul>
022 *    <li>comments: 用于验证身份的人脸特征数据表 </li>
023 * </ul>
024 * @author guyadong
025*/
026@ThriftStruct
027@ApiModel(description="用于验证身份的人脸特征数据表")
028public final class FeatureBean
029    implements Serializable,BaseBean<FeatureBean>,Comparable<FeatureBean>,Constant,Cloneable
030{
031    private static final long serialVersionUID = -2191238184879882524L;
032    /** NULL {@link FeatureBean} bean , IMMUTABLE instance */
033    public static final FeatureBean NULL = new FeatureBean().asNULL().asImmutable();
034    /** comments:主键,特征码md5校验码 */
035    @ApiModelProperty(value = "主键,特征码md5校验码" ,required=true ,dataType="String")
036    private String md5;
037
038    /** comments:特征码(算法)版本号,用于区分不同人脸识别算法生成的特征数据(允许字母,数字,-,.,_符号) */
039    @ApiModelProperty(value = "特征码(算法)版本号,用于区分不同人脸识别算法生成的特征数据(允许字母,数字,-,.,_符号)" ,required=true ,dataType="String")
040    private String version;
041
042    /** comments:外键,所属用户id */
043    @ApiModelProperty(value = "外键,所属用户id"  ,dataType="Integer")
044    private Integer personId;
045
046    /** comments:二进制特征数据 */
047    @ApiModelProperty(value = "二进制特征数据" ,required=true ,dataType="ByteBuffer")
048    private java.nio.ByteBuffer feature;
049
050    @ApiModelProperty(value = "update_time"  ,dataType="Date")
051    private java.util.Date updateTime;
052
053    /** flag whether {@code this} can be modified */
054    private Boolean immutable;
055    /** columns modified flag */
056    @ApiModelProperty(value="columns modified flag",dataType="int",required=true)
057    private int modified;
058    /** columns initialized flag */
059    @ApiModelProperty(value="columns initialized flag",dataType="int",required=true)
060    private int initialized;
061    /** new record flag  */
062    @ApiModelProperty(value="new record flag",dataType="boolean",required=true)
063    private boolean isNew;        
064    /** 
065     * set immutable status
066     * @return {@code this} 
067     */
068    private FeatureBean immutable(Boolean immutable) {
069        this.immutable = immutable;
070        return this;
071    }
072    /** 
073     * set {@code this} as immutable object
074     * @return {@code this} 
075     */
076    public FeatureBean asImmutable() {
077        return immutable(Boolean.TRUE);
078    }
079    /**
080     * @return {@code true} if {@code this} is a mutable object  
081     */
082    public boolean mutable(){
083        return !Boolean.TRUE.equals(this.immutable);
084    }
085    /**
086     * @return {@code this}
087     * @throws IllegalStateException if {@code this} is a immutable object 
088     */
089    private FeatureBean checkMutable(){
090        if(!mutable()){
091            throw new IllegalStateException("this is a immutable object");
092        }
093        return this;
094    }
095    /**
096     * @return return a new mutable copy of this object.
097     */
098    public FeatureBean cloneMutable(){
099        return clone().immutable(null);
100    }
101    @ThriftField(value=1,name="_new",requiredness=Requiredness.REQUIRED)
102    @Override
103    public boolean isNew()
104    {
105        return this.isNew;
106    }
107
108
109    @Override
110    public void isNew(boolean isNew)
111    {
112        this.isNew = isNew;
113    }
114    /**
115     * Specifies to the object if it has been set as new.
116     *
117     * @param isNew the boolean value to be assigned to the isNew field
118     */
119    @ThriftField()
120    public void setNew(boolean isNew)
121    {
122        this.isNew = isNew;
123    }
124    /**
125     * @return the modified status of columns
126     */
127    @ThriftField(value=2,requiredness=Requiredness.REQUIRED)
128    public int getModified(){
129        return modified;
130    }
131
132    /**
133     * @param modified the modified status bit to be assigned to {@link #modified}
134     */
135    @ThriftField()
136    public void setModified(int modified){
137        this.modified = modified;
138    }
139    /**
140     * @return the initialized status of columns
141     */
142    @ThriftField(value=3,requiredness=Requiredness.REQUIRED)
143    public int getInitialized(){
144        return initialized;
145    }
146
147    /**
148     * @param initialized the initialized status bit to be assigned to {@link #initialized}
149     */
150    @ThriftField()
151    public void setInitialized(int initialized){
152        this.initialized = initialized;
153    }
154    protected static final <T extends Comparable<T>>boolean equals(T a, T b) {
155        return a == b || (a != null && 0==a.compareTo(b));
156    }
157    public FeatureBean(){
158        super();
159        reset();
160    }
161    /**
162     * construct a new instance filled with primary keys
163     * @param md5 PK# 1 
164     */
165    public FeatureBean(String md5){
166        this();
167        setMd5(md5);
168    }
169    /**
170     * Getter method for {@link #md5}.<br>
171     * PRIMARY KEY.<br>
172     * Meta Data Information (in progress):
173     * <ul>
174     * <li>full name: fl_feature.md5</li>
175     * <li> imported key: fl_log.verify_feature</li>
176     * <li> imported key: fl_face.feature_md5</li>
177     * <li>comments: 主键,特征码md5校验码</li>
178     * <li>NOT NULL</li>
179     * <li>column size: 32</li>
180     * <li>JDBC type returned by the driver: Types.CHAR</li>
181     * </ul>
182     *
183     * @return the value of md5
184     */
185    @ThriftField(value=4)
186    public String getMd5(){
187        return md5;
188    }
189    /**
190     * Setter method for {@link #md5}.<br>
191     * The new value is set only if equals() says it is different,
192     * or if one of either the new value or the current value is null.
193     * In case the new value is different, it is set and the field is marked as 'modified'.
194     *
195     * @param newVal the new value( NOT NULL) to be assigned to md5
196     */
197    public void setMd5(String newVal)
198    {
199        checkMutable();
200
201        modified |= FL_FEATURE_ID_MD5_MASK;
202        initialized |= FL_FEATURE_ID_MD5_MASK;
203
204        if (Objects.equals(newVal, md5)) {
205            return;
206        }
207        md5 = newVal;
208    }
209    /** 
210     * setter for thrift:swift support<br>
211     * without modification for {@link #modified} and {@link #initialized}<br>
212     * <b>NOTE:</b>DO NOT use the method in your code
213     */
214    @ThriftField(name = "md5")
215    public void writeMd5(String newVal){
216        checkMutable();
217        md5 = newVal;
218    }
219    /**
220     * Determines if the md5 has been modified.
221     *
222     * @return true if the field has been modified, false if the field has not been modified
223     */
224    public boolean checkMd5Modified()
225    {
226        return 0L !=  (modified & FL_FEATURE_ID_MD5_MASK);
227    }
228
229    /**
230     * Determines if the md5 has been initialized.<br>
231     *
232     * It is useful to determine if a field is null on purpose or just because it has not been initialized.
233     *
234     * @return true if the field has been initialized, false otherwise
235     */
236    public boolean checkMd5Initialized()
237    {
238        return 0L !=  (initialized & FL_FEATURE_ID_MD5_MASK);
239    }
240    /**
241     * Getter method for {@link #version}.<br>
242     * Meta Data Information (in progress):
243     * <ul>
244     * <li>full name: fl_feature.version</li>
245     * <li>comments: 特征码(算法)版本号,用于区分不同人脸识别算法生成的特征数据(允许字母,数字,-,.,_符号)</li>
246     * <li>NOT NULL</li>
247     * <li>column size: 32</li>
248     * <li>JDBC type returned by the driver: Types.VARCHAR</li>
249     * </ul>
250     *
251     * @return the value of version
252     */
253    @ThriftField(value=5)
254    public String getVersion(){
255        return version;
256    }
257    /**
258     * Setter method for {@link #version}.<br>
259     * The new value is set only if equals() says it is different,
260     * or if one of either the new value or the current value is null.
261     * In case the new value is different, it is set and the field is marked as 'modified'.
262     *
263     * @param newVal the new value( NOT NULL) to be assigned to version
264     */
265    public void setVersion(String newVal)
266    {
267        checkMutable();
268
269        modified |= FL_FEATURE_ID_VERSION_MASK;
270        initialized |= FL_FEATURE_ID_VERSION_MASK;
271
272        if (Objects.equals(newVal, version)) {
273            return;
274        }
275        version = newVal;
276    }
277    /** 
278     * setter for thrift:swift support<br>
279     * without modification for {@link #modified} and {@link #initialized}<br>
280     * <b>NOTE:</b>DO NOT use the method in your code
281     */
282    @ThriftField(name = "version")
283    public void writeVersion(String newVal){
284        checkMutable();
285        version = newVal;
286    }
287    /**
288     * Determines if the version has been modified.
289     *
290     * @return true if the field has been modified, false if the field has not been modified
291     */
292    public boolean checkVersionModified()
293    {
294        return 0L !=  (modified & FL_FEATURE_ID_VERSION_MASK);
295    }
296
297    /**
298     * Determines if the version has been initialized.<br>
299     *
300     * It is useful to determine if a field is null on purpose or just because it has not been initialized.
301     *
302     * @return true if the field has been initialized, false otherwise
303     */
304    public boolean checkVersionInitialized()
305    {
306        return 0L !=  (initialized & FL_FEATURE_ID_VERSION_MASK);
307    }
308    /**
309     * Getter method for {@link #personId}.<br>
310     * Meta Data Information (in progress):
311     * <ul>
312     * <li>full name: fl_feature.person_id</li>
313     * <li> foreign key: fl_person.id</li>
314     * <li>comments: 外键,所属用户id</li>
315     * <li>column size: 10</li>
316     * <li>JDBC type returned by the driver: Types.INTEGER</li>
317     * </ul>
318     *
319     * @return the value of personId
320     */
321    @ThriftField(value=6)
322    public Integer getPersonId(){
323        return personId;
324    }
325    /**
326     * Setter method for {@link #personId}.<br>
327     * The new value is set only if equals() says it is different,
328     * or if one of either the new value or the current value is null.
329     * In case the new value is different, it is set and the field is marked as 'modified'.
330     *
331     * @param newVal the new value to be assigned to personId
332     */
333    public void setPersonId(Integer newVal)
334    {
335        checkMutable();
336
337        modified |= FL_FEATURE_ID_PERSON_ID_MASK;
338        initialized |= FL_FEATURE_ID_PERSON_ID_MASK;
339
340        if (Objects.equals(newVal, personId)) {
341            return;
342        }
343        personId = newVal;
344    }
345    /** 
346     * setter for thrift:swift support<br>
347     * without modification for {@link #modified} and {@link #initialized}<br>
348     * <b>NOTE:</b>DO NOT use the method in your code
349     */
350    @ThriftField(name = "personId")
351    public void writePersonId(Integer newVal){
352        checkMutable();
353        personId = newVal;
354    }
355    /**
356     * Setter method for {@link #personId}.<br>
357     * Convenient for those who do not want to deal with Objects for primary types.
358     *
359     * @param newVal the new value to be assigned to personId
360     */
361    public void setPersonId(int newVal)
362    {
363        setPersonId(new Integer(newVal));
364    }
365    /**
366     * Determines if the personId has been modified.
367     *
368     * @return true if the field has been modified, false if the field has not been modified
369     */
370    public boolean checkPersonIdModified()
371    {
372        return 0L !=  (modified & FL_FEATURE_ID_PERSON_ID_MASK);
373    }
374
375    /**
376     * Determines if the personId has been initialized.<br>
377     *
378     * It is useful to determine if a field is null on purpose or just because it has not been initialized.
379     *
380     * @return true if the field has been initialized, false otherwise
381     */
382    public boolean checkPersonIdInitialized()
383    {
384        return 0L !=  (initialized & FL_FEATURE_ID_PERSON_ID_MASK);
385    }
386    /**
387     * Getter method for {@link #feature}.<br>
388     * Meta Data Information (in progress):
389     * <ul>
390     * <li>full name: fl_feature.feature</li>
391     * <li>comments: 二进制特征数据</li>
392     * <li>NOT NULL</li>
393     * <li>column size: 65535</li>
394     * <li>JDBC type returned by the driver: Types.LONGVARBINARY</li>
395     * </ul>
396     *
397     * @return the value of feature
398     */
399    @ThriftField(value=7)
400    public java.nio.ByteBuffer getFeature(){
401        return feature;
402    }
403    /**
404     * Setter method for {@link #feature}.<br>
405     * The new value is set only if equals() says it is different,
406     * or if one of either the new value or the current value is null.
407     * In case the new value is different, it is set and the field is marked as 'modified'.
408     *
409     * @param newVal the new value( NOT NULL) to be assigned to feature
410     */
411    public void setFeature(java.nio.ByteBuffer newVal)
412    {
413        checkMutable();
414
415        modified |= FL_FEATURE_ID_FEATURE_MASK;
416        initialized |= FL_FEATURE_ID_FEATURE_MASK;
417
418        if (Objects.equals(newVal, feature)) {
419            return;
420        }
421        feature = newVal;
422    }
423    /** 
424     * setter for thrift:swift support<br>
425     * without modification for {@link #modified} and {@link #initialized}<br>
426     * <b>NOTE:</b>DO NOT use the method in your code
427     */
428    @ThriftField(name = "feature")
429    public void writeFeature(java.nio.ByteBuffer newVal){
430        checkMutable();
431        feature = newVal;
432    }
433    /**
434     * Determines if the feature has been modified.
435     *
436     * @return true if the field has been modified, false if the field has not been modified
437     */
438    public boolean checkFeatureModified()
439    {
440        return 0L !=  (modified & FL_FEATURE_ID_FEATURE_MASK);
441    }
442
443    /**
444     * Determines if the feature has been initialized.<br>
445     *
446     * It is useful to determine if a field is null on purpose or just because it has not been initialized.
447     *
448     * @return true if the field has been initialized, false otherwise
449     */
450    public boolean checkFeatureInitialized()
451    {
452        return 0L !=  (initialized & FL_FEATURE_ID_FEATURE_MASK);
453    }
454    /**
455     * Getter method for {@link #updateTime}.<br>
456     * Meta Data Information (in progress):
457     * <ul>
458     * <li>full name: fl_feature.update_time</li>
459     * <li>default value: 'CURRENT_TIMESTAMP'</li>
460     * <li>NOT NULL</li>
461     * <li>column size: 19</li>
462     * <li>JDBC type returned by the driver: Types.TIMESTAMP</li>
463     * </ul>
464     *
465     * @return the value of updateTime
466     */
467    public java.util.Date getUpdateTime(){
468        return updateTime;
469    }
470    /** 
471     * use Long to represent date type for thrift:swift support 
472     * @see #getUpdateTime()
473     */
474    @ThriftField(name = "updateTime",value = 8)
475    public Long readUpdateTime(){
476        return null == updateTime ? null:updateTime.getTime();
477    }
478    /**
479     * Setter method for {@link #updateTime}.<br>
480     * The new value is set only if equals() says it is different,
481     * or if one of either the new value or the current value is null.
482     * In case the new value is different, it is set and the field is marked as 'modified'.
483     *
484     * @param newVal the new value( NOT NULL) to be assigned to updateTime
485     */
486    public void setUpdateTime(java.util.Date newVal)
487    {
488        checkMutable();
489
490        modified |= FL_FEATURE_ID_UPDATE_TIME_MASK;
491        initialized |= FL_FEATURE_ID_UPDATE_TIME_MASK;
492
493        if (Objects.equals(newVal, updateTime)) {
494            return;
495        }
496        updateTime = newVal;
497    }
498    /** 
499     * setter for thrift:swift support<br>
500     * without modification for {@link #modified} and {@link #initialized}<br>
501     * <b>NOTE:</b>DO NOT use the method in your code
502     */
503    @ThriftField(name = "updateTime")
504    public void writeUpdateTime(Long newVal){
505        checkMutable();
506        updateTime = null == newVal?null:new java.util.Date(newVal);
507    }
508    /**
509     * Setter method for {@link #updateTime}.<br>
510     * Convenient for those who do not want to deal with Objects for primary types.
511     *
512     * @param newVal the new value to be assigned to updateTime
513     */
514    public void setUpdateTime(long newVal)
515    {
516        setUpdateTime(new java.util.Date(newVal));
517    }
518    /**
519     * Setter method for {@link #updateTime}.<br>
520     * @param newVal the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
521     */
522    public void setUpdateTime(Long newVal)
523    {
524        setUpdateTime(null == newVal ? null : new java.util.Date(newVal));
525    }
526    /**
527     * Determines if the updateTime has been modified.
528     *
529     * @return true if the field has been modified, false if the field has not been modified
530     */
531    public boolean checkUpdateTimeModified()
532    {
533        return 0L !=  (modified & FL_FEATURE_ID_UPDATE_TIME_MASK);
534    }
535
536    /**
537     * Determines if the updateTime has been initialized.<br>
538     *
539     * It is useful to determine if a field is null on purpose or just because it has not been initialized.
540     *
541     * @return true if the field has been initialized, false otherwise
542     */
543    public boolean checkUpdateTimeInitialized()
544    {
545        return 0L !=  (initialized & FL_FEATURE_ID_UPDATE_TIME_MASK);
546    }
547    //////////////////////////////////////
548    // referenced bean for FOREIGN KEYS
549    //////////////////////////////////////
550    /** 
551     * The referenced {@link PersonBean} by {@link #personId} . <br>
552     * FOREIGN KEY (person_id) REFERENCES fl_person(id)
553     */
554    @ApiModelProperty(hidden = true)
555    private PersonBean referencedByPersonId;
556    /**
557     * Getter method for {@link #referencedByPersonId}.
558     * @return PersonBean
559     */
560    public PersonBean getReferencedByPersonId() {
561        return this.referencedByPersonId;
562    }
563    /**
564     * Setter method for {@link #referencedByPersonId}.
565     * @param reference PersonBean
566     */
567    public void setReferencedByPersonId(PersonBean reference) {
568        this.referencedByPersonId = reference;
569    }
570
571    @Override
572    public boolean isModified()
573    {
574        return 0 != modified;
575    }
576  
577    @Override
578    public boolean isModified(int columnID){
579        switch ( columnID ){
580        case FL_FEATURE_ID_MD5:
581            return checkMd5Modified();
582        case FL_FEATURE_ID_VERSION:
583            return checkVersionModified();
584        case FL_FEATURE_ID_PERSON_ID:
585            return checkPersonIdModified();
586        case FL_FEATURE_ID_FEATURE:
587            return checkFeatureModified();
588        case FL_FEATURE_ID_UPDATE_TIME:
589            return checkUpdateTimeModified();
590        default:
591            return false;
592        }        
593    }
594
595    @Override
596    public boolean isInitialized(int columnID){
597        switch(columnID) {
598        case FL_FEATURE_ID_MD5:
599            return checkMd5Initialized();
600        case FL_FEATURE_ID_VERSION:
601            return checkVersionInitialized();
602        case FL_FEATURE_ID_PERSON_ID:
603            return checkPersonIdInitialized();
604        case FL_FEATURE_ID_FEATURE:
605            return checkFeatureInitialized();
606        case FL_FEATURE_ID_UPDATE_TIME:
607            return checkUpdateTimeInitialized();
608        default:
609            return false;
610        }
611    }
612    
613    @Override
614    public boolean isModified(String column){        
615        return isModified(columnIDOf(column));
616    }
617
618    @Override
619    public boolean isInitialized(String column){
620        return isInitialized(columnIDOf(column));
621    }
622    
623    @Override
624    public void resetIsModified()
625    {
626        checkMutable();
627        modified = 0;
628    }
629
630    @Override
631    public void resetPrimaryKeysModified()
632    {
633        modified &= (~(FL_FEATURE_ID_MD5_MASK));
634    }
635    /**
636     * Resets columns modification status except primary keys to 'not modified'.
637     */
638    public void resetModifiedExceptPrimaryKeys()
639    {
640        modified &= (~(FL_FEATURE_ID_VERSION_MASK |
641            FL_FEATURE_ID_PERSON_ID_MASK |
642            FL_FEATURE_ID_FEATURE_MASK |
643            FL_FEATURE_ID_UPDATE_TIME_MASK));
644    }
645    /**
646     * Resets the object initialization status to 'not initialized'.
647     */
648    private void resetInitialized()
649    {
650        initialized = 0;
651    }
652    /** reset all fields to initial value, equal to a new bean */
653    public void reset(){
654        checkMutable();
655        this.md5 = null;
656        this.version = null;
657        this.personId = null;
658        this.feature = null;
659        /* DEFAULT:'CURRENT_TIMESTAMP'*/
660        this.updateTime = null;
661        this.isNew = true;
662        this.modified = 0;
663        this.initialized = 0;
664    }
665    @Override
666    public boolean equals(Object object)
667    {
668        if (!(object instanceof FeatureBean)) {
669            return false;
670        }
671
672        FeatureBean obj = (FeatureBean) object;
673        return new EqualsBuilder()
674            .append(getMd5(), obj.getMd5())
675            .append(getVersion(), obj.getVersion())
676            .append(getPersonId(), obj.getPersonId())
677            .append(getFeature(), obj.getFeature())
678            .append(getUpdateTime(), obj.getUpdateTime())
679            .isEquals();
680    }
681
682    @Override
683    public int hashCode()
684    {
685        return new HashCodeBuilder(-82280557, -700257973)
686            .append(getMd5())
687            .toHashCode();
688    }
689
690    @Override
691    public String toString() {
692        return toString(true,false);
693    }
694    /**
695     * cast byte array to HEX string
696     * 
697     * @param input
698     * @return {@code null} if {@code input} is null
699     */
700    private static final String toHex(byte[] input) {
701        if (null == input){
702            return null;
703        }
704        StringBuffer sb = new StringBuffer(input.length * 2);
705        for (int i = 0; i < input.length; i++) {
706            sb.append(Character.forDigit((input[i] & 240) >> 4, 16));
707            sb.append(Character.forDigit(input[i] & 15, 16));
708        }
709        return sb.toString();
710    }
711    protected static final StringBuilder append(StringBuilder buffer,boolean full,byte[] value){
712        if(full || null == value){
713            buffer.append(toHex(value));
714        }else{
715            buffer.append(value.length).append(" bytes");
716        }
717        return buffer;
718    }
719    private static int stringLimit = 64;
720    private static final int MINIMUM_LIMIT = 16;
721    protected static final StringBuilder append(StringBuilder buffer,boolean full,String value){
722        if(full || null == value || value.length() <= stringLimit){
723            buffer.append(value);
724        }else{
725            buffer.append(value.substring(0,stringLimit - 8)).append(" ...").append(value.substring(stringLimit-4,stringLimit));
726        }
727        return buffer;
728    }
729    protected static final <T>StringBuilder append(StringBuilder buffer,boolean full,T value){
730        return buffer.append(value);
731    }
732    public static final void setStringLimit(int limit){
733        if(limit < MINIMUM_LIMIT){
734            throw new IllegalArgumentException(String.format("INVALID limit %d,minimum value %d",limit,MINIMUM_LIMIT));
735        }
736        stringLimit = limit;
737    }
738    @Override
739    public String toString(boolean notNull, boolean fullIfStringOrBytes) {
740        // only output initialized field
741        StringBuilder builder = new StringBuilder(this.getClass().getName()).append("@").append(Integer.toHexString(this.hashCode())).append("[");
742        int count = 0;        
743        if(checkMd5Initialized()){
744            if(!notNull || null != getMd5()){
745                if(count++ >0){
746                    builder.append(",");
747                }
748                builder.append("md5=");
749                append(builder,fullIfStringOrBytes,getMd5());
750            }
751        }
752        if(checkVersionInitialized()){
753            if(!notNull || null != getVersion()){
754                if(count++ >0){
755                    builder.append(",");
756                }
757                builder.append("version=");
758                append(builder,fullIfStringOrBytes,getVersion());
759            }
760        }
761        if(checkPersonIdInitialized()){
762            if(!notNull || null != getPersonId()){
763                if(count++ >0){
764                    builder.append(",");
765                }
766                builder.append("person_id=");
767                append(builder,fullIfStringOrBytes,getPersonId());
768            }
769        }
770        if(checkFeatureInitialized()){
771            if(!notNull || null != getFeature()){
772                if(count++ >0){
773                    builder.append(",");
774                }
775                builder.append("feature=");
776                append(builder,fullIfStringOrBytes,getFeature());
777            }
778        }
779        if(checkUpdateTimeInitialized()){
780            if(!notNull || null != getUpdateTime()){
781                if(count++ >0){
782                    builder.append(",");
783                }
784                builder.append("update_time=");
785                append(builder,fullIfStringOrBytes,getUpdateTime());
786            }
787        }
788        builder.append("]");
789        return builder.toString();
790    }
791    @Override
792    public int compareTo(FeatureBean object){
793        return new CompareToBuilder()
794            .append(getMd5(), object.getMd5())
795            .append(getVersion(), object.getVersion())
796            .append(getPersonId(), object.getPersonId())
797            .append(getFeature(), object.getFeature())
798            .append(getUpdateTime(), object.getUpdateTime())
799            .toComparison();
800    }
801    @Override
802    public FeatureBean clone(){
803        try {
804            return (FeatureBean) super.clone();
805        } catch (CloneNotSupportedException e) {
806            throw new RuntimeException(e);
807        }
808    }
809    /**
810     * Make {@code this} to a NULL bean<br>
811     * set all fields to null, {@link #modified} and {@link #initialized} be set to 0
812     * @return {@code this} bean
813     * @author guyadong
814     */
815    public FeatureBean asNULL()
816    {   
817        checkMutable();
818        
819        setMd5((String)null);
820        setVersion((String)null);
821        setPersonId((Integer)null);
822        setFeature((java.nio.ByteBuffer)null);
823        setUpdateTime((java.util.Date)null);
824        isNew(true);
825        resetInitialized();
826        resetIsModified();
827        return this;
828    }
829    /**
830     * check whether this bean is a NULL bean 
831     * @return {@code true} if {@link #initialized} be set to zero
832     * @see #asNULL()
833     */
834    public boolean checkNULL(){
835        return 0 == getInitialized();
836    }
837    /** 
838     * @param source source list
839     * @return {@code source} replace {@code null} element with null instance({@link #NULL})
840     */
841    public static final List<FeatureBean> replaceNull(List<FeatureBean> source){
842        if(null != source){
843            for(int i = 0,endIndex = source.size();i<endIndex;++i){
844                if(null == source.get(i)){
845                    source.set(i, NULL);
846                }
847            }
848        }
849        return source;
850    }
851    /** 
852     * @param source input list
853     * @return replace null instance element with {@code null}
854     * @see #checkNULL()
855     */
856    public static final List<FeatureBean> replaceNullInstance(List<FeatureBean> source){
857        if(null != source){
858            for(int i = 0,endIndex = source.size();i<endIndex;++i){
859                if(source.get(i).checkNULL()){
860                    source.set(i, null);
861                }
862            }
863        }
864        return source;
865    }
866    @Override
867    public FeatureBean copy(FeatureBean bean)
868    {
869        return copy(bean,new int[]{});
870    }
871    @Override
872    public FeatureBean copy(FeatureBean bean, int... fieldList)
873    {
874        if (null == fieldList || 0 == fieldList.length){
875            fieldList = new int[]{0,1,2,3,4};
876        }
877        for (int i = 0; i < fieldList.length; ++i) {
878            if( bean.isInitialized(fieldList[i]) && !Objects.deepEquals(bean.getValue(fieldList[i]), getValue(fieldList[i]))){
879                setValue(fieldList[i], bean.getValue(fieldList[i]));
880            }
881        }
882        return this;
883    }
884        
885    @Override
886    public FeatureBean copy(FeatureBean bean, String... fieldList)
887    {
888        if (null == fieldList || 0 == fieldList.length){
889            copy(bean,(int[])null);
890        }else{
891            int field;
892            for (int i = 0; i < fieldList.length; i++) {
893                field = columnIDOf(fieldList[i].trim());
894                if(bean.isInitialized(field) && !Objects.deepEquals(bean.getValue(field), getValue(field))){
895                    setValue(field, bean.getValue(field));
896                }
897            }
898        }
899        return this;
900    }
901
902    @SuppressWarnings("unchecked")
903    @Override
904    public <T>T getValue(int columnID)
905    {
906        switch( columnID ){
907        case FL_FEATURE_ID_MD5: 
908            return (T)getMd5();        
909        case FL_FEATURE_ID_VERSION: 
910            return (T)getVersion();        
911        case FL_FEATURE_ID_PERSON_ID: 
912            return (T)getPersonId();        
913        case FL_FEATURE_ID_FEATURE: 
914            return (T)getFeature();        
915        case FL_FEATURE_ID_UPDATE_TIME: 
916            return (T)getUpdateTime();        
917        default:
918            return null;
919        }
920    }
921
922    @Override
923    public <T> void setValue(int columnID,T value)
924    {
925        switch( columnID ) {
926        case FL_FEATURE_ID_MD5:
927            setMd5((String)value);
928            break;
929        case FL_FEATURE_ID_VERSION:
930            setVersion((String)value);
931            break;
932        case FL_FEATURE_ID_PERSON_ID:
933            setPersonId((Integer)value);
934            break;
935        case FL_FEATURE_ID_FEATURE:
936            setFeature((java.nio.ByteBuffer)value);
937            break;
938        case FL_FEATURE_ID_UPDATE_TIME:
939            setUpdateTime((java.util.Date)value);
940            break;
941        default:
942            break;
943        }
944    }
945    
946    @Override
947    public <T> T getValue(String column)
948    {
949        return getValue(columnIDOf(column));
950    }
951
952    @Override
953    public <T> void setValue(String column,T value)
954    {
955        setValue(columnIDOf(column),value);
956    }
957    
958    /**
959     * @param column column name
960     * @return column id for the given field name or negative if {@code column} is invalid name 
961     */
962    public static int columnIDOf(String column){
963        int index = FL_FEATURE_FIELDS_LIST.indexOf(column);
964        return  index < 0 
965            ? FL_FEATURE_JAVA_FIELDS_LIST.indexOf(column)
966            : index;
967    }
968    
969    public static String columnNameOf(int columnId){
970        try{
971            return FL_FEATURE_FIELDS_LIST.get(columnId);
972        } catch(IndexOutOfBoundsException e){
973            return null;
974        }
975    }
976    
977    public static Class<?> typeOf(int columnId){
978        try{
979            return FL_FEATURE_FIELD_TYPES[columnId];
980        } catch(IndexOutOfBoundsException e){
981            return null;
982        }
983    }
984    
985    public static final Builder builder(){
986        return new Builder().reset();
987    }
988    /** 
989     * a builder for FeatureBean,the template instance is thread local variable
990     * a instance of Builder can be reused.
991     */
992    public static final class Builder{
993        /** FeatureBean instance used for template to create new FeatureBean instance. */
994        static final ThreadLocal<FeatureBean> TEMPLATE = new ThreadLocal<FeatureBean>(){
995            @Override
996            protected FeatureBean initialValue() {
997                return new FeatureBean();
998            }};
999        private Builder() {}
1000        /** 
1001         * reset the bean as template 
1002         * @see FeatureBean#reset()
1003         */
1004        public Builder reset(){
1005            TEMPLATE.get().reset();
1006            return this;
1007        }
1008        /** set a bean as template,must not be {@code null} */
1009        public Builder template(FeatureBean bean){
1010            if(null == bean){
1011                throw new NullPointerException();
1012            }
1013            TEMPLATE.set(bean);
1014            return this;
1015        }
1016        /** return a clone instance of {@link #TEMPLATE}*/
1017        public FeatureBean build(){
1018            return TEMPLATE.get().clone();
1019        }
1020        /** 
1021         * fill the field : fl_feature.md5
1022         * @param md5 主键,特征码md5校验码
1023         * @see FeatureBean#getMd5()
1024         * @see FeatureBean#setMd5(String)
1025         */
1026        public Builder md5(String md5){
1027            TEMPLATE.get().setMd5(md5);
1028            return this;
1029        }
1030        /** 
1031         * fill the field : fl_feature.version
1032         * @param version 特征码(算法)版本号,用于区分不同人脸识别算法生成的特征数据(允许字母,数字,-,.,_符号)
1033         * @see FeatureBean#getVersion()
1034         * @see FeatureBean#setVersion(String)
1035         */
1036        public Builder version(String version){
1037            TEMPLATE.get().setVersion(version);
1038            return this;
1039        }
1040        /** 
1041         * fill the field : fl_feature.person_id
1042         * @param personId 外键,所属用户id
1043         * @see FeatureBean#getPersonId()
1044         * @see FeatureBean#setPersonId(Integer)
1045         */
1046        public Builder personId(Integer personId){
1047            TEMPLATE.get().setPersonId(personId);
1048            return this;
1049        }
1050        /** 
1051         * fill the field : fl_feature.feature
1052         * @param feature 二进制特征数据
1053         * @see FeatureBean#getFeature()
1054         * @see FeatureBean#setFeature(java.nio.ByteBuffer)
1055         */
1056        public Builder feature(java.nio.ByteBuffer feature){
1057            TEMPLATE.get().setFeature(feature);
1058            return this;
1059        }
1060        /** 
1061         * fill the field : fl_feature.update_time
1062         * @param updateTime 
1063         * @see FeatureBean#getUpdateTime()
1064         * @see FeatureBean#setUpdateTime(java.util.Date)
1065         */
1066        public Builder updateTime(java.util.Date updateTime){
1067            TEMPLATE.get().setUpdateTime(updateTime);
1068            return this;
1069        }
1070    }
1071}