signature:
public class FileDownloadQueueSet { /** * Start tasks in a queue .
 * @ see # downloadSequentially ( BaseDownloadTask . . . )
 * @ see # downloadSequentially ( List )
 * @ see # downloadTogether ( BaseDownloadTask . . . )
 * @ see # downloadTogether ( List ) */
public void start ( ) { } }

implementation: for ( BaseDownloadTask task : tasks ) { task . setListener ( target ) ; if ( autoRetryTimes != null ) { task . setAutoRetryTimes ( autoRetryTimes ) ; } if ( syncCallback != null ) { task . setSyncCallback ( syncCallback ) ; } if ( isForceReDownload != null ) { task . setForceReDownload ( isForceReDownload ) ; } if ( callbackProgressTimes != null ) { task . setCallbackProgressTimes ( callbackProgressTimes ) ; } if ( callbackProgressMinIntervalMillis != null ) { task . setCallbackProgressMinInterval ( callbackProgressMinIntervalMillis ) ; } if ( tag != null ) { task . setTag ( tag ) ; } if ( taskFinishListenerList != null ) { for ( BaseDownloadTask . FinishListener finishListener : taskFinishListenerList ) { task . addFinishListener ( finishListener ) ; } } if ( this . directory != null ) { task . setPath ( this . directory , true ) ; } if ( this . isWifiRequired != null ) { task . setWifiRequired ( this . isWifiRequired ) ; } task . asInQueueTask ( ) . enqueue ( ) ; } FileDownloader . getImpl ( ) . start ( target , isSerial ) ;


signature:
public class FileDownloadList { /** * Divert all data in list 2 destination list */
void divertAndIgnoreDuplicate ( @ SuppressWarnings ( "SameParameterValue" ) final List < BaseDownloadTask . IRunningTask > destination ) { } }

implementation: synchronized ( mList ) { for ( BaseDownloadTask . IRunningTask iRunningTask : mList ) { if ( ! destination . contains ( iRunningTask ) ) { destination . add ( iRunningTask ) ; } } mList . clear ( ) ; }


signature:
public class FileDownloadList { /** * This method generally used for enqueuing the task which will be assembled by a queue .
 * @ see BaseDownloadTask . InQueueTask # enqueue ( ) */
void addUnchecked ( final BaseDownloadTask . IRunningTask task ) { } }

implementation: if ( task . isMarkedAdded2List ( ) ) { return ; } synchronized ( mList ) { if ( mList . contains ( task ) ) { FileDownloadLog . w ( this , "already has %s" , task ) ; } else { task . markAdded2List ( ) ; mList . add ( task ) ; if ( FileDownloadLog . NEED_LOG ) { FileDownloadLog . v ( this , "add list in all %s %d %d" , task , task . getOrigin ( ) . getStatus ( ) , mList . size ( ) ) ; } } }


signature:
public class FileDownloadSerialQueue { /** * Enqueues the given task sometime in the serial queue . If the { @ code task } is in the head of
 * the serial queue , the { @ code task } will be started automatically . */
public void enqueue ( BaseDownloadTask task ) { } }

implementation: synchronized ( finishCallback ) { if ( paused ) { pausedList . add ( task ) ; return ; } try { mTasks . put ( task ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } }


signature:
public class FileDownloadSerialQueue { /** * Pause the queue .
 * @ see # resume ( ) */
public void pause ( ) { } }

implementation: synchronized ( finishCallback ) { if ( paused ) { FileDownloadLog . w ( this , "require pause this queue(remain %d), but " + "it has already been paused" , mTasks . size ( ) ) ; return ; } paused = true ; mTasks . drainTo ( pausedList ) ; if ( workingTask != null ) { workingTask . removeFinishListener ( finishCallback ) ; workingTask . pause ( ) ; } }


signature:
public class FileDownloadSerialQueue { /** * Resume the queue if the queue is paused .
 * @ see # pause ( ) */
public void resume ( ) { } }

implementation: synchronized ( finishCallback ) { if ( ! paused ) { FileDownloadLog . w ( this , "require resume this queue(remain %d), but it is" + " still running" , mTasks . size ( ) ) ; return ; } paused = false ; mTasks . addAll ( pausedList ) ; pausedList . clear ( ) ; if ( workingTask == null ) { sendNext ( ) ; } else { workingTask . addFinishListener ( finishCallback ) ; workingTask . start ( ) ; } }


signature:
public class FileDownloadSerialQueue { /** * Attempts to stop the working task , halts the processing of waiting tasks , and returns a list
 * of the tasks that were awaiting execution . These tasks are drained ( removed ) from the task
 * queue upon return from this method . */
public List < BaseDownloadTask > shutdown ( ) { } }

implementation: synchronized ( finishCallback ) { if ( workingTask != null ) { pause ( ) ; } final List < BaseDownloadTask > unDealTaskList = new ArrayList < > ( pausedList ) ; pausedList . clear ( ) ; mHandler . removeMessages ( WHAT_NEXT ) ; mHandlerThread . interrupt ( ) ; mHandlerThread . quit ( ) ; return unDealTaskList ; }


signature:
public class FileDownloadUtils { /** * The same to com . android . providers . downloads . Helpers # parseContentDisposition .
 * Parse the Content - Disposition HTTP Header . The format of the header
 * is defined here : http : / / www . w3 . org / Protocols / rfc2616 / rfc2616 - sec19 . html
 * This header provides a filename for content that is going to be
 * downloaded to the file system . We only support the attachment type . */
public static String parseContentDisposition ( String contentDisposition ) { } }

implementation:
if ( contentDisposition == null ) { return null ; } try { Matcher m = CONTENT_DISPOSITION_WITH_ASTERISK_PATTERN . matcher ( contentDisposition ) ; if ( m . find ( ) ) { String charset = m . group ( 1 ) ; String encodeFileName = m . group ( 2 ) ; return URLDecoder . decode ( encodeFileName , charset ) ; } m = CONTENT_DISPOSITION_WITHOUT_ASTERISK_PATTERN . matcher ( contentDisposition ) ; if ( m . find ( ) ) { return m . group ( 1 ) ; } } catch ( IllegalStateException | UnsupportedEncodingException ignore ) { // This function is defined as returning null when it can ' t parse the header
} return null ;


signature:
public class FileDownloadUtils { /** * accept range is effect by response code and Accept - Ranges header field . */
public static boolean isAcceptRange ( int responseCode , FileDownloadConnection connection ) { } }

implementation: if ( responseCode == HttpURLConnection . HTTP_PARTIAL || responseCode == FileDownloadConnection . RESPONSE_CODE_FROM_OFFSET ) return true ; final String acceptRanges = connection . getResponseHeaderField ( "Accept-Ranges" ) ; return "bytes" . equals ( acceptRanges ) ;


signature:
public class FileDownloadUtils { /** * content - length . */
public static long findInstanceLengthForTrial ( FileDownloadConnection connection ) { } }

implementation:
long length = findInstanceLengthFromContentRange ( connection ) ; if ( length < 0 ) { length = TOTAL_VALUE_IN_CHUNKED_RESOURCE ; FileDownloadLog . w ( FileDownloadUtils . class , "don't get instance length from" + "Content-Range header" ) ; } // the response of HEAD method is not very canonical sometimes ( it depends on server
// implementation )
// so that it ' s uncertain the content - length is the same as the response of GET method if
// content - length = 0 , so we have to filter this case in here .
if ( length == 0 && FileDownloadProperties . getImpl ( ) . trialConnectionHeadMethod ) { length = TOTAL_VALUE_IN_CHUNKED_RESOURCE ; } return length ;


signature:
public class FloatingActionMenu { /** * Sets whether open and close actions should be animated
 * @ param animated if < b > false < / b > - menu items will appear / disappear instantly without any animation */
public void setAnimated ( boolean animated ) { } }

implementation: mIsAnimated = animated ; mOpenAnimatorSet . setDuration ( animated ? ANIMATION_DURATION : 0 ) ; mCloseAnimatorSet . setDuration ( animated ? ANIMATION_DURATION : 0 ) ;


signature:
public class FloatingActionMenu { /** * Makes the { @ link # FloatingActionMenu } to disappear and sets its visibility to { @ link # INVISIBLE }
 * @ param animate if true - plays " hide animation " */
public void hideMenu ( final boolean animate ) { } }

implementation: if ( ! isMenuHidden ( ) && ! mIsMenuButtonAnimationRunning ) { mIsMenuButtonAnimationRunning = true ; if ( isOpened ( ) ) { close ( animate ) ; mUiHandler . postDelayed ( new Runnable ( ) { @ Override public void run ( ) { if ( animate ) { startAnimation ( mMenuButtonHideAnimation ) ; } setVisibility ( INVISIBLE ) ; mIsMenuButtonAnimationRunning = false ; } } , mAnimationDelayPerItem * mButtonsCount ) ; } else { if ( animate ) { startAnimation ( mMenuButtonHideAnimation ) ; } setVisibility ( INVISIBLE ) ; mIsMenuButtonAnimationRunning = false ; } }


signature:
public class FloatingActionMenu { /** * Makes the { @ link FloatingActionButton } to disappear inside the { @ link # FloatingActionMenu } and
 * sets its visibility to { @ link # INVISIBLE }
 * @ param animate if true - plays " hide animation " */
public void hideMenuButton ( final boolean animate ) { } }

implementation: if ( ! isMenuButtonHidden ( ) && ! mIsMenuButtonAnimationRunning ) { mIsMenuButtonAnimationRunning = true ; if ( isOpened ( ) ) { close ( animate ) ; mUiHandler . postDelayed ( new Runnable ( ) { @ Override public void run ( ) { hideMenuButtonWithImage ( animate ) ; } } , mAnimationDelayPerItem * mButtonsCount ) ; } else { hideMenuButtonWithImage ( animate ) ; } }


signature:
public class FloatingActionButton { /** * Sets the size of the < b > FloatingActionButton < / b > and invalidates its layout .
 * @ param size size of the < b > FloatingActionButton < / b > . Accepted values : SIZE _ NORMAL , SIZE _ MINI . */
public void setButtonSize ( int size ) { } }

implementation: if ( size != SIZE_NORMAL && size != SIZE_MINI ) { throw new IllegalArgumentException ( "Use @FabSize constants only!" ) ; } if ( mFabSize != size ) { mFabSize = size ; updateBackground ( ) ; }


signature:
public class FloatingActionButton { /** * Sets the shadow radius of the < b > FloatingActionButton < / b > and invalidates its layout .
 * @ param dimenResId the resource identifier of the dimension */
public void setShadowRadius ( int dimenResId ) { } }

implementation: int shadowRadius = getResources ( ) . getDimensionPixelSize ( dimenResId ) ; if ( mShadowRadius != shadowRadius ) { mShadowRadius = shadowRadius ; requestLayout ( ) ; updateBackground ( ) ; }


signature:
public class FloatingActionButton { /** * Sets the shadow x offset of the < b > FloatingActionButton < / b > and invalidates its layout .
 * @ param dimenResId the resource identifier of the dimension */
public void setShadowXOffset ( int dimenResId ) { } }

implementation: int shadowXOffset = getResources ( ) . getDimensionPixelSize ( dimenResId ) ; if ( mShadowXOffset != shadowXOffset ) { mShadowXOffset = shadowXOffset ; requestLayout ( ) ; updateBackground ( ) ; }


signature:
public class FloatingActionButton { /** * Sets the shadow y offset of the < b > FloatingActionButton < / b > and invalidates its layout .
 * @ param dimenResId the resource identifier of the dimension */
public void setShadowYOffset ( int dimenResId ) { } }

implementation: int shadowYOffset = getResources ( ) . getDimensionPixelSize ( dimenResId ) ; if ( mShadowYOffset != shadowYOffset ) { mShadowYOffset = shadowYOffset ; requestLayout ( ) ; updateBackground ( ) ; }


signature:
public class FloatingActionButton { /** * Sets the shadow color and radius to mimic the native elevation .
 * < p > < b > API 21 + < / b > : Sets the native elevation of this view , in pixels . Updates margins to
 * make the view hold its position in layout across different platform versions . < / p > */
@ TargetApi ( Build . VERSION_CODES . LOLLIPOP ) public void setElevationCompat ( float elevation ) { } }

implementation: mShadowColor = 0x26000000 ; mShadowRadius = Math . round ( elevation / 2 ) ; mShadowXOffset = 0 ; mShadowYOffset = Math . round ( mFabSize == SIZE_NORMAL ? elevation : elevation / 2 ) ; if ( Util . hasLollipop ( ) ) { super . setElevation ( elevation ) ; mUsingElevationCompat = true ; mShowShadow = false ; updateBackground ( ) ; ViewGroup . LayoutParams layoutParams = getLayoutParams ( ) ; if ( layoutParams != null ) { setLayoutParams ( layoutParams ) ; } } else { mShowShadow = true ; updateBackground ( ) ; }


signature:
public class FloatingActionButton { /** * < p > Change the indeterminate mode for the progress bar . In indeterminate
 * mode , the progress is ignored and the progress bar shows an infinite
 * animation instead . < / p >
 * @ param indeterminate true to enable the indeterminate mode */
public synchronized void setIndeterminate ( boolean indeterminate ) { } }

implementation:
if ( ! indeterminate ) { mCurrentProgress = 0.0f ; } mProgressBarEnabled = indeterminate ; mShouldUpdateButtonPosition = true ; mProgressIndeterminate = indeterminate ; mLastTimeAnimated = SystemClock . uptimeMillis ( ) ; setupProgressBounds ( ) ; // saveButtonOriginalPosition ( ) ;
updateBackground ( ) ;


signature:
public class FloatingActionButton { /** * < b > This will clear all AnimationListeners . < / b > */
public void hideButtonInMenu ( boolean animate ) { } }

implementation: if ( ! isHidden ( ) && getVisibility ( ) != GONE ) { hide ( animate ) ; Label label = getLabelView ( ) ; if ( label != null ) { label . hide ( animate ) ; } getHideAnimation ( ) . setAnimationListener ( new Animation . AnimationListener ( ) { @ Override public void onAnimationStart ( Animation animation ) { } @ Override public void onAnimationEnd ( Animation animation ) { setVisibility ( GONE ) ; getHideAnimation ( ) . setAnimationListener ( null ) ; } @ Override public void onAnimationRepeat ( Animation animation ) { } } ) ; }


signature:
public class FloatingActionButton { /** * Set the label ' s background colors */
public void setLabelColors ( int colorNormal , int colorPressed , int colorRipple ) { } }

implementation: Label label = getLabelView ( ) ; int left = label . getPaddingLeft ( ) ; int top = label . getPaddingTop ( ) ; int right = label . getPaddingRight ( ) ; int bottom = label . getPaddingBottom ( ) ; label . setColors ( colorNormal , colorPressed , colorRipple ) ; label . updateBackground ( ) ; label . setPadding ( left , top , right , bottom ) ;


signature:
public class SelectSelectivePlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param warnings
 * @ return */
@ Override public boolean validate ( List < String > warnings ) { } }

implementation:
// 插件使用前提是使用了ModelColumnPlugin插件
if ( ! PluginTools . checkDependencyPlugin ( getContext ( ) , ModelColumnPlugin . class ) ) { warnings . add ( "itfsw:插件" + this . getClass ( ) . getTypeName ( ) + "插件需配合com.itfsw.mybatis.generator.plugins.ModelColumnPlugin插件使用！" ) ; return false ; } return super . validate ( warnings ) ;


signature:
public class SelectSelectivePlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param introspectedTable */
@ Override public void initialized ( IntrospectedTable introspectedTable ) { } }

implementation:
super . initialized ( introspectedTable ) ; // bug : 26,27
this . selectByExampleSelectiveEle = null ; this . selectByPrimaryKeySelectiveEle = null ;


signature:
public class SelectSelectivePlugin { /** * = = = = = client 方法生成 = = = = = */
@ Override public boolean clientSelectByExampleWithBLOBsMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation: FormatTools . addMethodWithBestPosition ( interfaze , this . replaceMethodWithSelective ( method , METHOD_SELECT_BY_EXAMPLE_SELECTIVE , "@Param(\"example\")" , introspectedTable ) ) ; return super . clientSelectByExampleWithBLOBsMethodGenerated ( method , interfaze , introspectedTable ) ;


signature:
public class SelectSelectivePlugin { /** * = = = = = sqlMap 生成 = = = = = */
@ Override public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated ( XmlElement element , IntrospectedTable introspectedTable ) { } }

implementation: this . selectByExampleSelectiveEle = this . generateSelectSelectiveElement ( METHOD_SELECT_BY_EXAMPLE_SELECTIVE , introspectedTable , false , true ) ; return super . sqlMapSelectByExampleWithoutBLOBsElementGenerated ( element , introspectedTable ) ;


signature:
public class SelectSelectivePlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param document
 * @ param introspectedTable
 * @ return */
@ Override public boolean sqlMapDocumentGenerated ( Document document , IntrospectedTable introspectedTable ) { } }

implementation:
// issues # 16
if ( introspectedTable . isConstructorBased ( ) ) { XmlElement resultMapEle = new XmlElement ( "resultMap" ) ; resultMapEle . addAttribute ( new Attribute ( "id" , ID_FOR_PROPERTY_BASED_RESULT_MAP ) ) ; resultMapEle . addAttribute ( new Attribute ( "type" , introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) . getFullyQualifiedName ( ) ) ) ; commentGenerator . addComment ( resultMapEle ) ; for ( IntrospectedColumn introspectedColumn : introspectedTable . getPrimaryKeyColumns ( ) ) { resultMapEle . addElement ( XmlElementGeneratorTools . generateResultMapResultElement ( "id" , introspectedColumn ) ) ; } for ( IntrospectedColumn introspectedColumn : introspectedTable . getNonPrimaryKeyColumns ( ) ) { resultMapEle . addElement ( XmlElementGeneratorTools . generateResultMapResultElement ( "result" , introspectedColumn ) ) ; } document . getRootElement ( ) . addElement ( 0 , resultMapEle ) ; } // 1 . selectByExampleSelective 方法
if ( this . selectByExampleSelectiveEle != null ) { FormatTools . addElementWithBestPosition ( document . getRootElement ( ) , this . selectByExampleSelectiveEle ) ; PluginTools . getHook ( ISelectSelectivePluginHook . class ) . sqlMapSelectByExampleSelectiveElementGenerated ( document , this . selectByExampleSelectiveEle , introspectedTable ) ; } // 2 . selectByPrimaryKeySelective
if ( this . selectByPrimaryKeySelectiveEle != null ) { FormatTools . addElementWithBestPosition ( document . getRootElement ( ) , this . selectByPrimaryKeySelectiveEle ) ; } return true ;


signature:
public class SelectSelectivePlugin { /** * = = = = = ISelectOneByExamplePluginHook = = = = = */
@ Override public boolean clientSelectOneByExampleWithBLOBsMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation: FormatTools . addMethodWithBestPosition ( interfaze , this . replaceMethodWithSelective ( method , METHOD_SELECT_ONE_BY_EXAMPLE_SELECTIVE , "@Param(\"example\")" , introspectedTable ) ) ; return true ;


signature:
public class SelectSelectivePlugin { /** * 生成selectOneByExampleSelective
 * @ param introspectedTable
 * @ return */
private XmlElement generateSelectSelectiveElement ( String id , IntrospectedTable introspectedTable , boolean selectOne , boolean byExample ) { } }

implementation:
XmlElement selectSelectiveEle = new XmlElement ( "select" ) ; commentGenerator . addComment ( selectSelectiveEle ) ; selectSelectiveEle . addAttribute ( new Attribute ( "id" , id ) ) ; // issues # 16
if ( introspectedTable . isConstructorBased ( ) ) { selectSelectiveEle . addAttribute ( new Attribute ( "resultMap" , ID_FOR_PROPERTY_BASED_RESULT_MAP ) ) ; } else if ( introspectedTable . hasBLOBColumns ( ) ) { selectSelectiveEle . addAttribute ( new Attribute ( "resultMap" , introspectedTable . getResultMapWithBLOBsId ( ) ) ) ; } else { selectSelectiveEle . addAttribute ( new Attribute ( "resultMap" , introspectedTable . getBaseResultMapId ( ) ) ) ; } selectSelectiveEle . addAttribute ( new Attribute ( "parameterType" , "map" ) ) ; if ( byExample ) { selectSelectiveEle . addElement ( new TextElement ( "select" ) ) ; if ( stringHasValue ( introspectedTable . getSelectByExampleQueryId ( ) ) ) { selectSelectiveEle . addElement ( new TextElement ( "'" + introspectedTable . getSelectByExampleQueryId ( ) + "' as QUERYID," ) ) ; } if ( ! selectOne ) { // issues # 20
XmlElement ifDistinctElement = new XmlElement ( "if" ) ; ifDistinctElement . addAttribute ( new Attribute ( "test" , "example.distinct" ) ) ; ifDistinctElement . addElement ( new TextElement ( "distinct" ) ) ; selectSelectiveEle . addElement ( ifDistinctElement ) ; } } else { selectSelectiveEle . addElement ( new TextElement ( "select" ) ) ; if ( stringHasValue ( introspectedTable . getSelectByPrimaryKeyQueryId ( ) ) ) { selectSelectiveEle . addElement ( new TextElement ( "'" + introspectedTable . getSelectByPrimaryKeyQueryId ( ) + "' as QUERYID," ) ) ; } } selectSelectiveEle . addElement ( this . generateSelectiveElement ( introspectedTable ) ) ; selectSelectiveEle . addElement ( new TextElement ( "from " + introspectedTable . getAliasedFullyQualifiedTableNameAtRuntime ( ) ) ) ; if ( byExample ) { selectSelectiveEle . addElement ( XmlElementGeneratorTools . getUpdateByExampleIncludeElement ( introspectedTable ) ) ; XmlElement ifElement1 = new XmlElement ( "if" ) ; ifElement1 . addAttribute ( new Attribute ( "test" , "example.orderByClause != null" ) ) ; ifElement1 . addElement ( new TextElement ( "order by ${example.orderByClause}" ) ) ; selectSelectiveEle . addElement ( ifElement1 ) ; } else { boolean and = false ; StringBuffer sb = new StringBuffer ( ) ; for ( IntrospectedColumn introspectedColumn : introspectedTable . getPrimaryKeyColumns ( ) ) { sb . setLength ( 0 ) ; if ( and ) { sb . append ( "  and " ) ; } else { sb . append ( "where " ) ; and = true ; } sb . append ( MyBatis3FormattingUtilities . getAliasedEscapedColumnName ( introspectedColumn ) ) ; sb . append ( " = " ) ; sb . append ( MyBatis3FormattingUtilities . getParameterClause ( introspectedColumn , introspectedTable . getRules ( ) . generatePrimaryKeyClass ( ) ? "record." : null ) ) ; selectSelectiveEle . addElement ( new TextElement ( sb . toString ( ) ) ) ; } } if ( selectOne ) { // 只查询一条
selectSelectiveEle . addElement ( new TextElement ( "limit 1" ) ) ; } return selectSelectiveEle ;


signature:
public class SelectSelectivePlugin { /** * 生成Selective xml节点
 * @ param introspectedTable
 * @ return */
private XmlElement generateSelectiveElement ( IntrospectedTable introspectedTable ) { } }

implementation:
XmlElement chooseEle = new XmlElement ( "choose" ) ; XmlElement whenEle = new XmlElement ( "when" ) ; whenEle . addAttribute ( new Attribute ( "test" , "selective != null and selective.length > 0" ) ) ; chooseEle . addElement ( whenEle ) ; // 生成返回字段节点
XmlElement keysEle = new XmlElement ( "foreach" ) ; whenEle . addElement ( keysEle ) ; keysEle . addAttribute ( new Attribute ( "collection" , "selective" ) ) ; keysEle . addAttribute ( new Attribute ( "item" , "column" ) ) ; keysEle . addAttribute ( new Attribute ( "separator" , "," ) ) ; keysEle . addElement ( new TextElement ( "${column.aliasedEscapedColumnName}" ) ) ; XmlElement otherwiseEle = new XmlElement ( "otherwise" ) ; chooseEle . addElement ( otherwiseEle ) ; // 存在关键词column或者table定义了alias属性 , 这里直接使用对应的ColumnListElement
if ( introspectedTable . getRules ( ) . generateSelectByExampleWithBLOBs ( ) ) { otherwiseEle . addElement ( XmlElementGeneratorTools . getBaseColumnListElement ( introspectedTable ) ) ; otherwiseEle . addElement ( new TextElement ( "," ) ) ; otherwiseEle . addElement ( XmlElementGeneratorTools . getBlobColumnListElement ( introspectedTable ) ) ; } else { otherwiseEle . addElement ( XmlElementGeneratorTools . getBaseColumnListElement ( introspectedTable ) ) ; } return chooseEle ;


signature:
public class SelectSelectivePlugin { /** * 替换方法成withSelective
 * @ param method
 * @ param name
 * @ param firstAnnotation
 * @ param introspectedTable
 * @ return */
private Method replaceMethodWithSelective ( Method method , String name , String firstAnnotation , IntrospectedTable introspectedTable ) { } }

implementation:
Method withSelective = JavaElementTools . clone ( method ) ; FormatTools . replaceGeneralMethodComment ( commentGenerator , withSelective , introspectedTable ) ; withSelective . setName ( name ) ; // example
withSelective . getParameters ( ) . get ( 0 ) . addAnnotation ( firstAnnotation ) ; // selective
withSelective . addParameter ( new Parameter ( this . getModelColumnFullyQualifiedJavaType ( introspectedTable ) , "selective" , "@Param(\"selective\")" , true ) ) ; return withSelective ;


signature:
public class SelectSelectivePlugin { /** * 获取ModelColumn type
 * @ param introspectedTable
 * @ return */
private FullyQualifiedJavaType getModelColumnFullyQualifiedJavaType ( IntrospectedTable introspectedTable ) { } }

implementation: return new FullyQualifiedJavaType ( introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) . getShortName ( ) + "." + ModelColumnPlugin . ENUM_NAME ) ;


signature:
public class ModelCloneablePlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelBaseRecordClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: this . supportCloneable ( topLevelClass , introspectedTable ) ; return super . modelBaseRecordClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class ModelCloneablePlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelPrimaryKeyClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: this . supportCloneable ( topLevelClass , introspectedTable ) ; return super . modelPrimaryKeyClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class ModelCloneablePlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelRecordWithBLOBsClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: this . supportCloneable ( topLevelClass , introspectedTable ) ; return super . modelRecordWithBLOBsClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class ModelCloneablePlugin { /** * 支持Cloneable
 * @ param topLevelClass
 * @ param introspectedTable */
private void supportCloneable ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// implement
topLevelClass . addSuperInterface ( new FullyQualifiedJavaType ( "java.lang.Cloneable" ) ) ; // clone
Method cloneMethod = JavaElementGeneratorTools . generateMethod ( "clone" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) ) ; commentGenerator . addGeneralMethodComment ( cloneMethod , introspectedTable ) ; cloneMethod . addAnnotation ( "@Override" ) ; cloneMethod . addException ( new FullyQualifiedJavaType ( "java.lang.CloneNotSupportedException" ) ) ; cloneMethod . addBodyLine ( "return (" + topLevelClass . getType ( ) . getShortName ( ) + ") super.clone();" ) ; topLevelClass . addMethod ( cloneMethod ) ;


signature:
public class EnumTypeStatusPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param introspectedTable */
@ Override public void initialized ( IntrospectedTable introspectedTable ) { } }

implementation:
super . initialized ( introspectedTable ) ; this . enumColumns = new LinkedHashMap < > ( ) ; String autoScan = this . getProperties ( ) . getProperty ( PRO_AUTO_SCAN ) ; // 是否开启了自动扫描
if ( StringUtility . stringHasValue ( autoScan ) && ! StringUtility . isTrue ( autoScan ) ) { // 获取全局配置
String enumColumns = this . getProperties ( ) . getProperty ( EnumTypeStatusPlugin . PRO_ENUM_COLUMNS ) ; // 如果有局部配置 , 则附加上去
String tableEnumColumns = introspectedTable . getTableConfigurationProperty ( EnumTypeStatusPlugin . PRO_ENUM_COLUMNS ) ; if ( tableEnumColumns != null ) { enumColumns = enumColumns == null ? "" : ( enumColumns + "," ) ; enumColumns += introspectedTable . getTableConfigurationProperty ( EnumTypeStatusPlugin . PRO_ENUM_COLUMNS ) ; } if ( StringUtility . stringHasValue ( enumColumns ) ) { // 切分
String [ ] enumColumnsStrs = enumColumns . split ( "," ) ; for ( String enumColumnsStr : enumColumnsStrs ) { IntrospectedColumn column = IntrospectedTableTools . safeGetColumn ( introspectedTable , enumColumnsStr ) ; if ( column != null ) { try { EnumInfo enumInfo = new EnumInfo ( column ) ; // 解析注释
enumInfo . parseRemarks ( column . getRemarks ( ) ) ; if ( enumInfo . hasItems ( ) ) { this . enumColumns . put ( column . getJavaProperty ( ) , enumInfo ) ; } } catch ( EnumInfo . CannotParseException e ) { warnings . add ( "itfsw:插件" + EnumTypeStatusPlugin . class . getTypeName ( ) + "没有找到column为" + enumColumnsStr . trim ( ) + "对应格式的注释的字段！" ) ; } catch ( EnumInfo . NotSupportTypeException e ) { warnings . add ( "itfsw:插件" + EnumTypeStatusPlugin . class . getTypeName ( ) + "找到column为" + enumColumnsStr . trim ( ) + "对应Java类型不在支持范围内！" ) ; } } } } } else { for ( IntrospectedColumn column : introspectedTable . getAllColumns ( ) ) { try { EnumInfo enumInfo = new EnumInfo ( column ) ; // 解析注释
enumInfo . parseRemarks ( column . getRemarks ( ) ) ; if ( enumInfo . hasItems ( ) ) { this . enumColumns . put ( column . getJavaProperty ( ) , enumInfo ) ; } } catch ( Exception e ) { // nothing
} } }


signature:
public class EnumTypeStatusPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelPrimaryKeyClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: this . generateModelEnum ( topLevelClass , introspectedTable ) ; return super . modelPrimaryKeyClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class EnumTypeStatusPlugin { /** * Model 生成
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelBaseRecordClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: this . generateModelEnum ( topLevelClass , introspectedTable ) ; return super . modelBaseRecordClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class EnumTypeStatusPlugin { /** * 生成对应enum
 * @ param topLevelClass
 * @ param introspectedTable */
private void generateModelEnum ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// 枚举跟随字段走
for ( Field field : topLevelClass . getFields ( ) ) { if ( this . enumColumns . get ( field . getName ( ) ) != null ) { InnerEnum innerEnum = this . enumColumns . get ( field . getName ( ) ) . generateEnum ( commentGenerator , introspectedTable ) ; topLevelClass . addInnerEnum ( innerEnum ) ; } }


signature:
public class HookAggregator { /** * 获取插件
 * @ param clazz
 * @ param < T >
 * @ return */
private < T > List < T > getPlugins ( Class < T > clazz ) { } }

implementation:
List list = new ArrayList ( ) ; // 反射获取插件列表 , 不能用单例去弄 , 不然因为类释放的问题而导致测试用例出问题
try { List < Plugin > plugins = ( List < Plugin > ) BeanUtils . getProperty ( this . context . getPlugins ( ) , "plugins" ) ; for ( Plugin plugin : plugins ) { if ( clazz . isInstance ( plugin ) ) { list . add ( plugin ) ; } } } catch ( Exception e ) { logger . error ( "获取插件列表失败！" , e ) ; } return list ;


signature:
public class HookAggregator { /** * = = = = = IIncrementsPluginHook = = = = = */
@ Override public List < Element > incrementSetElementGenerated ( IntrospectedColumn introspectedColumn , String prefix , boolean hasComma ) { } }

implementation: if ( this . getPlugins ( IIncrementsPluginHook . class ) . isEmpty ( ) ) { return new ArrayList < > ( ) ; } else { return this . getPlugins ( IIncrementsPluginHook . class ) . get ( 0 ) . incrementSetElementGenerated ( introspectedColumn , prefix , hasComma ) ; }


signature:
public class HookAggregator { /** * = = = = = IModelBuilderPluginHook = = = = = */
@ Override public boolean modelBuilderClassGenerated ( TopLevelClass topLevelClass , InnerClass builderClass , List < IntrospectedColumn > columns , IntrospectedTable introspectedTable ) { } }

implementation: for ( IModelBuilderPluginHook plugin : this . getPlugins ( IModelBuilderPluginHook . class ) ) { if ( ! plugin . modelBuilderClassGenerated ( topLevelClass , builderClass , columns , introspectedTable ) ) { return false ; } } return true ;


signature:
public class HookAggregator { /** * = = = = = IUpsertPluginHook = = = = = */
@ Override public boolean clientUpsertSelectiveMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation: for ( IUpsertPluginHook plugin : this . getPlugins ( IUpsertPluginHook . class ) ) { if ( ! plugin . clientUpsertSelectiveMethodGenerated ( method , interfaze , introspectedTable ) ) { return false ; } } return true ;


signature:
public class HookAggregator { /** * = = = = = IOptimisticLockerPluginHook = = = = = */
@ Override public boolean clientUpdateWithVersionByExampleSelectiveMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation: for ( IOptimisticLockerPluginHook plugin : this . getPlugins ( IOptimisticLockerPluginHook . class ) ) { if ( ! plugin . clientUpdateWithVersionByExampleSelectiveMethodGenerated ( method , interfaze , introspectedTable ) ) { return false ; } } return true ;


signature:
public class HookAggregator { /** * = = = = = ISelectOneByExamplePluginHook = = = = = */
@ Override public boolean clientSelectOneByExampleWithBLOBsMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation: for ( ISelectOneByExamplePluginHook plugin : this . getPlugins ( ISelectOneByExamplePluginHook . class ) ) { if ( ! plugin . clientSelectOneByExampleWithBLOBsMethodGenerated ( method , interfaze , introspectedTable ) ) { return false ; } } return true ;


signature:
public class HookAggregator { /** * = = = = = ITableConfigurationHook = = = = = */
@ Override public void tableConfiguration ( IntrospectedTable introspectedTable ) { } }

implementation: if ( ! this . getPlugins ( ITableConfigurationHook . class ) . isEmpty ( ) ) { this . getPlugins ( ITableConfigurationHook . class ) . get ( 0 ) . tableConfiguration ( introspectedTable ) ; }


signature:
public class HookAggregator { /** * = = = = = ILogicalDeletePluginHook = = = = = */
@ Override public boolean clientLogicalDeleteByExampleMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation: for ( ILogicalDeletePluginHook plugin : this . getPlugins ( ILogicalDeletePluginHook . class ) ) { if ( ! plugin . clientLogicalDeleteByExampleMethodGenerated ( method , interfaze , introspectedTable ) ) { return false ; } } return true ;


signature:
public class HookAggregator { /** * = = = = = ISelectSelectivePluginHook = = = = = */
@ Override public boolean sqlMapSelectByExampleSelectiveElementGenerated ( Document document , XmlElement element , IntrospectedTable introspectedTable ) { } }

implementation: for ( ISelectSelectivePluginHook plugin : this . getPlugins ( ISelectSelectivePluginHook . class ) ) { if ( ! plugin . sqlMapSelectByExampleSelectiveElementGenerated ( document , element , introspectedTable ) ) { return false ; } } return true ;


signature:
public class JavaElementGeneratorTools { /** * 生成静态常量
 * @ param fieldName 常量名称
 * @ param javaType 类型
 * @ param initString 初始化字段
 * @ return */
public static Field generateStaticFinalField ( String fieldName , FullyQualifiedJavaType javaType , String initString ) { } }

implementation: Field field = new Field ( fieldName , javaType ) ; field . setVisibility ( JavaVisibility . PUBLIC ) ; field . setStatic ( true ) ; field . setFinal ( true ) ; if ( initString != null ) { field . setInitializationString ( initString ) ; } return field ;


signature:
public class JavaElementGeneratorTools { /** * 生成属性
 * @ param fieldName 常量名称
 * @ param visibility 可见性
 * @ param javaType 类型
 * @ param initString 初始化字段
 * @ return */
public static Field generateField ( String fieldName , JavaVisibility visibility , FullyQualifiedJavaType javaType , String initString ) { } }

implementation: Field field = new Field ( fieldName , javaType ) ; field . setVisibility ( visibility ) ; if ( initString != null ) { field . setInitializationString ( initString ) ; } return field ;


signature:
public class JavaElementGeneratorTools { /** * 生成方法
 * @ param methodName 方法名
 * @ param visibility 可见性
 * @ param returnType 返回值类型
 * @ param parameters 参数列表
 * @ return */
public static Method generateMethod ( String methodName , JavaVisibility visibility , FullyQualifiedJavaType returnType , Parameter ... parameters ) { } }

implementation: Method method = new Method ( methodName ) ; method . setVisibility ( visibility ) ; method . setReturnType ( returnType ) ; if ( parameters != null ) { for ( Parameter parameter : parameters ) { method . addParameter ( parameter ) ; } } return method ;


signature:
public class JavaElementGeneratorTools { /** * 生成方法实现体
 * @ param method 方法
 * @ param bodyLines 方法实现行
 * @ return */
public static Method generateMethodBody ( Method method , String ... bodyLines ) { } }

implementation: if ( bodyLines != null ) { for ( String bodyLine : bodyLines ) { method . addBodyLine ( bodyLine ) ; } } return method ;


signature:
public class JavaElementGeneratorTools { /** * 生成Filed的Set方法
 * @ param field field
 * @ return */
public static Method generateSetterMethod ( Field field ) { } }

implementation: Method method = generateMethod ( "set" + FormatTools . upFirstChar ( field . getName ( ) ) , JavaVisibility . PUBLIC , null , new Parameter ( field . getType ( ) , field . getName ( ) ) ) ; return generateMethodBody ( method , "this." + field . getName ( ) + " = " + field . getName ( ) + ";" ) ;


signature:
public class JavaElementGeneratorTools { /** * 生成Filed的Get方法
 * @ param field field
 * @ return */
public static Method generateGetterMethod ( Field field ) { } }

implementation: Method method = generateMethod ( "get" + FormatTools . upFirstChar ( field . getName ( ) ) , JavaVisibility . PUBLIC , field . getType ( ) ) ; return generateMethodBody ( method , "return this." + field . getName ( ) + ";" ) ;


signature:
public class JavaElementGeneratorTools { /** * 获取Model没有BLOBs类时的类型
 * @ param introspectedTable
 * @ return */
public static FullyQualifiedJavaType getModelTypeWithoutBLOBs ( IntrospectedTable introspectedTable ) { } }

implementation: FullyQualifiedJavaType type ; if ( introspectedTable . getRules ( ) . generateBaseRecordClass ( ) ) { type = new FullyQualifiedJavaType ( introspectedTable . getBaseRecordType ( ) ) ; } else if ( introspectedTable . getRules ( ) . generatePrimaryKeyClass ( ) ) { type = new FullyQualifiedJavaType ( introspectedTable . getPrimaryKeyType ( ) ) ; } else { throw new RuntimeException ( getString ( "RuntimeError.12" ) ) ; } return type ;


signature:
public class JavaElementGeneratorTools { /** * 获取Model有BLOBs类时的类型
 * @ param introspectedTable
 * @ return */
public static FullyQualifiedJavaType getModelTypeWithBLOBs ( IntrospectedTable introspectedTable ) { } }

implementation:
FullyQualifiedJavaType type ; if ( introspectedTable . getRules ( ) . generateRecordWithBLOBsClass ( ) ) { type = new FullyQualifiedJavaType ( introspectedTable . getRecordWithBLOBsType ( ) ) ; } else { // the blob fields must be rolled up into the base class
type = new FullyQualifiedJavaType ( introspectedTable . getBaseRecordType ( ) ) ; } return type ;


signature:
public class ConstructorBasedBugFixPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelBaseRecordClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// 有种情况下ModelBaseRecordClass不会生成不包含BLOBs的构造方法
if ( introspectedTable . isConstructorBased ( ) && introspectedTable . hasBLOBColumns ( ) && introspectedTable . getBLOBColumns ( ) . size ( ) == 1 ) { // 判断是否已经生成了对应构造函数
String version = Plugin . class . getPackage ( ) . getImplementationVersion ( ) ; if ( version != null ) { String [ ] strs = version . split ( "\\." ) ; if ( strs . length == 3 && strs [ 0 ] . equals ( "1" ) && strs [ 1 ] . equals ( "3" ) && Integer . parseInt ( strs [ 2 ] ) < 6 ) { // 添加没有BLOBs的构造方法
Method method = new Method ( ) ; method . setVisibility ( JavaVisibility . PUBLIC ) ; method . setConstructor ( true ) ; method . setName ( topLevelClass . getType ( ) . getShortName ( ) ) ; commentGenerator . addGeneralMethodComment ( method , introspectedTable ) ; // 使用没有blobs的字段
List < IntrospectedColumn > constructorColumns = introspectedTable . getNonBLOBColumns ( ) ; for ( IntrospectedColumn introspectedColumn : constructorColumns ) { method . addParameter ( new Parameter ( introspectedColumn . getFullyQualifiedJavaType ( ) , introspectedColumn . getJavaProperty ( ) ) ) ; topLevelClass . addImportedType ( introspectedColumn . getFullyQualifiedJavaType ( ) ) ; } StringBuilder sb = new StringBuilder ( ) ; if ( introspectedTable . getRules ( ) . generatePrimaryKeyClass ( ) ) { boolean comma = false ; sb . append ( "super(" ) ; for ( IntrospectedColumn introspectedColumn : introspectedTable . getPrimaryKeyColumns ( ) ) { if ( comma ) { sb . append ( ", " ) ; } else { comma = true ; } sb . append ( introspectedColumn . getJavaProperty ( ) ) ; } sb . append ( ");" ) ; method . addBodyLine ( sb . toString ( ) ) ; } List < IntrospectedColumn > introspectedColumns ; if ( ! introspectedTable . getRules ( ) . generatePrimaryKeyClass ( ) && introspectedTable . hasPrimaryKeyColumns ( ) ) { introspectedColumns = introspectedTable . getNonBLOBColumns ( ) ; } else { introspectedColumns = introspectedTable . getBaseColumns ( ) ; } for ( IntrospectedColumn introspectedColumn : introspectedColumns ) { sb . setLength ( 0 ) ; sb . append ( "this." ) ; sb . append ( introspectedColumn . getJavaProperty ( ) ) ; sb . append ( " = " ) ; sb . append ( introspectedColumn . getJavaProperty ( ) ) ; sb . append ( ';' ) ; method . addBodyLine ( sb . toString ( ) ) ; } FormatTools . addMethodWithBestPosition ( topLevelClass , method ) ; } } } return true ;


signature:
public class ExampleEnhancedPlugin { /** * { @ inheritDoc }
 * @ param introspectedTable */
@ Override public void initialized ( IntrospectedTable introspectedTable ) { } }

implementation: super . initialized ( introspectedTable ) ; this . enableColumnOperate = PluginTools . checkDependencyPlugin ( context , ModelColumnPlugin . class ) ; String enableAndIf = properties . getProperty ( PRO_ENABLE_AND_IF ) ; this . enableAndIf = enableAndIf == null ? true : StringUtility . isTrue ( enableAndIf ) ;


signature:
public class ExampleEnhancedPlugin { /** * ModelExample Methods 生成
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelExampleClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
List < InnerClass > innerClasses = topLevelClass . getInnerClasses ( ) ; for ( int i = 0 ; i < innerClasses . size ( ) ; i ++ ) { InnerClass innerClass = innerClasses . get ( i ) ; if ( "Criteria" . equals ( innerClass . getType ( ) . getShortName ( ) ) ) { // 工厂方法
addFactoryMethodToCriteria ( topLevelClass , innerClass , introspectedTable ) ; // andIf
if ( this . enableAndIf ) { addAndIfMethodToCriteria ( topLevelClass , innerClass , introspectedTable ) ; } // when
addWhenToCriteria ( topLevelClass , innerClass , introspectedTable ) ; } else if ( "GeneratedCriteria" . equals ( innerClass . getType ( ) . getShortName ( ) ) ) { // column 方法
if ( this . enableColumnOperate ) { addColumnMethodToCriteria ( topLevelClass , innerClass , introspectedTable ) ; } } } List < Method > methods = topLevelClass . getMethods ( ) ; for ( Method method : methods ) { if ( ! "createCriteriaInternal" . equals ( method . getName ( ) ) ) { continue ; } else { method . getBodyLines ( ) . set ( 0 , "Criteria criteria = new Criteria(this);" ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "修改createCriteriaInternal方法，修改构造Criteria时传入Example对象" ) ; } } // orderBy方法
this . addOrderByMethodToExample ( topLevelClass , introspectedTable ) ; // createCriteria 静态方法
this . addStaticCreateCriteriaMethodToExample ( topLevelClass , introspectedTable ) ; // when
addWhenToExample ( topLevelClass , introspectedTable ) ; return true ;


signature:
public class ExampleEnhancedPlugin { /** * 添加 createCriteria 静态方法
 * @ param topLevelClass
 * @ param introspectedTable */
private void addStaticCreateCriteriaMethodToExample ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: Method createCriteriaMethod = JavaElementGeneratorTools . generateMethod ( METHOD_NEW_AND_CREATE_CRITERIA , JavaVisibility . PUBLIC , FullyQualifiedJavaType . getCriteriaInstance ( ) ) ; commentGenerator . addGeneralMethodComment ( createCriteriaMethod , introspectedTable ) ; createCriteriaMethod . setStatic ( true ) ; createCriteriaMethod . addBodyLine ( topLevelClass . getType ( ) . getShortName ( ) + " example = new " + topLevelClass . getType ( ) . getShortName ( ) + "();" ) ; createCriteriaMethod . addBodyLine ( "return example.createCriteria();" ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , createCriteriaMethod ) ;


signature:
public class ExampleEnhancedPlugin { /** * 添加列操作方法
 * @ param topLevelClass
 * @ param innerClass
 * @ param introspectedTable */
private void addColumnMethodToCriteria ( TopLevelClass topLevelClass , InnerClass innerClass , IntrospectedTable introspectedTable ) { } }

implementation:
// ! ! ! ! ! Column import比较特殊引入的是外部类
topLevelClass . addImportedType ( introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) ) ; for ( IntrospectedColumn introspectedColumn : introspectedTable . getNonBLOBColumns ( ) ) { topLevelClass . addImportedType ( introspectedColumn . getFullyQualifiedJavaType ( ) ) ; // EqualTo
FormatTools . addMethodWithBestPosition ( innerClass , this . generateSingleValueMethod ( introspectedTable , introspectedColumn , "EqualTo" , "=" ) ) ; // NotEqualTo
FormatTools . addMethodWithBestPosition ( innerClass , this . generateSingleValueMethod ( introspectedTable , introspectedColumn , "NotEqualTo" , "<>" ) ) ; // GreaterThan
FormatTools . addMethodWithBestPosition ( innerClass , this . generateSingleValueMethod ( introspectedTable , introspectedColumn , "GreaterThan" , ">" ) ) ; // GreaterThanOrEqualTo
FormatTools . addMethodWithBestPosition ( innerClass , this . generateSingleValueMethod ( introspectedTable , introspectedColumn , "GreaterThanOrEqualTo" , ">=" ) ) ; // LessThan
FormatTools . addMethodWithBestPosition ( innerClass , this . generateSingleValueMethod ( introspectedTable , introspectedColumn , "LessThan" , "<" ) ) ; // LessThanOrEqualTo
FormatTools . addMethodWithBestPosition ( innerClass , this . generateSingleValueMethod ( introspectedTable , introspectedColumn , "LessThanOrEqualTo" , "<=" ) ) ; }


signature:
public class ExampleEnhancedPlugin { /** * 生成column操作的具体方法
 * @ param introspectedTable
 * @ param introspectedColumn
 * @ param nameFragment
 * @ param operator
 * @ return */
private Method generateSingleValueMethod ( IntrospectedTable introspectedTable , IntrospectedColumn introspectedColumn , String nameFragment , String operator ) { } }

implementation:
// 方法名
StringBuilder sb = new StringBuilder ( ) ; sb . append ( introspectedColumn . getJavaProperty ( ) ) ; sb . setCharAt ( 0 , Character . toUpperCase ( sb . charAt ( 0 ) ) ) ; sb . insert ( 0 , "and" ) ; sb . append ( nameFragment ) ; sb . append ( "Column" ) ; Method method = JavaElementGeneratorTools . generateMethod ( sb . toString ( ) , JavaVisibility . PUBLIC , FullyQualifiedJavaType . getCriteriaInstance ( ) , new Parameter ( new FullyQualifiedJavaType ( introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) . getShortName ( ) + "." + ModelColumnPlugin . ENUM_NAME ) , "column" ) ) ; commentGenerator . addGeneralMethodComment ( method , introspectedTable ) ; // 方法体
sb . setLength ( 0 ) ; sb . append ( "addCriterion(" ) ; sb . append ( "new StringBuilder(\"" ) ; sb . append ( MyBatis3FormattingUtilities . getAliasedActualColumnName ( introspectedColumn ) ) ; sb . append ( " " ) ; sb . append ( operator ) ; sb . append ( " \").append(" ) ; sb . append ( "column." ) ; sb . append ( ModelColumnPlugin . METHOD_GET_ESCAPED_COLUMN_NAME ) ; sb . append ( "()).toString());" ) ; JavaElementGeneratorTools . generateMethodBody ( method , sb . toString ( ) , "return (Criteria) this;" ) ; return method ;


signature:
public class ExampleEnhancedPlugin { /** * 添加工厂方法
 * @ param topLevelClass
 * @ param innerClass
 * @ param introspectedTable */
private void addFactoryMethodToCriteria ( TopLevelClass topLevelClass , InnerClass innerClass , IntrospectedTable introspectedTable ) { } }

implementation:
// example field
Field exampleField = JavaElementGeneratorTools . generateField ( "example" , JavaVisibility . PRIVATE , topLevelClass . getType ( ) , null ) ; commentGenerator . addFieldComment ( exampleField , introspectedTable ) ; innerClass . addField ( exampleField ) ; // overwrite constructor
List < Method > methods = innerClass . getMethods ( ) ; for ( Method method : methods ) { if ( method . isConstructor ( ) ) { method . addParameter ( new Parameter ( topLevelClass . getType ( ) , "example" ) ) ; method . addBodyLine ( "this.example = example;" ) ; commentGenerator . addGeneralMethodComment ( method , introspectedTable ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "修改构造方法，增加example参数" ) ; } } // 添加example工厂方法
Method exampleMethod = JavaElementGeneratorTools . generateMethod ( "example" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) ) ; commentGenerator . addGeneralMethodComment ( exampleMethod , introspectedTable ) ; exampleMethod = JavaElementGeneratorTools . generateMethodBody ( exampleMethod , "return this.example;" ) ; FormatTools . addMethodWithBestPosition ( innerClass , exampleMethod ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "." + innerClass . getType ( ) . getShortName ( ) + "增加工厂方法example" ) ;


signature:
public class ExampleEnhancedPlugin { /** * 增强Criteria的链式调用 ( when )
 * @ param topLevelClass
 * @ param innerClass
 * @ param introspectedTable */
private void addWhenToCriteria ( TopLevelClass topLevelClass , InnerClass innerClass , IntrospectedTable introspectedTable ) { } }

implementation: this . addWhenToClass ( topLevelClass , innerClass , introspectedTable , "criteria" ) ;


signature:
public class ExampleEnhancedPlugin { /** * 增强链式调用 ( when )
 * @ param topLevelClass
 * @ param clazz
 * @ param introspectedTable */
private void addWhenToClass ( TopLevelClass topLevelClass , InnerClass clazz , IntrospectedTable introspectedTable , String type ) { } }

implementation:
// 添加接口When
InnerInterface whenInterface = new InnerInterface ( "I" + FormatTools . upFirstChar ( type ) + "When" ) ; whenInterface . setVisibility ( JavaVisibility . PUBLIC ) ; // ICriteriaAdd增加接口add
Method addMethod = JavaElementGeneratorTools . generateMethod ( type , JavaVisibility . DEFAULT , null , new Parameter ( clazz . getType ( ) , type ) ) ; commentGenerator . addGeneralMethodComment ( addMethod , introspectedTable ) ; whenInterface . addMethod ( addMethod ) ; InnerClass innerClassWrapper = new InnerInterfaceWrapperToInnerClass ( whenInterface ) ; // 添加注释
commentGenerator . addClassComment ( innerClassWrapper , introspectedTable ) ; topLevelClass . addInnerClass ( innerClassWrapper ) ; // 添加when方法
Method whenMethod = JavaElementGeneratorTools . generateMethod ( "when" , JavaVisibility . PUBLIC , clazz . getType ( ) , new Parameter ( FullyQualifiedJavaType . getBooleanPrimitiveInstance ( ) , "condition" ) , new Parameter ( whenInterface . getType ( ) , "then" ) ) ; commentGenerator . addGeneralMethodComment ( whenMethod , introspectedTable ) ; whenMethod = JavaElementGeneratorTools . generateMethodBody ( whenMethod , "if (condition) {" , "then." + type + "(this);" , "}" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( clazz , whenMethod ) ; Method whenOtherwiseMethod = JavaElementGeneratorTools . generateMethod ( "when" , JavaVisibility . PUBLIC , clazz . getType ( ) , new Parameter ( FullyQualifiedJavaType . getBooleanPrimitiveInstance ( ) , "condition" ) , new Parameter ( whenInterface . getType ( ) , "then" ) , new Parameter ( whenInterface . getType ( ) , "otherwise" ) ) ; commentGenerator . addGeneralMethodComment ( whenOtherwiseMethod , introspectedTable ) ; whenOtherwiseMethod = JavaElementGeneratorTools . generateMethodBody ( whenOtherwiseMethod , "if (condition) {" , "then." + type + "(this);" , "} else {" , "otherwise." + type + "(this);" , "}" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( clazz , whenOtherwiseMethod ) ;


signature:
public class ExampleEnhancedPlugin { /** * 增强Criteria的链式调用 , 添加andIf ( boolean addIf , CriteriaAdd add ) 方法 , 实现链式调用中按条件增加查询语句
 * @ param topLevelClass
 * @ param innerClass
 * @ param introspectedTable */
@ Deprecated private void addAndIfMethodToCriteria ( TopLevelClass topLevelClass , InnerClass innerClass , IntrospectedTable introspectedTable ) { } }

implementation:
// 添加接口CriteriaAdd
InnerInterface criteriaAddInterface = new InnerInterface ( "ICriteriaAdd" ) ; criteriaAddInterface . setVisibility ( JavaVisibility . PUBLIC ) ; criteriaAddInterface . addAnnotation ( "@Deprecated" ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "." + innerClass . getType ( ) . getShortName ( ) + "增加接口ICriteriaAdd" ) ; // ICriteriaAdd增加接口add
Method addMethod = JavaElementGeneratorTools . generateMethod ( "add" , JavaVisibility . DEFAULT , innerClass . getType ( ) , new Parameter ( innerClass . getType ( ) , "add" ) ) ; commentGenerator . addGeneralMethodComment ( addMethod , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( criteriaAddInterface , addMethod ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "." + innerClass . getType ( ) . getShortName ( ) + "." + criteriaAddInterface . getType ( ) . getShortName ( ) + "增加方法add" ) ; InnerClass innerClassWrapper = new InnerInterfaceWrapperToInnerClass ( criteriaAddInterface ) ; // 添加注释
commentGenerator . addClassComment ( innerClassWrapper , introspectedTable ) ; innerClass . addInnerClass ( innerClassWrapper ) ; // 添加andIf方法
Method andIfMethod = JavaElementGeneratorTools . generateMethod ( "andIf" , JavaVisibility . PUBLIC , innerClass . getType ( ) , new Parameter ( FullyQualifiedJavaType . getBooleanPrimitiveInstance ( ) , "ifAdd" ) , new Parameter ( criteriaAddInterface . getType ( ) , "add" ) ) ; andIfMethod . addAnnotation ( "@Deprecated" ) ; commentGenerator . addGeneralMethodComment ( andIfMethod , introspectedTable ) ; andIfMethod = JavaElementGeneratorTools . generateMethodBody ( andIfMethod , "if (ifAdd) {" , "add.add(this);" , "}" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( innerClass , andIfMethod ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "." + innerClass . getType ( ) . getShortName ( ) + "增加方法andIf" ) ;


signature:
public class ExampleEnhancedPlugin { /** * Example增强了setOrderByClause方法 , 新增orderBy ( String orderByClause ) 方法直接返回example , 增强链式调用 , 可以一路 . 下去了 。
 * @ param topLevelClass
 * @ param introspectedTable */
private void addOrderByMethodToExample ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// 添加orderBy
Method orderByMethod = JavaElementGeneratorTools . generateMethod ( "orderBy" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) , new Parameter ( FullyQualifiedJavaType . getStringInstance ( ) , "orderByClause" ) ) ; commentGenerator . addGeneralMethodComment ( orderByMethod , introspectedTable ) ; orderByMethod = JavaElementGeneratorTools . generateMethodBody ( orderByMethod , "this.setOrderByClause(orderByClause);" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , orderByMethod ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加方法orderBy" ) ; // 添加orderBy
Method orderByMethod1 = JavaElementGeneratorTools . generateMethod ( "orderBy" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) , new Parameter ( FullyQualifiedJavaType . getStringInstance ( ) , "orderByClauses" , true ) ) ; commentGenerator . addGeneralMethodComment ( orderByMethod1 , introspectedTable ) ; orderByMethod1 = JavaElementGeneratorTools . generateMethodBody ( orderByMethod1 , "StringBuffer sb = new StringBuffer();" , "for (int i = 0; i < orderByClauses.length; i++) {" , "sb.append(orderByClauses[i]);" , "if (i < orderByClauses.length - 1) {" , "sb.append(\" , \");" , "}" , "}" , "this.setOrderByClause(sb.toString());" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , orderByMethod1 ) ; logger . debug ( "itfsw(Example增强插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加方法orderBy(String ... orderByClauses)" ) ;


signature:
public class ModelColumnPlugin { /** * Model Methods 生成
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelBaseRecordClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: topLevelClass . addInnerEnum ( this . generateColumnEnum ( topLevelClass , introspectedTable ) ) ; return super . modelBaseRecordClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class ModelColumnPlugin { /** * Model Methods 生成
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelRecordWithBLOBsClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: topLevelClass . addInnerEnum ( this . generateColumnEnum ( topLevelClass , introspectedTable ) ) ; return super . modelRecordWithBLOBsClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class ModelColumnPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelPrimaryKeyClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation: topLevelClass . addInnerEnum ( this . generateColumnEnum ( topLevelClass , introspectedTable ) ) ; return super . modelPrimaryKeyClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class ModelColumnPlugin { /** * 生成Column字段枚举
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
private InnerEnum generateColumnEnum ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// 生成内部枚举
InnerEnum innerEnum = new InnerEnum ( new FullyQualifiedJavaType ( ENUM_NAME ) ) ; innerEnum . setVisibility ( JavaVisibility . PUBLIC ) ; innerEnum . setStatic ( true ) ; commentGenerator . addEnumComment ( innerEnum , introspectedTable ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加内部Builder类。" ) ; // 生成常量
Field beginningDelimiterField = JavaElementGeneratorTools . generateField ( CONST_BEGINNING_DELIMITER , JavaVisibility . PRIVATE , FullyQualifiedJavaType . getStringInstance ( ) , "\"" + StringUtility . escapeStringForJava ( context . getBeginningDelimiter ( ) ) + "\"" ) ; beginningDelimiterField . setStatic ( true ) ; beginningDelimiterField . setFinal ( true ) ; commentGenerator . addFieldComment ( beginningDelimiterField , introspectedTable ) ; innerEnum . addField ( beginningDelimiterField ) ; Field endingDelimiterField = JavaElementGeneratorTools . generateField ( CONST_ENDING_DELIMITER , JavaVisibility . PRIVATE , FullyQualifiedJavaType . getStringInstance ( ) , "\"" + StringUtility . escapeStringForJava ( context . getEndingDelimiter ( ) ) + "\"" ) ; endingDelimiterField . setStatic ( true ) ; endingDelimiterField . setFinal ( true ) ; commentGenerator . addFieldComment ( endingDelimiterField , introspectedTable ) ; innerEnum . addField ( endingDelimiterField ) ; // 生成属性和构造函数
Field columnField = new Field ( "column" , FullyQualifiedJavaType . getStringInstance ( ) ) ; columnField . setVisibility ( JavaVisibility . PRIVATE ) ; columnField . setFinal ( true ) ; commentGenerator . addFieldComment ( columnField , introspectedTable ) ; innerEnum . addField ( columnField ) ; Field isColumnNameDelimitedField = new Field ( "isColumnNameDelimited" , FullyQualifiedJavaType . getBooleanPrimitiveInstance ( ) ) ; isColumnNameDelimitedField . setVisibility ( JavaVisibility . PRIVATE ) ; isColumnNameDelimitedField . setFinal ( true ) ; commentGenerator . addFieldComment ( isColumnNameDelimitedField , introspectedTable ) ; innerEnum . addField ( isColumnNameDelimitedField ) ; Field javaPropertyField = new Field ( "javaProperty" , FullyQualifiedJavaType . getStringInstance ( ) ) ; javaPropertyField . setVisibility ( JavaVisibility . PRIVATE ) ; javaPropertyField . setFinal ( true ) ; commentGenerator . addFieldComment ( javaPropertyField , introspectedTable ) ; innerEnum . addField ( javaPropertyField ) ; Field jdbcTypeField = new Field ( "jdbcType" , FullyQualifiedJavaType . getStringInstance ( ) ) ; jdbcTypeField . setVisibility ( JavaVisibility . PRIVATE ) ; jdbcTypeField . setFinal ( true ) ; commentGenerator . addFieldComment ( jdbcTypeField , introspectedTable ) ; innerEnum . addField ( jdbcTypeField ) ; Method mValue = new Method ( "value" ) ; mValue . setVisibility ( JavaVisibility . PUBLIC ) ; mValue . setReturnType ( FullyQualifiedJavaType . getStringInstance ( ) ) ; mValue . addBodyLine ( "return this.column;" ) ; commentGenerator . addGeneralMethodComment ( mValue , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , mValue ) ; Method mGetValue = new Method ( "getValue" ) ; mGetValue . setVisibility ( JavaVisibility . PUBLIC ) ; mGetValue . setReturnType ( FullyQualifiedJavaType . getStringInstance ( ) ) ; mGetValue . addBodyLine ( "return this.column;" ) ; commentGenerator . addGeneralMethodComment ( mGetValue , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , mGetValue ) ; Method mGetJavaProperty = JavaElementGeneratorTools . generateGetterMethod ( javaPropertyField ) ; commentGenerator . addGeneralMethodComment ( mGetJavaProperty , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , mGetJavaProperty ) ; Method mGetJdbcType = JavaElementGeneratorTools . generateGetterMethod ( jdbcTypeField ) ; commentGenerator . addGeneralMethodComment ( mGetJdbcType , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , mGetJdbcType ) ; Method constructor = new Method ( ENUM_NAME ) ; constructor . setConstructor ( true ) ; constructor . addBodyLine ( "this.column = column;" ) ; constructor . addBodyLine ( "this.javaProperty = javaProperty;" ) ; constructor . addBodyLine ( "this.jdbcType = jdbcType;" ) ; constructor . addBodyLine ( "this.isColumnNameDelimited = isColumnNameDelimited;" ) ; constructor . addParameter ( new Parameter ( FullyQualifiedJavaType . getStringInstance ( ) , "column" ) ) ; constructor . addParameter ( new Parameter ( FullyQualifiedJavaType . getStringInstance ( ) , "javaProperty" ) ) ; constructor . addParameter ( new Parameter ( FullyQualifiedJavaType . getStringInstance ( ) , "jdbcType" ) ) ; constructor . addParameter ( new Parameter ( FullyQualifiedJavaType . getBooleanPrimitiveInstance ( ) , "isColumnNameDelimited" ) ) ; commentGenerator . addGeneralMethodComment ( constructor , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , constructor ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + ".Column增加构造方法和column属性。" ) ; // Enum枚举
for ( IntrospectedColumn introspectedColumn : introspectedTable . getAllColumns ( ) ) { Field field = JavaBeansUtil . getJavaBeansField ( introspectedColumn , context , introspectedTable ) ; StringBuffer sb = new StringBuffer ( ) ; sb . append ( field . getName ( ) ) ; sb . append ( "(\"" ) ; sb . append ( introspectedColumn . getActualColumnName ( ) ) ; sb . append ( "\", \"" ) ; sb . append ( introspectedColumn . getJavaProperty ( ) ) ; sb . append ( "\", \"" ) ; sb . append ( introspectedColumn . getJdbcTypeName ( ) ) ; sb . append ( "\", " ) ; sb . append ( introspectedColumn . isColumnNameDelimited ( ) ) ; sb . append ( ")" ) ; innerEnum . addEnumConstant ( sb . toString ( ) ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + ".Column增加" + field . getName ( ) + "枚举。" ) ; } // asc 和 desc 方法
Method desc = new Method ( "desc" ) ; desc . setVisibility ( JavaVisibility . PUBLIC ) ; desc . setReturnType ( FullyQualifiedJavaType . getStringInstance ( ) ) ; desc . addBodyLine ( "return this." + METHOD_GET_ESCAPED_COLUMN_NAME + "() + \" DESC\";" ) ; commentGenerator . addGeneralMethodComment ( desc , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , desc ) ; Method asc = new Method ( "asc" ) ; asc . setVisibility ( JavaVisibility . PUBLIC ) ; asc . setReturnType ( FullyQualifiedJavaType . getStringInstance ( ) ) ; asc . addBodyLine ( "return this." + METHOD_GET_ESCAPED_COLUMN_NAME + "() + \" ASC\";" ) ; commentGenerator . addGeneralMethodComment ( asc , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( innerEnum , asc ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + ".Column增加asc()和desc()方法。" ) ; // excludes
topLevelClass . addImportedType ( "java.util.Arrays" ) ; topLevelClass . addImportedType ( FullyQualifiedJavaType . getNewArrayListInstance ( ) ) ; Method mExcludes = JavaElementGeneratorTools . generateMethod ( METHOD_EXCLUDES , JavaVisibility . PUBLIC , new FullyQualifiedJavaType ( ENUM_NAME + "[]" ) , new Parameter ( innerEnum . getType ( ) , "excludes" , true ) ) ; commentGenerator . addGeneralMethodComment ( mExcludes , introspectedTable ) ; mExcludes . setStatic ( true ) ; JavaElementGeneratorTools . generateMethodBody ( mExcludes , "ArrayList<Column> columns = new ArrayList<>(Arrays.asList(Column.values()));" , "if (excludes != null && excludes.length > 0) {" , "columns.removeAll(new ArrayList<>(Arrays.asList(excludes)));" , "}" , "return columns.toArray(new Column[]{});" ) ; FormatTools . addMethodWithBestPosition ( innerEnum , mExcludes ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + ".Column增加excludes方法。" ) ; // getEscapedColumnName
Method mGetEscapedColumnName = JavaElementGeneratorTools . generateMethod ( METHOD_GET_ESCAPED_COLUMN_NAME , JavaVisibility . PUBLIC , FullyQualifiedJavaType . getStringInstance ( ) ) ; commentGenerator . addGeneralMethodComment ( mGetEscapedColumnName , introspectedTable ) ; JavaElementGeneratorTools . generateMethodBody ( mGetEscapedColumnName , "if (this.isColumnNameDelimited) {" , "return new StringBuilder().append(" + CONST_BEGINNING_DELIMITER + ").append(this.column).append(" + CONST_ENDING_DELIMITER + ").toString();" , "} else {" , "return this.column;" , "}" ) ; FormatTools . addMethodWithBestPosition ( innerEnum , mGetEscapedColumnName ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + ".Column增加getEscapedColumnName方法。" ) ; // getAliasedEscapedColumnName
Method mGetAliasedEscapedColumnName = JavaElementGeneratorTools . generateMethod ( METHOD_GET_ALIASED_ESCAPED_COLUMN_NAME , JavaVisibility . PUBLIC , FullyQualifiedJavaType . getStringInstance ( ) ) ; commentGenerator . addGeneralMethodComment ( mGetAliasedEscapedColumnName , introspectedTable ) ; if ( StringUtility . stringHasValue ( introspectedTable . getTableConfiguration ( ) . getAlias ( ) ) ) { String alias = introspectedTable . getTableConfiguration ( ) . getAlias ( ) ; mGetAliasedEscapedColumnName . addBodyLine ( "StringBuilder sb = new StringBuilder();" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(\"" + alias + ".\");" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(this." + METHOD_GET_ESCAPED_COLUMN_NAME + "());" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(\" as \");" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "if (this.isColumnNameDelimited) {" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(" + CONST_BEGINNING_DELIMITER + ");" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "}" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(\"" + alias + "_\");" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(this.column);" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "if (this.isColumnNameDelimited) {" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "sb.append(" + CONST_BEGINNING_DELIMITER + ");" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "}" ) ; mGetAliasedEscapedColumnName . addBodyLine ( "return sb.toString();" ) ; } else { mGetAliasedEscapedColumnName . addBodyLine ( "return this." + METHOD_GET_ESCAPED_COLUMN_NAME + "();" ) ; } FormatTools . addMethodWithBestPosition ( innerEnum , mGetAliasedEscapedColumnName ) ; logger . debug ( "itfsw(数据Model属性对应Column获取插件):" + topLevelClass . getType ( ) . getShortName ( ) + ".Column增加getAliasedEscapedColumnName方法。" ) ; return innerEnum ;


signature:
public class LimitPlugin { /** * { @ inheritDoc } */
@ Override public boolean validate ( List < String > warnings ) { } }

implementation:
// 该插件只支持MYSQL
if ( "com.mysql.jdbc.Driver" . equalsIgnoreCase ( this . getContext ( ) . getJdbcConnectionConfiguration ( ) . getDriverClass ( ) ) == false && "com.mysql.cj.jdbc.Driver" . equalsIgnoreCase ( this . getContext ( ) . getJdbcConnectionConfiguration ( ) . getDriverClass ( ) ) == false ) { warnings . add ( "itfsw:插件" + this . getClass ( ) . getTypeName ( ) + "只支持MySQL数据库！" ) ; return false ; } return super . validate ( warnings ) ;


signature:
public class LimitPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param introspectedTable */
@ Override public void initialized ( IntrospectedTable introspectedTable ) { } }

implementation:
super . initialized ( introspectedTable ) ; // 获取配置
String startPage = this . getProperties ( ) . getProperty ( LimitPlugin . PRO_START_PAGE ) ; if ( StringUtility . stringHasValue ( startPage ) ) { this . startPage = Integer . valueOf ( startPage ) ; } else { this . startPage = DEFAULT_START_PAGE ; }


signature:
public class LimitPlugin { /** * ModelExample Methods 生成
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelExampleClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType . getIntInstance ( ) . getPrimitiveTypeWrapper ( ) ; // 添加offset和rows字段
Field offsetField = JavaElementGeneratorTools . generateField ( "offset" , JavaVisibility . PROTECTED , integerWrapper , null ) ; commentGenerator . addFieldComment ( offsetField , introspectedTable ) ; topLevelClass . addField ( offsetField ) ; Field rowsField = JavaElementGeneratorTools . generateField ( "rows" , JavaVisibility . PROTECTED , integerWrapper , null ) ; commentGenerator . addFieldComment ( rowsField , introspectedTable ) ; topLevelClass . addField ( rowsField ) ; logger . debug ( "itfsw(MySQL分页插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加offset和rows字段" ) ; // 增加getter & & setter 方法
Method mSetOffset = JavaElementGeneratorTools . generateSetterMethod ( offsetField ) ; commentGenerator . addGeneralMethodComment ( mSetOffset , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , mSetOffset ) ; Method mGetOffset = JavaElementGeneratorTools . generateGetterMethod ( offsetField ) ; commentGenerator . addGeneralMethodComment ( mGetOffset , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , mGetOffset ) ; Method mSetRows = JavaElementGeneratorTools . generateSetterMethod ( rowsField ) ; commentGenerator . addGeneralMethodComment ( mSetRows , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , mSetRows ) ; Method mGetRows = JavaElementGeneratorTools . generateGetterMethod ( rowsField ) ; commentGenerator . addGeneralMethodComment ( mGetRows , introspectedTable ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , mGetRows ) ; logger . debug ( "itfsw(MySQL分页插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加offset和rows的getter和setter实现。" ) ; // 提供几个快捷方法
Method setLimit = JavaElementGeneratorTools . generateMethod ( "limit" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) , new Parameter ( integerWrapper , "rows" ) ) ; commentGenerator . addGeneralMethodComment ( setLimit , introspectedTable ) ; setLimit = JavaElementGeneratorTools . generateMethodBody ( setLimit , "this.rows = rows;" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , setLimit ) ; Method setLimit2 = JavaElementGeneratorTools . generateMethod ( "limit" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) , new Parameter ( integerWrapper , "offset" ) , new Parameter ( integerWrapper , "rows" ) ) ; commentGenerator . addGeneralMethodComment ( setLimit2 , introspectedTable ) ; setLimit2 = JavaElementGeneratorTools . generateMethodBody ( setLimit2 , "this.offset = offset;" , "this.rows = rows;" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , setLimit2 ) ; logger . debug ( "itfsw(MySQL分页插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加limit方法。" ) ; Method setPage = JavaElementGeneratorTools . generateMethod ( "page" , JavaVisibility . PUBLIC , topLevelClass . getType ( ) , new Parameter ( integerWrapper , "page" ) , new Parameter ( integerWrapper , "pageSize" ) ) ; commentGenerator . addGeneralMethodComment ( setPage , introspectedTable ) ; setPage = JavaElementGeneratorTools . generateMethodBody ( setPage , "this.offset = " + ( this . startPage == 0 ? "page" : "(page - " + this . startPage + ")" ) + " * pageSize;" , "this.rows = pageSize;" , "return this;" ) ; FormatTools . addMethodWithBestPosition ( topLevelClass , setPage ) ; logger . debug ( "itfsw(MySQL分页插件):" + topLevelClass . getType ( ) . getShortName ( ) + "增加page方法" ) ; // ! ! ! clear 方法增加 offset 和 rows的清理
List < Method > methodList = topLevelClass . getMethods ( ) ; for ( Method method : methodList ) { if ( method . getName ( ) . equals ( "clear" ) ) { method . addBodyLine ( "rows = null;" ) ; method . addBodyLine ( "offset = null;" ) ; logger . debug ( "itfsw(MySQL分页插件):" + topLevelClass . getType ( ) . getShortName ( ) + "修改clear方法,增加rows和offset字段的清空" ) ; } } return true ;


signature:
public class LimitPlugin { /** * = = = = = ISelectSelectivePluginHook = = = = = */
@ Override public boolean sqlMapSelectByExampleSelectiveElementGenerated ( Document document , XmlElement element , IntrospectedTable introspectedTable ) { } }

implementation: this . generateLimitElementWithExample ( element ) ; return false ;


signature:
public class LimitPlugin { /** * 生成limit节点
 * @ param element */
private void generateLimitElement ( XmlElement element ) { } }

implementation: XmlElement ifLimitNotNullElement = new XmlElement ( "if" ) ; ifLimitNotNullElement . addAttribute ( new Attribute ( "test" , "rows != null" ) ) ; XmlElement ifOffsetNotNullElement = new XmlElement ( "if" ) ; ifOffsetNotNullElement . addAttribute ( new Attribute ( "test" , "offset != null" ) ) ; ifOffsetNotNullElement . addElement ( new TextElement ( "limit ${offset}, ${rows}" ) ) ; ifLimitNotNullElement . addElement ( ifOffsetNotNullElement ) ; XmlElement ifOffsetNullElement = new XmlElement ( "if" ) ; ifOffsetNullElement . addAttribute ( new Attribute ( "test" , "offset == null" ) ) ; ifOffsetNullElement . addElement ( new TextElement ( "limit ${rows}" ) ) ; ifLimitNotNullElement . addElement ( ifOffsetNullElement ) ; element . addElement ( ifLimitNotNullElement ) ;


signature:
public class InnerInterface { /** * 格式化后内容 , 因为是内部接口 , 需要增加缩进
 * @ param indentLevel the indent level
 * @ param compilationUnit the compilation unit
 * @ return the formatted content */
@ Override public String getFormattedContent ( int indentLevel , CompilationUnit compilationUnit ) { } }

implementation: StringBuilder sb = new StringBuilder ( ) ; for ( String commentLine : getFileCommentLines ( ) ) { sb . append ( commentLine ) ; newLine ( sb ) ; } if ( stringHasValue ( getType ( ) . getPackageName ( ) ) ) { sb . append ( "package " ) ; sb . append ( getType ( ) . getPackageName ( ) ) ; sb . append ( ';' ) ; newLine ( sb ) ; newLine ( sb ) ; } for ( String staticImport : getStaticImports ( ) ) { sb . append ( "import static " ) ; sb . append ( staticImport ) ; sb . append ( ';' ) ; newLine ( sb ) ; } if ( getStaticImports ( ) . size ( ) > 0 ) { newLine ( sb ) ; } Set < String > importStrings = calculateImports ( getImportedTypes ( ) ) ; for ( String importString : importStrings ) { sb . append ( importString ) ; newLine ( sb ) ; } if ( importStrings . size ( ) > 0 ) { newLine ( sb ) ; } addFormattedJavadoc ( sb , indentLevel ) ; addFormattedAnnotations ( sb , indentLevel ) ; OutputUtilities . javaIndent ( sb , indentLevel ) ; sb . append ( getVisibility ( ) . getValue ( ) ) ; if ( isFinal ( ) ) { sb . append ( "final " ) ; } sb . append ( "interface " ) ; sb . append ( getType ( ) . getShortName ( ) ) ; if ( getSuperInterfaceTypes ( ) . size ( ) > 0 ) { sb . append ( " extends " ) ; boolean comma = false ; for ( FullyQualifiedJavaType fqjt : getSuperInterfaceTypes ( ) ) { if ( comma ) { sb . append ( ", " ) ; } else { comma = true ; } sb . append ( JavaDomUtils . calculateTypeName ( this , fqjt ) ) ; } } sb . append ( " {" ) ; indentLevel ++ ; Iterator < Method > mtdIter = getMethods ( ) . iterator ( ) ; while ( mtdIter . hasNext ( ) ) { newLine ( sb ) ; Method method = mtdIter . next ( ) ; sb . append ( method . getFormattedContent ( indentLevel , true , this ) ) ; if ( mtdIter . hasNext ( ) ) { newLine ( sb ) ; } } indentLevel -- ; newLine ( sb ) ; javaIndent ( sb , indentLevel ) ; sb . append ( '}' ) ; return sb . toString ( ) ;


signature:
public class IntrospectedTableTools { /** * 设置DomainObjectName和MapperName
 * @ param introspectedTable
 * @ param context
 * @ param domainObjectName */
public static void setDomainObjectName ( IntrospectedTable introspectedTable , Context context , String domainObjectName ) throws NoSuchFieldException , IllegalAccessException , NoSuchMethodException , InvocationTargetException { } }

implementation:
// 配置信息 ( 没啥用 )
introspectedTable . getTableConfiguration ( ) . setDomainObjectName ( domainObjectName ) ; // FullyQualifiedTable修正
Field domainObjectNameField = FullyQualifiedTable . class . getDeclaredField ( "domainObjectName" ) ; domainObjectNameField . setAccessible ( true ) ; domainObjectNameField . set ( introspectedTable . getFullyQualifiedTable ( ) , domainObjectName ) ; // 重新修正introspectedTable属性信息
Method calculateJavaClientAttributes = IntrospectedTable . class . getDeclaredMethod ( "calculateJavaClientAttributes" ) ; calculateJavaClientAttributes . setAccessible ( true ) ; calculateJavaClientAttributes . invoke ( introspectedTable ) ; Method calculateModelAttributes = IntrospectedTable . class . getDeclaredMethod ( "calculateModelAttributes" ) ; calculateModelAttributes . setAccessible ( true ) ; calculateModelAttributes . invoke ( introspectedTable ) ; Method calculateXmlAttributes = IntrospectedTable . class . getDeclaredMethod ( "calculateXmlAttributes" ) ; calculateXmlAttributes . setAccessible ( true ) ; calculateXmlAttributes . invoke ( introspectedTable ) ; // 注意 ! ! 如果配置了ExampleTargetPlugin插件 , 要修正Example 位置
PluginConfiguration configuration = PluginTools . getPluginConfiguration ( context , ExampleTargetPlugin . class ) ; if ( configuration != null && configuration . getProperty ( ExampleTargetPlugin . PRO_TARGET_PACKAGE ) != null ) { String exampleType = introspectedTable . getExampleType ( ) ; // 修改包名
JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = context . getJavaModelGeneratorConfiguration ( ) ; String targetPackage = javaModelGeneratorConfiguration . getTargetPackage ( ) ; String newExampleType = exampleType . replace ( targetPackage , configuration . getProperty ( ExampleTargetPlugin . PRO_TARGET_PACKAGE ) ) ; introspectedTable . setExampleType ( newExampleType ) ; }


signature:
public class IntrospectedTableTools { /** * 安全获取column 通过正则获取的name可能包含beginningDelimiter & & endingDelimiter
 * @ param introspectedTable
 * @ param columnName
 * @ return */
public static IntrospectedColumn safeGetColumn ( IntrospectedTable introspectedTable , String columnName ) { } }

implementation:
// columnName
columnName = columnName . trim ( ) ; // 过滤
String beginningDelimiter = introspectedTable . getContext ( ) . getBeginningDelimiter ( ) ; if ( StringUtility . stringHasValue ( beginningDelimiter ) ) { columnName = columnName . replaceFirst ( "^" + beginningDelimiter , "" ) ; } String endingDelimiter = introspectedTable . getContext ( ) . getEndingDelimiter ( ) ; if ( StringUtility . stringHasValue ( endingDelimiter ) ) { columnName = columnName . replaceFirst ( endingDelimiter + "$" , "" ) ; } return introspectedTable . getColumn ( columnName ) ;


signature:
public class IntrospectedTableTools { /** * 获取生成model baseRecord的列
 * @ param introspectedTable
 * @ return */
public static List < IntrospectedColumn > getModelBaseRecordClomns ( IntrospectedTable introspectedTable ) { } }

implementation: List < IntrospectedColumn > introspectedColumns ; if ( includePrimaryKeyColumns ( introspectedTable ) ) { if ( includeBLOBColumns ( introspectedTable ) ) { introspectedColumns = introspectedTable . getAllColumns ( ) ; } else { introspectedColumns = introspectedTable . getNonBLOBColumns ( ) ; } } else { if ( includeBLOBColumns ( introspectedTable ) ) { introspectedColumns = introspectedTable . getNonPrimaryKeyColumns ( ) ; } else { introspectedColumns = introspectedTable . getBaseColumns ( ) ; } } return introspectedColumns ;


signature:
public class LombokPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param warnings
 * @ return */
@ Override public boolean validate ( List < String > warnings ) { } }

implementation: Properties properties = this . getProperties ( ) ; String builder = properties . getProperty ( PRO_BUILDER ) ; String allArgsConstructor = properties . getProperty ( PRO_ALL_ARGS_CONSTRUCTOR ) ; String noArgsConstructor = properties . getProperty ( PRO_NO_ARGS_CONSTRUCTOR ) ; this . hasBuilder = builder == null ? false : StringUtility . isTrue ( builder ) ; this . hasAllArgsConstructor = allArgsConstructor == null ? false : StringUtility . isTrue ( allArgsConstructor ) ; this . hasNoArgsConstructor = noArgsConstructor == null ? false : StringUtility . isTrue ( noArgsConstructor ) ; return super . validate ( warnings ) ;


signature:
public class LombokPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelBaseRecordClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// @ Data
this . addAnnotations ( topLevelClass , EnumLombokAnnotations . DATA ) ; if ( topLevelClass . getSuperClass ( ) != null ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . EQUALS_AND_HASH_CODE_CALL_SUPER ) ; this . addAnnotations ( topLevelClass , EnumLombokAnnotations . TO_STRING_CALL_SUPER ) ; } // @ Builder
List < IntrospectedColumn > columns = IntrospectedTableTools . getModelBaseRecordClomns ( introspectedTable ) ; if ( this . hasBuilder && PluginTools . getHook ( ILombokPluginHook . class ) . modelBaseRecordBuilderClassGenerated ( topLevelClass , columns , introspectedTable ) ) { // 有子类或者父类
if ( introspectedTable . getRules ( ) . generateRecordWithBLOBsClass ( ) || introspectedTable . getRules ( ) . generatePrimaryKeyClass ( ) || topLevelClass . getSuperClass ( ) != null ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . SUPER_BUILDER ) ; } else { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . BUILDER ) ; } } // @ Constructor
if ( this . hasNoArgsConstructor ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . NO_ARGS_CONSTRUCTOR ) ; } if ( this . hasAllArgsConstructor ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . ALL_ARGS_CONSTRUCTOR ) ; } return super . modelBaseRecordClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class LombokPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelPrimaryKeyClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// @ Data
this . addAnnotations ( topLevelClass , EnumLombokAnnotations . DATA ) ; if ( topLevelClass . getSuperClass ( ) != null ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . EQUALS_AND_HASH_CODE_CALL_SUPER ) ; this . addAnnotations ( topLevelClass , EnumLombokAnnotations . TO_STRING_CALL_SUPER ) ; } // @ Builder
List < IntrospectedColumn > columns = introspectedTable . getPrimaryKeyColumns ( ) ; if ( this . hasBuilder && PluginTools . getHook ( ILombokPluginHook . class ) . modelPrimaryKeyBuilderClassGenerated ( topLevelClass , columns , introspectedTable ) ) { // 有子类或者父类
if ( introspectedTable . getRules ( ) . generateRecordWithBLOBsClass ( ) || introspectedTable . getRules ( ) . generateBaseRecordClass ( ) || topLevelClass . getSuperClass ( ) != null ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . SUPER_BUILDER ) ; } else { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . BUILDER ) ; } } // @ Constructor
if ( this . hasNoArgsConstructor ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . NO_ARGS_CONSTRUCTOR ) ; } if ( this . hasAllArgsConstructor ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . ALL_ARGS_CONSTRUCTOR ) ; } return super . modelPrimaryKeyClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class LombokPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param topLevelClass
 * @ param introspectedTable
 * @ return */
@ Override public boolean modelRecordWithBLOBsClassGenerated ( TopLevelClass topLevelClass , IntrospectedTable introspectedTable ) { } }

implementation:
// @ Data
this . addAnnotations ( topLevelClass , EnumLombokAnnotations . DATA ) ; if ( topLevelClass . getSuperClass ( ) != null ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . EQUALS_AND_HASH_CODE_CALL_SUPER ) ; this . addAnnotations ( topLevelClass , EnumLombokAnnotations . TO_STRING_CALL_SUPER ) ; } // @ Builder
List < IntrospectedColumn > columns = introspectedTable . getBLOBColumns ( ) ; if ( this . hasBuilder && PluginTools . getHook ( ILombokPluginHook . class ) . modelRecordWithBLOBsBuilderClassGenerated ( topLevelClass , columns , introspectedTable ) ) { // 有子类或者父类
if ( introspectedTable . getRules ( ) . generateBaseRecordClass ( ) || introspectedTable . getRules ( ) . generatePrimaryKeyClass ( ) || topLevelClass . getSuperClass ( ) != null ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . SUPER_BUILDER ) ; } else { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . BUILDER ) ; } } // @ Constructor
if ( this . hasNoArgsConstructor ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . NO_ARGS_CONSTRUCTOR ) ; } if ( this . hasAllArgsConstructor ) { this . addAnnotations ( topLevelClass , EnumLombokAnnotations . ALL_ARGS_CONSTRUCTOR ) ; } return super . modelRecordWithBLOBsClassGenerated ( topLevelClass , introspectedTable ) ;


signature:
public class LombokPlugin { /** * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param method
 * @ param topLevelClass
 * @ param introspectedColumn
 * @ param introspectedTable
 * @ param modelClassType
 * @ return */
@ Override public boolean modelSetterMethodGenerated ( Method method , TopLevelClass topLevelClass , IntrospectedColumn introspectedColumn , IntrospectedTable introspectedTable , ModelClassType modelClassType ) { } }

implementation: return false ;


signature:
public class LombokPlugin { /** * 添加注解
 * @ param topLevelClass
 * @ param annotations */
private void addAnnotations ( TopLevelClass topLevelClass , EnumLombokAnnotations annotations ) { } }

implementation: topLevelClass . addImportedType ( annotations . getClazz ( ) ) ; topLevelClass . addAnnotation ( annotations . getAnnotation ( ) ) ;


signature:
public class TablePrefixPlugin { /** * { @ inheritDoc } */
@ Override public boolean validate ( List < String > warnings ) { } }

implementation:
// 如果table配置了domainObjectName或者mapperName就不要再启动该插件了
for ( TableConfiguration tableConfiguration : context . getTableConfigurations ( ) ) { if ( tableConfiguration . getDomainObjectName ( ) != null || tableConfiguration . getMapperName ( ) != null ) { warnings . add ( "itfsw:插件" + this . getClass ( ) . getTypeName ( ) + "插件请不要配合table的domainObjectName或者mapperName一起使用！" ) ; return false ; } } return super . validate ( warnings ) ;


signature:
public class TablePrefixPlugin { /** * 初始化阶段
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param introspectedTable
 * @ return */
@ Override public void initialized ( IntrospectedTable introspectedTable ) { } }

implementation:
// 1 . 首先获取全局配置
this . prefix = getProperties ( ) . getProperty ( PRO_PREFIX ) ; // 2 . 获取每个table 具体的
if ( introspectedTable . getTableConfigurationProperty ( PRO_PREFIX ) != null ) { this . prefix = introspectedTable . getTableConfigurationProperty ( PRO_PREFIX ) ; } // 3 . 判断是否配置了前缀
// ! ! ! TableRenamePlugin 插件的 tableOverride 优先级最高
if ( this . prefix != null && introspectedTable . getTableConfigurationProperty ( TableRenamePlugin . PRO_TABLE_OVERRIDE ) == null ) { String domainObjectName = introspectedTable . getFullyQualifiedTable ( ) . getDomainObjectName ( ) ; domainObjectName = prefix + domainObjectName ; try { IntrospectedTableTools . setDomainObjectName ( introspectedTable , getContext ( ) , domainObjectName ) ; } catch ( Exception e ) { logger . error ( "itfsw:插件" + this . getClass ( ) . getTypeName ( ) + "使用prefix替换时异常！" , e ) ; } } super . initialized ( introspectedTable ) ;


signature:
public class SelectiveEnhancedPlugin { /** * insertSelective 方法生成
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param method
 * @ param interfaze
 * @ param introspectedTable
 * @ return */
@ Override public boolean clientInsertSelectiveMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation:
method . getParameters ( ) . clear ( ) ; FullyQualifiedJavaType parameterType = introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) ; method . addParameter ( new Parameter ( parameterType , "record" , "@Param(\"record\")" ) ) ; // 找出全字段对应的Model
FullyQualifiedJavaType fullFieldModel = introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) ; // column枚举
FullyQualifiedJavaType selectiveType = new FullyQualifiedJavaType ( fullFieldModel . getShortName ( ) + "." + ModelColumnPlugin . ENUM_NAME ) ; method . addParameter ( new Parameter ( selectiveType , "selective" , "@Param(\"selective\")" , true ) ) ; FormatTools . replaceGeneralMethodComment ( commentGenerator , method , introspectedTable ) ; return super . clientInsertSelectiveMethodGenerated ( method , interfaze , introspectedTable ) ;


signature:
public class SelectiveEnhancedPlugin { /** * insertSelective
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param element
 * @ param introspectedTable
 * @ return */
@ Override public boolean sqlMapInsertSelectiveElementGenerated ( XmlElement element , IntrospectedTable introspectedTable ) { } }

implementation:
// 清空
XmlElement answer = new XmlElement ( "insert" ) ; answer . addAttribute ( new Attribute ( "id" , introspectedTable . getInsertSelectiveStatementId ( ) ) ) ; answer . addAttribute ( new Attribute ( "parameterType" , "map" ) ) ; commentGenerator . addComment ( answer ) ; GeneratedKey gk = introspectedTable . getGeneratedKey ( ) ; if ( gk != null ) { IntrospectedColumn introspectedColumn = introspectedTable . getColumn ( gk . getColumn ( ) ) ; // if the column is null , then it ' s a configuration error . The
// warning has already been reported
if ( introspectedColumn != null ) { if ( gk . isJdbcStandard ( ) ) { XmlElementGeneratorTools . useGeneratedKeys ( answer , introspectedTable , "record." ) ; } else { answer . addElement ( XmlElementGeneratorTools . getSelectKey ( introspectedColumn , gk , "record." ) ) ; } } } StringBuilder sb = new StringBuilder ( ) ; sb . append ( "insert into " ) ; sb . append ( introspectedTable . getFullyQualifiedTableNameAtRuntime ( ) ) ; answer . addElement ( new TextElement ( sb . toString ( ) ) ) ; // columns
answer . addElement ( this . generateInsertColumnSelective ( ListUtilities . removeIdentityAndGeneratedAlwaysColumns ( introspectedTable . getAllColumns ( ) ) ) ) ; // values
answer . addElement ( new TextElement ( "values" ) ) ; answer . addElement ( this . generateInsertValuesSelective ( ListUtilities . removeIdentityAndGeneratedAlwaysColumns ( introspectedTable . getAllColumns ( ) ) ) ) ; XmlElementTools . replaceXmlElement ( element , answer ) ; return super . sqlMapInsertSelectiveElementGenerated ( element , introspectedTable ) ;


signature:
public class SelectiveEnhancedPlugin { /** * updateByExampleSelective
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param element
 * @ param introspectedTable
 * @ return */
@ Override public boolean sqlMapUpdateByExampleSelectiveElementGenerated ( XmlElement element , IntrospectedTable introspectedTable ) { } }

implementation:
// 清空
XmlElement answer = new XmlElement ( "update" ) ; answer . addAttribute ( new Attribute ( "id" , introspectedTable . getUpdateByExampleSelectiveStatementId ( ) ) ) ; answer . addAttribute ( new Attribute ( "parameterType" , "map" ) ) ; commentGenerator . addComment ( answer ) ; StringBuilder sb = new StringBuilder ( ) ; sb . append ( "update " ) ; sb . append ( introspectedTable . getAliasedFullyQualifiedTableNameAtRuntime ( ) ) ; answer . addElement ( new TextElement ( sb . toString ( ) ) ) ; // selective
answer . addElement ( new TextElement ( "SET" ) ) ; answer . addElement ( this . generateSetsSelective ( ListUtilities . removeGeneratedAlwaysColumns ( introspectedTable . getAllColumns ( ) ) ) ) ; answer . addElement ( XmlElementGeneratorTools . getUpdateByExampleIncludeElement ( introspectedTable ) ) ; XmlElementTools . replaceXmlElement ( element , answer ) ; return super . sqlMapUpdateByExampleSelectiveElementGenerated ( element , introspectedTable ) ;


signature:
public class SelectiveEnhancedPlugin { /** * updateByPrimaryKeySelective
 * 具体执行顺序 http : / / www . mybatis . org / generator / reference / pluggingIn . html
 * @ param element
 * @ param introspectedTable
 * @ return */
@ Override public boolean sqlMapUpdateByPrimaryKeySelectiveElementGenerated ( XmlElement element , IntrospectedTable introspectedTable ) { } }

implementation:
// 清空
XmlElement answer = new XmlElement ( "update" ) ; answer . addAttribute ( new Attribute ( "id" , introspectedTable . getUpdateByPrimaryKeySelectiveStatementId ( ) ) ) ; answer . addAttribute ( new Attribute ( "parameterType" , "map" ) ) ; commentGenerator . addComment ( answer ) ; StringBuilder sb = new StringBuilder ( ) ; sb . append ( "update " ) ; sb . append ( introspectedTable . getFullyQualifiedTableNameAtRuntime ( ) ) ; answer . addElement ( new TextElement ( sb . toString ( ) ) ) ; // selective
answer . addElement ( new TextElement ( "SET" ) ) ; answer . addElement ( this . generateSetsSelective ( ListUtilities . removeGeneratedAlwaysColumns ( introspectedTable . getNonPrimaryKeyColumns ( ) ) ) ) ; XmlElementGeneratorTools . generateWhereByPrimaryKeyTo ( answer , introspectedTable . getPrimaryKeyColumns ( ) , "record." ) ; XmlElementTools . replaceXmlElement ( element , answer ) ; return super . sqlMapUpdateByPrimaryKeySelectiveElementGenerated ( element , introspectedTable ) ;


signature:
public class SelectiveEnhancedPlugin { /** * upsertSelective 方法
 * @ param method
 * @ param interfaze
 * @ param introspectedTable
 * @ return */
@ Override public boolean clientUpsertSelectiveMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation:
// @ Param ( " record " )
method . getParameters ( ) . get ( 0 ) . addAnnotation ( "@Param(\"record\")" ) ; // column枚举
// 找出全字段对应的Model
FullyQualifiedJavaType fullFieldModel = introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) ; FullyQualifiedJavaType selectiveType = new FullyQualifiedJavaType ( fullFieldModel . getShortName ( ) + "." + ModelColumnPlugin . ENUM_NAME ) ; method . addParameter ( new Parameter ( selectiveType , "selective" , "@Param(\"selective\")" , true ) ) ; return true ;


signature:
public class SelectiveEnhancedPlugin { /** * upsertByExampleSelective 方法
 * @ param method
 * @ param interfaze
 * @ param introspectedTable
 * @ return */
@ Override public boolean clientUpsertByExampleSelectiveMethodGenerated ( Method method , Interface interfaze , IntrospectedTable introspectedTable ) { } }

implementation:
// column枚举
// 找出全字段对应的Model
FullyQualifiedJavaType fullFieldModel = introspectedTable . getRules ( ) . calculateAllFieldsClass ( ) ; FullyQualifiedJavaType selectiveType = new FullyQualifiedJavaType ( fullFieldModel . getShortName ( ) + "." + ModelColumnPlugin . ENUM_NAME ) ; method . addParameter ( new Parameter ( selectiveType , "selective" , "@Param(\"selective\")" , true ) ) ; return true ;