com.viiyue.plugins.mybatis.template.TemplateBuilderFactory Maven / Gradle / Ivy
Show all versions of mybatis-mapper Show documentation
/**
* Copyright (C) 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viiyue.plugins.mybatis.template;
import org.apache.ibatis.mapping.SqlCommandType;
import com.viiyue.plugins.mybatis.metadata.Entity;
import com.viiyue.plugins.mybatis.metadata.EntityParser;
import com.viiyue.plugins.mybatis.template.builder.ColumnBuilder;
import com.viiyue.plugins.mybatis.template.builder.ColumnsBuilder;
import com.viiyue.plugins.mybatis.template.builder.LogicallyDeleteBuilder;
import com.viiyue.plugins.mybatis.template.builder.MappingBuilder;
import com.viiyue.plugins.mybatis.template.builder.OptimisticLockBuilder;
import com.viiyue.plugins.mybatis.template.builder.OrderByBuilder;
import com.viiyue.plugins.mybatis.template.builder.TableBuilder;
import com.viiyue.plugins.mybatis.template.builder.UpdateSetBuilder;
import com.viiyue.plugins.mybatis.template.builder.ValuesBuilder;
import com.viiyue.plugins.mybatis.template.builder.WhereBuilder;
/**
* The parsing builder factory of the template syntax for parsing the various
* template syntaxes that appear in the template text.
*
* @author tangxbai
* @since 1.1.0
*/
public final class TemplateBuilderFactory {
/** Model bean parsing object */
private final Entity entity;
/** SQL statement command type */
private final SqlCommandType commandType;
/**
* Internal instantiation template factory object for parsing template
* syntax that appears in the template engine
*
* @param modelBeanType model bean parsing object
* @param commandType SQL command type
*/
private TemplateBuilderFactory( Class> modelBeanType, SqlCommandType commandType ) {
this.entity = EntityParser.getEntity( modelBeanType );
this.commandType = commandType;
}
/**
* Instantiate a template factory object to parse the template syntax that
* appears in the template engine
*
* @param modelBeanType model bean parsing object
* @param commandType SQL command type
* @return template builder factory
*/
public static TemplateBuilderFactory build( Class> modelBeanType, SqlCommandType commandType ) {
return new TemplateBuilderFactory( modelBeanType, commandType );
}
/**
*
* The template factory is used to get the current table object, which can
* be used in any scenario in theory, but it is generally used for static
* template compilation.
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.table}
-> t_table_name
* @{this.table.prefix("t")}
-> t.t_table_name
* @{this.table.alias("alias")}
-> t_table_name [as] 'alias'
*
*
* @return table builder
*/
public TableBuilder table() {
return new TableBuilder( entity );
}
/**
*
* The template factory is used to get the primary key, because there is no
* limit to the existence of a primary key in the plugin, so if you do not
* explicitly specify which one to use as the primary key, the first primary
* key is used by default.
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.pk}
-> primary_key
* @{this.pk.prefix("t")}
-> t.primary_key
* @{this.pk.suffix("_xxx")}
-> t.primary_key_xxx
* @{this.pk.alias("ttt")}
-> primary_key [as] 'ttt'
*
*
* @return primary key column builder
*/
public ColumnBuilder pk() {
return new ColumnBuilder( entity ).apply( entity.getDefaultPrimaryKey() );
}
/**
*
* In the template factory, in the case of multiple primary keys, get the
* primary key of the specified subscript
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.pk(Integer)}
-> primary_key
* @{this.pk(Integer).prefix("t")}
-> t.primary_key
* @{this.pk(Integer).suffix("_xxx")}
-> t.primary_key_xxx
* @{this.pk(Integer).alias("ttt")}
-> primary_key [as] 'ttt'
*
*
* @param index primary key index
* @return primary key column builder
*/
public ColumnBuilder pk( int index ) {
return new ColumnBuilder( entity ).apply( entity.getPrimaryKey( index ) );
}
/**
*
* Used in the template factory to get all the columns of the table
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.columns}
-> id, name, column
* @{this.columns.prefix("t")}
-> t.id, t.name, t.column
* @{this.columns.dynamic(Object)}
-> id, name ( Select all non-null attributes )
* @{this.columns.include("id")}
-> id
* @{this.columns.include("id")}
-> name
*
*
* @param index primary key index
* @return property column builder
*/
public ColumnsBuilder columns() {
return new ColumnsBuilder( entity, commandType );
}
// ---------------------- How to get the column? ------------------------------
// /**
// *
// * The column builder object used to get the specified property name in the
// * template factory
// *
// *
// * In theory it can be used in any scenario, but it is usually used for
// * static template compilation.
// *
// *
// * @{this.column("yourPropertyName").prefix("t")}
-> t.your_property_name
// * @{this.column("yourPropertyName").suffix("_xxx")}
-> t.your_property_name_xxx
// * @{this.column("yourPropertyName").alias("ttt")}
-> t.your_property_name [as] 'ttt'
// * @{this.column("yourPropertyName").property}
-> yourPropertyName
// * @{this.column("yourPropertyName").jdbcType}
-> VARCHAR ( See the actual situation )
// * @{this.column("yourPropertyName").javaType}
-> String ( See the actual situation )
// *
// *
// * @param propertyName property name
// * @return property column builder
// */
// // Method 1:
// // Is it too complicated? ...
// // Example: this.column( String ) -> this.column( 'propertyName' )
// public ColumnBuilder column( String propertyName ) {
// return new ColumnBuilder( entity ).apply( entity.getProperty( propertyName ) );
// }
/**
*
* The column builder object used to get the specified property name in the
* template factory, but this method returns a map builder object
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.column.yourPropertyName}
-> your_property_name
* @{this.column.yourPropertyName.prefix("t")}
-> t.your_property_name
* @{this.column.yourPropertyName.suffix("_xxx")}
-> t.your_property_name_xxx
* @{this.column.yourPropertyName.alias("ttt")}
-> t.your_property_name [as] 'ttt'
* @{this.column.yourPropertyName.property}
-> yourPropertyName
* @{this.column.yourPropertyName.jdbcType}
-> VARCHAR ( See the actual situation )
* @{this.column.yourPropertyName.javaType}
-> String ( See the actual situation )
*
*
* Note: This method is exactly the same as the {@link TemplateBuilderFactory#map() map()} method.
*
* @return property column mapping builder object
* @see #map()
*/
// Method 2
// It seems like this is OK?
// Example: this.column.xxx -> this.column.propertyName
public MappingBuilder column() {
return new MappingBuilder( entity );
}
/**
*
* The column builder object used to get the specified property name in the
* template factory, but this method returns a map builder object
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.map.xxx}
-> xxx
* @{this.map.loginName}
-> login_name
* @{this.map.yourPropertyName}
-> your_property_name
* @{this.map.yourPropertyName.prefix("t")}
-> t.your_property_name
* @{this.map.yourPropertyName.suffix("_xxx")}
-> t.your_property_name_xxx
* @{this.map.yourPropertyName.alias("ttt")}
-> t.your_property_name [as] 'ttt'
* @{this.map.yourPropertyName.property}
-> yourPropertyName
* @{this.map.yourPropertyName.jdbcType}
-> VARCHAR ( See the actual situation )
* @{this.map.yourPropertyName.javaType}
-> String ( See the actual situation )
*
*
* Note: This method is exactly the same as the {@link TemplateBuilderFactory#column() column()} method.
*
* @return property column mapping builder object
* @see #column()
*/
// Method 3:
// Map or column? tangled ...
// Ok, both of them are reserved and can be used normally.
// Example: this.map.xxx -> this.map.propertyName
public MappingBuilder map() {
return new MappingBuilder( entity );
}
// ------------------------------ Get the column ------------------------------
/**
*
* The set value builder object used to generate the update statement in the
* template factory
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.set}
-> id = #{id}, name = #{name}, nick_name = #{nickName}
* @{this.set.prefix("t")}
-> t.id = #{id}, t.name = #{name}, t.nick_name = #{nickName}
* @{this.set.alias("param")}
-> id = #{param.id}, name = #{param.name}, nick_name = #{param.nickName}
* @{this.set.include("id,name")}
-> id = #{param.id}, name = #{param.name}
* @{this.set.exclude("id,name")}
-> nick_name = #{param.nickName}
* @{this.set.dynamic(Object)}
-> id = #{id} ( Select all non-null attributes )
*
*
*
* Note: This method is exactly the same as the
* {@link TemplateBuilderFactory#column() column()} method.
*
* @return set value builder object of update statement
*/
public UpdateSetBuilder set() {
return new UpdateSetBuilder( entity, commandType );
}
/**
*
* All assignment columns used to generate statements in the template
* factory
*
*
* In the actual situation, it may appear in the static template
* compilation. At this time, all the columns will be output, or it may
* appear in the dynamic template compilation, and the dynamic filtering
* needs to use the columns.
*
*
* @{this.values}
-> #{id}, #{name}, #{nickName}
* @{this.values.alias("param")}
-> #{param.id}, #{param.name}, #{param.nickName}
* @{this.values.dynamic(Object)}
-> #{param.name} ( Select all non-null attributes )
* @{this.values.include("id,name")}
-> #{id}, #{name}
* @{this.values.exclude("id,name")}
-> #{nickName}
*
*
* @return statement values builder
*/
public ValuesBuilder values() {
return new ValuesBuilder( entity, commandType );
}
/**
* The where condition used to generate the statement in the template
* factory
*
*
This build object can only be applied to dynamic template compilation.
*
*
* @{this.where(Object)}
-> [where] id = #{id} [and] name = #{name}
*
*
* @param parameter dynamic parameter
* @return query condition builder object
*/
public WhereBuilder where( Object parameter ) {
return new WhereBuilder( entity, commandType, parameter );
}
/**
*
* Used to generate default sort fields in the template factory
*
*
* In theory it can be used in any scenario, but it is usually used for
* static template compilation.
*
*
* @{this.defaultOrderBy}
-> [order by] column [desc]
* @{this.defaultOrderBy.prefix("t")}
-> [order by] t.column [desc]
* @{this.defaultOrderBy.asc}
-> [order by] column [asc]
* @{this.defaultOrderBy.desc}
-> [order by] column [desc]
*
*
* @return order by builder object
*/
public OrderByBuilder defaultOrderBy() {
return new OrderByBuilder( entity );
}
/**
*
* Used to generate a logically delete builder object in a template factory, either
* in an update statement or in a query statement object.
*
*
* @{this.tryLogicallyDelete}
-> logically_delete = #{deleteValue}
* @{this.tryLogicallyDelete.prefix("t")}
-> t.logically_delete = #{deleteValue}
* @{this.tryLogicallyDelete.useWhereQuery}
-> [where] logically_delete = #{selectValue}
* @{this.tryLogicallyDelete.useAndQuery}
-> [and] logically_delete = #{selectValue}
* @{this.tryLogicallyDelete.useOrQuery}
-> [or] logically_delete = #{selectValue}
*
*
* @return logically delete builder object
*/
public LogicallyDeleteBuilder tryLogicallyDelete() {
return new LogicallyDeleteBuilder( entity, commandType );
}
/**
*
* Used to generate an optimistic lock builder object, only valid in the
* modification statement.
*
*
* @{this.tryOptimisticLock}
-> version = #{version}
* @{this.tryOptimisticLock.prefix("t")}
-> t.version = #{version}
* @{this.tryOptimisticLock.useWhereQuery}
-> [where] version = #{version}
* @{this.tryOptimisticLock.useAndQuery}
-> [and] version = #{version}
* @{this.tryOptimisticLock.useOrQuery}
-> [or] version = #{version}
*
*
* @return
*/
public OptimisticLockBuilder tryOptimisticLock() {
return new OptimisticLockBuilder( entity );
}
}