All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.viiyue.plugins.mybatis.scripting.parser.KeyGeneratorRegistry Maven / Gradle / Ivy

Go to download

Mybatis generic mapper plugin for solving most basic operations, simplifying sql syntax and improving dynamic execution efficiency

There is a newer version: 1.3.7
Show newest version
/**
 * 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.scripting.parser;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.annotations.Lang;
import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.LanguageDriverRegistry;
import org.apache.ibatis.session.Configuration;

import com.viiyue.plugins.mybatis.annotation.member.GeneratedKey;
import com.viiyue.plugins.mybatis.api.AutoIncrementStatementProvider;
import com.viiyue.plugins.mybatis.api.GeneratedValueProvider;
import com.viiyue.plugins.mybatis.enums.AutoIncrement;
import com.viiyue.plugins.mybatis.metadata.Entity;
import com.viiyue.plugins.mybatis.metadata.info.GeneratedKeyInfo;
import com.viiyue.plugins.mybatis.utils.Assert;
import com.viiyue.plugins.mybatis.utils.ObjectUtil;
import com.viiyue.plugins.mybatis.utils.SingletonUtil;

/**
 * 

* Primary Key Generator Registry, build a primary key generation strategy for * the model bean primary key. * *

    *
  • {@link Jdbc3KeyGenerator} - get the automatically generated primary key * to create the result of this Statement object execution *
  • {@link SelectKeyGenerator} - insert data does not support the primary key automatic generation solution *
  • {@link PrimaryKeyGenerator} - mybatis-mapper's primary key generation strategy *
* * @author tangxbai * @since 1.1.0 */ final class KeyGeneratorRegistry { private final Entity entity; private final String selectKeyId; private final MappedStatement statement; private final Configuration configuration; private final GeneratedKeyInfo generatedKeyInfo; public KeyGeneratorRegistry( MappedStatement ms, Entity entity, String selectKeyId ) { this.statement = ms; this.entity = entity; this.selectKeyId = selectKeyId; this.configuration = ms.getConfiguration(); this.generatedKeyInfo = entity.getGeneratedKeyInfo(); } /** *

* Get the appropriate primary key generator, * configure with {@link GeneratedKey @GeneratedKey}. * *

    *
  • if {@link GeneratedKey#useGeneratedKeys() useGeneratedKeys} * is set to true, then {@link Jdbc3KeyGenerator} is used. *
  • if {@link GeneratedKey#valueProvider() valueProvider} * is used, use {@link PrimaryKeyGenerator}. *
  • if {@link GeneratedKey#statement() statement}/{@link GeneratedKey#statementProvider() statementProvider} * is used, use {@link SelectKeyGenerator}. *
* * @param method the mapper method * @return the final key generator */ public KeyGenerator getKeyGenerator( Method method ) { // Level 1, the var(useGeneratedKeys) is the highest level. // Primary key generated using jdbc if ( generatedKeyInfo.isUseGeneratedKeys() ) { return new Jdbc3KeyGenerator(); } // Level 2, dynamically generated primary key value is the second level. // Dynamically generate primary keys Class primaryKeyProvider = generatedKeyInfo.getPrimaryKeyProvider(); if ( ObjectUtil.isDifferent( GeneratedValueProvider.class, primaryKeyProvider ) ) { return new PrimaryKeyGenerator( generatedKeyInfo ); } // Minimum level, Finally use the sql statement. // Select sql statement generator LanguageDriver languageDriver = getLanguageDriver( method ); MappedStatement selectKeyMappedStatement = addSelectKeyMappedStatement( languageDriver ); return new SelectKeyGenerator( selectKeyMappedStatement, generatedKeyInfo.isExecuteBefore() ); } /** * Create and register a {@code MappedStatement} object for the primary key * query statement * * @param languageDriver the specified language driver * @return the select key {@code MappedStatement} */ private MappedStatement addSelectKeyMappedStatement( LanguageDriver languageDriver ) { String selectKeySqlStatement = getSelectKeySqlStatement(); Assert.notEmpty( selectKeySqlStatement, "Select key sql statement cannot be empty text, " + "you can use statementProvider or statement to generate select sql statement" ); SqlSource sqlSource = languageDriver.createSqlSource( configuration, selectKeySqlStatement, ParamMap.class ); MappedStatement.Builder statementBuilder = new MappedStatement.Builder( configuration, selectKeyId, sqlSource, SqlCommandType.SELECT ) .resource( statement.getResource() ) .statementType( generatedKeyInfo.getStatementType() ) .keyGenerator( new NoKeyGenerator() ) .keyProperty( generatedKeyInfo.getKeyProperty() ) .keyColumn( generatedKeyInfo.getKeyColumn() ) .databaseId( configuration.getDatabaseId() ) .lang( languageDriver ); statementBuilder.resultMaps( getStatementResultMaps() ); statementBuilder.parameterMap( getStatementParameterMap() ); MappedStatement statement = statementBuilder.build(); configuration.addMappedStatement( statement ); return statement; } /** * Get the statement parameter Map, * you can refer to {@link MapperBuilderAssistant#getStatementParameterMap}. * * @return the statement parameter Map */ private ParameterMap getStatementParameterMap() { List parameterMappings = new ArrayList(); ParameterMap.Builder builder = new ParameterMap.Builder( configuration, selectKeyId + "-Inline", entity.getBeanType(), parameterMappings ); return builder.build(); } /** * Get the statement result Map {@code List}, * you can refer to {@link MapperBuilderAssistant#getStatementResultMaps}. * * @return */ private List getStatementResultMaps() { ResultMap.Builder resultMapBuilder = new ResultMap.Builder( configuration, selectKeyId + "-Inline", generatedKeyInfo.getResultType(), new ArrayList(), null ); List resultMaps = new ArrayList(); resultMaps.add( resultMapBuilder.build() ); return resultMaps; } /** * Get the select key sql statement * * @return the select key sql statement */ private String getSelectKeySqlStatement() { // Generate sql statement by the provider Class providerType = generatedKeyInfo.getStatementProvider(); if ( ObjectUtil.isDifferent( AutoIncrementStatementProvider.class, providerType ) ) { AutoIncrementStatementProvider statementProvider = SingletonUtil.getSingleton( providerType ); return statementProvider.getAutoIncrementSqlStatement( generatedKeyInfo ); } // Handwritten SQL statement // It may be the name of the enumeration or the sql statement String statement = generatedKeyInfo.getStatement(); try { // Enumeration constant( MYSQL/DB2/SQLSERVER/CLOUDSCAPE/DERBY/HSQLDB/SYBASE/DB2_MF ) AutoIncrement increment = AutoIncrement.valueOf( statement ); statement = increment.statement(); } catch ( Exception e ) { // Ignore, no related enumeration reference was found } // ALERT : this statement can only be a sql text return statement; } /** * If the {@link org.apache.ibatis.annotations.Lang @Lang} annotation is * configured, the configuration language driver for the Lang annotation is * obtained. If there is no registration, it will be automatically * registered. * Otherwise, the default language driver of the configuration center is obtained. * * @param method the mapper method * @return the specified language driver if a driver type is specified, * otherwise returns the default language driver. */ private LanguageDriver getLanguageDriver( Method method ) { Lang lang = method.getAnnotation( Lang.class ); LanguageDriverRegistry languageRegistry = configuration.getLanguageRegistry(); if ( lang != null ) { languageRegistry.register( lang.value() ); return languageRegistry.getDriver( lang.value() ); } return languageRegistry.getDefaultDriver(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy