Java tutorial
/** * Copyright (C) 2015-2016 OurBeehive(http://ourbeehive.github.io/) * * 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. * Project Name: MyBatisPioneer * File Name: SelectBuilder.java * Package Name: org.ourbeehive.mbp.builder * * Date: Jan 20, 2016 * Author: Sericloud * */ package org.ourbeehive.mbp.builder; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.ourbeehive.mbp.exception.AppException; import org.ourbeehive.mbp.factory.OrmFactory; import org.ourbeehive.mbp.lang.JavaSrcElm; import org.ourbeehive.mbp.lang.MapperElm; import org.ourbeehive.mbp.model.ant.FilterConfig; import org.ourbeehive.mbp.model.ant.MapperArtifact; import org.ourbeehive.mbp.model.ant.MapperProfile; import org.ourbeehive.mbp.model.ant.RelConfig; import org.ourbeehive.mbp.model.ant.ResultMapConfig; import org.ourbeehive.mbp.model.ant.UserFilter; import org.ourbeehive.mbp.model.db.OrmColumn; import org.ourbeehive.mbp.model.db.OrmTable; import org.ourbeehive.mbp.model.mybatis3.If; import org.ourbeehive.mbp.model.mybatis3.Include; import org.ourbeehive.mbp.model.mybatis3.Mapper; import org.ourbeehive.mbp.model.mybatis3.ObjectFactory; import org.ourbeehive.mbp.model.mybatis3.Select; import org.ourbeehive.mbp.model.mybatis3.Sql; import org.ourbeehive.mbp.model.mybatis3.Trim; import org.ourbeehive.mbp.register.CtxCacheFacade; import org.ourbeehive.mbp.register.OneToOneIdx; import org.ourbeehive.mbp.register.OneToOneIdxFacade; import org.ourbeehive.mbp.util.ClassAnalyzer; import org.ourbeehive.mbp.util.ExceptionUtil; import org.ourbeehive.mbp.util.JavaFormatter; import org.ourbeehive.mbp.util.KeyWordsTransformer; import org.ourbeehive.mbp.util.MapperFormatter; import org.ourbeehive.mbp.util.ProfileHelper; import org.ourbeehive.mbp.util.StringHelper; public class SelectBuilder { private static Logger logger = Logger.getLogger(SelectBuilder.class); private ObjectFactory mapperObjFactory; private OrmFactory ormFactory; public SelectBuilder(ObjectFactory mapperObjFactory) { this.mapperObjFactory = mapperObjFactory; } public void buildCountRootTableBySql(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig resultMapConfig) throws AppException { try { // The expected 'id' of 'select'. String rootTableName = resultMapConfig.getTableName(); String rootTableAlias = resultMapConfig.getTableAlias(); // count XX BySql String selectId = MapperFormatter.getSelIdOfCountBySql(resultMapConfig); logger.debug("SELECT: Prepare to build select with id '" + selectId + "'."); // Lookup 'select' element with 'id'. Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectId); if (select != null) { return; } // Initiate a blank Select. select = mapperObjFactory.createSelect(); mapper.getSelect().add(select); // Register the new 'select' element. CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate the 'id' attribute for Select with value 'count<Root Table Name>BySqlClause'. select.setId(selectId); // TODO 2016.1.25 slp.bss.model.util.MapperSqlClause ? where?? // Populate the 'parameterCalss' attribute for Select. select.setParameterType(JavaSrcElm.SQL_CLAUSE_FULL); // Populate the 'resultClass' attribute for Select. select.setResultType(JavaSrcElm.LANG_INTEGER_FULL); // Find Table corresponding to current Select, if no Table found, then return Select without elements. OrmTable rootTable = CtxCacheFacade.lookupOrmTable(rootTableName); if (rootTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + rootTableName); return; } // Iterate all of the columns in a table to determine the count criteria. Hashtable<String, OrmColumn> allColumnIdx = rootTable.getColumnIdx(); String columnName = null; OrmColumn column = null; StringBuffer countBy = new StringBuffer(); for (Enumeration<String> allColumnKey = allColumnIdx.keys(); allColumnKey.hasMoreElements();) { columnName = allColumnKey.nextElement(); column = rootTable.getColumnIdx().get(columnName); // Find the primary key. if (column.isPrimaryKey() == true) { if (StringUtils.isNotBlank(countBy)) { countBy.append(MapperElm.COMMA); countBy.append(MapperElm.WHITE_SPACE); } countBy.append(columnName); } } if (StringUtils.isBlank(countBy)) { countBy.append(MapperElm.STAR); } // Create select clause and from clause. StringBuffer selectClause = new StringBuffer(); StringBuffer fromClause = new StringBuffer(); selectClause.append(MapperElm.SQL_SELECT); selectClause.append(MapperElm.WHITE_SPACE); selectClause.append(MapperElm.SQL_COUNT); selectClause.append(MapperElm.LEFT_PARENTHESIS); selectClause.append(countBy); selectClause.append(MapperElm.RIGHT_PARENTHESIS); fromClause.append(MapperElm.SQL_FROM); fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, rootTableName, rootTableAlias)); select.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + selectClause.toString() + fromClause.toString() + MapperElm.CDATA_ANCHOR_END); // Append dynamic where clause and order by clause. Trim whereTrim = mapperObjFactory.createTrim(); select.getTrim().add(whereTrim); whereTrim.setPrefix(MapperElm.SQL_WHERE_SIMPLE); whereTrim.setPrefixOverrides(MapperElm.SQL_AND_OR); whereTrim.setCDataBegin( MapperElm.CDATA_ANCHOR_BEGIN + MapperElm.ANCHOR_WHERE_CLAUSE + MapperElm.CDATA_ANCHOR_END); // Register a DAO method. List<String> paramTypeNameList = new ArrayList<String>(); paramTypeNameList.add(JavaSrcElm.SQL_CLAUSE_FULL); String comments = resultMapConfig.getComments() + JavaSrcElm.COUNT_ONE_TABLE; CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, rootTableName, selectId, paramTypeNameList, JavaSrcElm.LANG_INTEGER_FULL, comments); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } public void buildSelectRootTableByPK(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig resultMapConfig) throws AppException { try { // The expected 'id' of 'select'. String selectId = MapperFormatter.getSelIdOfRootTabByPK(resultMapConfig); logger.debug("SELECT: Prepare to build select with id '" + selectId + "'."); // Lookup 'select' element with composite id containing the select element name and the 'java.lang.Long' type name. String selectIdLong = selectId + JavaSrcElm.LANG_LONG_SIMPLE; Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectIdLong); if (select == null) { buildSelectRootTableByPKParamType(mapper, mapperProfile, mapperArtifact, resultMapConfig, selectIdLong, JavaSrcElm.LANG_LONG_FULL); } // Lookup 'select' element with composite id containing the element name and the DTOX type name. String selectIdDtox = selectId + JavaSrcElm.DTOX_NAME_SUFFIX; select = CtxCacheFacade.lookupSelect(mapperArtifact, selectIdDtox); if (select == null) { String paramTypeName = resultMapConfig.getClassName(); buildSelectRootTableByPKParamType(mapper, mapperProfile, mapperArtifact, resultMapConfig, selectIdDtox, paramTypeName); } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } public void buildSelectRootTableBySql(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig resultMapConfig) throws AppException { try { // The expected 'id' of 'select'. String selectId = MapperFormatter.getSelIdOfRootTabBySql(resultMapConfig); logger.debug("SELECT: Prepare to build select with id '" + selectId + "'."); // Lookup 'select' element with id. Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectId); if (select != null) { return; } // Initiate a blank 'select' and register it. select = mapperObjFactory.createSelect(); select.setId(selectId); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate the 'parameterType' attribute for select. select.setParameterType(JavaSrcElm.SQL_CLAUSE_FULL); // Populate the 'resultMap' attribute for select. String rootTableName = resultMapConfig.getTableName(); // String rootTableAlias = resultMapConfig.getTableAlias(); String resultMapId = MapperFormatter.getResultMapIdOfRootTab(resultMapConfig); select.setResultMap(resultMapId); // Find Table corresponding to current Select, if no Table found, then return Select without elements. OrmTable rootTable = CtxCacheFacade.lookupOrmTable(rootTableName); if (rootTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + rootTableName); return; } // Define separate select and from clause for easy to reuse. String sqlId = MapperFormatter.getSqlIdOfRootTabSel(resultMapConfig); MapperSql mapperSql = new MapperSql(); defineReusableSelectFrom4RootTab(mapperSql, mapper, mapperProfile, mapperArtifact, resultMapConfig, rootTable, sqlId); // Define the paging query. if (ormFactory == null) { this.ormFactory = new OrmFactory(mapperProfile.getAllMapperProfile()); } ormFactory.getPageQueryBuilder().definePagingQuery(mapperProfile, select, resultMapConfig, mapperSql, sqlId, false, mapperObjFactory); // Register DAO methods. List<String> paramTypeNameList = new ArrayList<String>(); paramTypeNameList.add(JavaSrcElm.SQL_CLAUSE_FULL); String classFullName = resultMapConfig.getClassName(); String classSimpleName = JavaFormatter.getClassSimpleName(classFullName); String returnTypeName = JavaSrcElm.UTIL_LIST_SIMPLE + JavaSrcElm.LESS_THAN + classSimpleName + JavaSrcElm.GREATER_THAN; String comments = resultMapConfig.getComments() + JavaSrcElm.QUERY_ONE_TABLE; // The method without paging. CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, rootTableName, selectId, paramTypeNameList, returnTypeName, comments); // The method for paged query. // paramTypeNameList.add(JavaSrcElm.INT); // paramTypeNameList.add(JavaSrcElm.INT); // CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, rootTableName, selectId, paramTypeNameList, returnTypeName, comments); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Build public select, including oneToOne and oneToMany // // <ancesResultMapConfig> // ....<descOneToOne /> // </ancesResultMapConfig> // public void buildMultiTabSelectByPK(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig, List<OneToOneIdx> descOtoIdxList) throws AppException { try { // The expected 'id' of 'select'. String selectId = MapperFormatter.getSelIdOfMultiTabByPK(ancesResultMapConfig, descOtoIdxList); logger.debug("SELECT: Prepare to build select with id '" + selectId + "'."); // Lookup 'select' element with composite id containing the select element name and the 'java.lang.Long' type name. String selectIdLong = selectId + JavaSrcElm.LANG_LONG_SIMPLE; Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectIdLong); if (select == null) { buildMultiTabSelectByPKParamType(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList, selectIdLong, JavaSrcElm.LANG_LONG_FULL); } // Lookup 'select' element with composite id containing the element name and the DTOX type name. String selectIdDtox = selectId + JavaSrcElm.DTOX_NAME_SUFFIX; String ancesClassName = ancesResultMapConfig.getClassName(); select = CtxCacheFacade.lookupSelect(mapperArtifact, selectIdDtox); if (select == null) { buildMultiTabSelectByPKParamType(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList, selectIdDtox, ancesClassName); } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Build public select, including oneToOne and oneToMany // // <ancesResultMapConfig> // ....<descOneToOne /> // </ancesResultMapConfig> // public void buildMultiTabSelectBySql(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig, List<OneToOneIdx> descOtoIdxList) throws AppException { try { // The expected 'id' of 'select'. String selectId = MapperFormatter.getSelIdOfMultiTabBySql(ancesResultMapConfig, descOtoIdxList); logger.debug("SELECT: Prepare to build select with id '" + selectId + "'."); // Lookup 'select' element with id. Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectId); if (select != null) { return; } // Initiate a blank 'select' and register it. select = mapperObjFactory.createSelect(); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate attributes of select. select.setId(selectId); select.setParameterType(JavaSrcElm.SQL_CLAUSE_FULL); String resultMapId = MapperFormatter.getResultMapIdOfMultiTab(ancesResultMapConfig, descOtoIdxList); select.setResultMap(resultMapId); // Find Table corresponding to current Select, if no Table found, then return Select without elements. String ancesTableName = ancesResultMapConfig.getTableName(); OrmTable ancesTable = CtxCacheFacade.lookupOrmTable(ancesTableName); if (ancesTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + ancesTableName); return; } // Compute the select clause. MapperSql mapperSql = new MapperSql(); computeSelectClause(mapperSql, mapperProfile, null, ancesResultMapConfig, ancesTable); // Define join type according to the association. int joinType = -1; if (descOtoIdxList == null || descOtoIdxList.size() == 0) { joinType = MapperSql.JOIN_TYPE_NONE; } else if (descOtoIdxList != null && descOtoIdxList.size() != 0 && hasOuterJoin(descOtoIdxList) == true) { joinType = MapperSql.JOIN_TYPE_OUTER; } else { joinType = MapperSql.JOIN_TYPE_PUBLIC_INNER; } mapperSql.setJoinType(joinType); // Populate different kinds of clause according to join tyoe. computeSqlElmtForJoin(mapperSql, mapperProfile, ancesResultMapConfig, descOtoIdxList); // Append different kinds of clause as usable sql clause. String sqlId = MapperFormatter.getSqlIdOfMultiTabSel(ancesResultMapConfig, descOtoIdxList, true); defineReusableSelectFrom4MultiTab(mapperSql, mapper, mapperArtifact, sqlId); // Define the paging query. //definePagingQuery(mapperProfile, select, ancesResultMapConfig, mapperSql, sqlId,true); if (ormFactory == null) { this.ormFactory = new OrmFactory(mapperProfile.getAllMapperProfile()); } ormFactory.getPageQueryBuilder().definePagingQuery(mapperProfile, select, ancesResultMapConfig, mapperSql, sqlId, true, mapperObjFactory); // Register DAO methods. List<String> paramTypeNameList = new ArrayList<String>(); paramTypeNameList.add(JavaSrcElm.SQL_CLAUSE_FULL); String classFullName = ancesResultMapConfig.getClassName(); String classSimpleName = JavaFormatter.getClassSimpleName(classFullName); String returnTypeName = JavaSrcElm.UTIL_LIST_SIMPLE + JavaSrcElm.LESS_THAN + classSimpleName + JavaSrcElm.GREATER_THAN; String comments = ancesResultMapConfig.getComments() + JavaSrcElm.QUERY_MULTI_TABLE; CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, ancesTableName, selectId, paramTypeNameList, returnTypeName, comments); // To register a method for paging query. // paramTypeNameList.add(JavaSrcElm.INT); // paramTypeNameList.add(JavaSrcElm.INT); // CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, ancesTableName, selectId, paramTypeNameList, returnTypeName, comments); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Internal selectOneToOne only comes from oneToMany, which could from both top or higher oneToOne. // // <fatherResultMapConfig> // ....<sonOneToMany> // ........<sonReultMapConfig> // ............<descOneToOne /> // ........</sonReultMapConfig> // ........<fatherAttr /> // ........<sonAttr /> // ....</sonOneToMany> // </fatherResultMapConfig> // public void buildIntnlSelectOto(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig fatherResultMapConfig, RelConfig sonOtmConfig, List<OneToOneIdx> descOtoIdxList, String selectId, String resultMapId) throws AppException { logger.debug("ENTRY: Prepare to execute 'buildIntnlSelectOto' with given 'selectId': " + selectId); try { // Lookup 'select' element with id. Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectId); if (select != null) { return; } // Initiate a blank 'select' and register it. select = mapperObjFactory.createSelect(); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate attributes of select. select.setId(selectId); select.setResultMap(resultMapId); // Find Table corresponding to current Select, if no Table found, then return Select without elements. ResultMapConfig sonResultMapConfig = sonOtmConfig.getResultMapConfig(); String sonTableName = sonResultMapConfig.getTableName(); String sonTableAlias = sonResultMapConfig.getTableAlias(); // String sonClassName = sonResultMapConfig.getClassName(); // select.setParameterType(sonClassName); OrmTable sonTable = CtxCacheFacade.lookupOrmTable(sonTableName); if (sonTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + sonTableName); return; } // Compute the select clause. MapperSql mapperSql = new MapperSql(); StringBuffer selectClause = mapperSql.getSelectClause(); computeSelectClause(mapperSql, mapperProfile, null, sonResultMapConfig, sonTable); // Create where clause. StringBuffer whereClause = mapperSql.getWhereClause(); MapperFormatter.beginWhereStatement(whereClause); String sonAttr = sonOtmConfig.getSonAttr(); String sonColumnName = JavaFormatter.getDbStyle(sonAttr); String fatherTableName = fatherResultMapConfig.getTableName(); String fatherTableAlias = fatherResultMapConfig.getTableAlias(); String fatherColumnName = JavaFormatter.getDbStyle(sonOtmConfig.getFatherAttr()); whereClause.append( MapperFormatter.getColumnFullName(mapperProfile, sonTableName, sonTableAlias, sonColumnName)); whereClause.append(MapperElm.EQUAL); whereClause.append(MapperElm.POUND); whereClause.append(MapperElm.LEFT_BRACE); whereClause.append(MapperFormatter.getColumnAlias(mapperProfile, fatherTableName, fatherTableAlias, fatherColumnName)); whereClause.append(MapperElm.RIGHT_BRACE); // Populate from clause, append those clause from one to one. StringBuffer fromClause = mapperSql.getFromClause(); int joinType = (hasOuterJoin(descOtoIdxList) == true) ? MapperSql.JOIN_TYPE_OUTER : MapperSql.JOIN_TYPE_PRIVATE_INNER; mapperSql.setJoinType(joinType); computeSqlElmtForJoin(mapperSql, mapperProfile, sonResultMapConfig, descOtoIdxList); select.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + selectClause.toString() + fromClause.toString() + whereClause.toString() + MapperElm.CDATA_ANCHOR_END); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Internal selectOneTable comes from oneToOne, top or higher oneToMany. // // From oneToOne: // <ancesResultMap> // ....<fatherOtoIndex> // ........<fatherResultMapConfig> // ............<sonOneToMany listOfSon="" fatherAttr=""> // ................<sonResultMapConfig /> // ............</sonOneToMany> // ........</fatherResultMapConfig> // ....</fatherOtoIndex> // ....<descOneToOne /> // </ancesResultMap> // // From top or higher oneToMany: // <fatherResultMapConfig> // ....<sonOneToMany listOfSon="", fatherAttr=""> // ........<sonResultMapConfig /> // ....</sonOneToMany> // </fatherResultMapConfig> // public void buildIntnlSelectOneTable(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig, OneToOneIdx fatherOtoIndex, ResultMapConfig fatherResultMapConfig, RelConfig sonOtmConfig) throws AppException { try { ResultMapConfig sonResultMapConfig = sonOtmConfig.getResultMapConfig(); String sonTableName = sonResultMapConfig.getTableName(); String sonTableAlias = sonResultMapConfig.getTableAlias(); String listOfSon = sonOtmConfig.getListOfSon(); // Populate the 'id' attribute for 'select'. String selectId = MapperFormatter.getSelIdOfIntnlOtm(null, mapperArtifact, sonResultMapConfig, listOfSon, false); // Lookup 'select' element with id. Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectId); if (select != null) { return; } logger.debug("INTERNAL SELECT: Begin to build internal select with id: " + selectId); // Initiate a blank 'select' and register it. select = mapperObjFactory.createSelect(); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate the 'resultMap' attribute for 'select'. select.setId(selectId); String resultMapId = MapperFormatter.getResultMapIdOfIntnlOtm(mapperProfile, mapperArtifact, sonResultMapConfig, listOfSon); select.setResultMap(resultMapId); // Find Table corresponding to current Select, if no Table found, then return Select without elements. OrmTable sonTable = CtxCacheFacade.lookupOrmTable(sonTableName); if (sonTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + sonTableName); return; } // Compute the select clause. MapperSql mapperSql = new MapperSql(); StringBuffer selectClause = mapperSql.getSelectClause(); computeSelectClause(mapperSql, mapperProfile, null, sonResultMapConfig, sonTable); // Populate from clause. StringBuffer fromClause = mapperSql.getFromClause(); MapperFormatter.beginFromStatement(fromClause); fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, sonTableName, sonTableAlias)); // Create where clause. StringBuffer whereClause = mapperSql.getWhereClause(); MapperFormatter.beginWhereStatement(whereClause); String sonAttr = sonOtmConfig.getSonAttr(); String sonColumnName = JavaFormatter.getDbStyle(sonAttr); String fatherTableName = fatherResultMapConfig.getTableName(); String fatherTableAlias = fatherResultMapConfig.getTableAlias(); String fatherColumnName = JavaFormatter.getDbStyle(sonOtmConfig.getFatherAttr()); whereClause.append( MapperFormatter.getColumnFullName(mapperProfile, sonTableName, sonTableAlias, sonColumnName)); whereClause.append(MapperElm.EQUAL); whereClause.append(MapperElm.POUND); whereClause.append(MapperElm.LEFT_BRACE); whereClause.append(MapperFormatter.getColumnAlias(mapperProfile, fatherTableName, fatherTableAlias, fatherColumnName)); whereClause.append(MapperElm.RIGHT_BRACE); // Append configured filter. populateFilterConfig(mapperProfile, whereClause, sonResultMapConfig, MapperElm.SQL_AND_SIMPLE); select.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + selectClause.toString() + fromClause.toString() + whereClause.toString() + MapperElm.CDATA_ANCHOR_END); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } /** * Construct select element with different parameter type. * * @param mapper * @param mapperProfile * @param mapperArtifact * @param resultMapConfig * @param selectId * @param paramTypeName * @throws AppException */ private void buildSelectRootTableByPKParamType(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig resultMapConfig, String selectId, String paramTypeName) throws AppException { try { // Initiate a new 'select' and register it. Select select = mapperObjFactory.createSelect(); select.setId(selectId); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate the 'parameterType' attribute for select. select.setParameterType(paramTypeName); // Populate the 'resultMap' attribute for select. String rootTableName = resultMapConfig.getTableName(); // String rootTableAlias = resultMapConfig.getTableAlias(); String resultMapId = MapperFormatter.getResultMapIdOfRootTab(resultMapConfig); select.setResultMap(resultMapId); // Find Table corresponding to current Select, if no Table found, then return Select without elements. OrmTable rootTable = CtxCacheFacade.lookupOrmTable(rootTableName); if (rootTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + rootTableName); return; } // Define separate select and from clause for easy to reuse. String sqlId = MapperFormatter.getSqlIdOfRootTabSel(resultMapConfig); MapperSql mapperSql = new MapperSql(); defineReusableSelectFrom4RootTab(mapperSql, mapper, mapperProfile, mapperArtifact, resultMapConfig, rootTable, sqlId); // Anyway, need to populate primary key clause. computeWhereClauseWithPK(mapperSql, mapperProfile, rootTable, resultMapConfig, paramTypeName); StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); MapperFormatter.insertWhereStatement(primaryKeyClause); // Refer to common sql clause in 'select'. Include include = mapperObjFactory.createInclude(); include.setRefid(sqlId); select.getInclude().add(include); select.setCDataBegin( MapperElm.CDATA_ANCHOR_BEGIN + primaryKeyClause.toString() + MapperElm.CDATA_ANCHOR_END); // Register a DAO method. List<String> paramTypeNameList = new ArrayList<String>(); paramTypeNameList.add(paramTypeName); String returnTypeName = resultMapConfig.getClassName(); String comments = resultMapConfig.getComments() + JavaSrcElm.QUERY_ONE_TABLE; CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, rootTableName, selectId, paramTypeNameList, returnTypeName, comments); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } /** * Construct select element with different parameter type. * * @param mapper * @param mapperProfile * @param mapperArtifact * @param ancesResultMapConfig * @param descOtoIdxList * @throws AppException */ private void buildMultiTabSelectByPKParamType(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig, List<OneToOneIdx> descOtoIdxList, String selectId, String paramTypeName) throws AppException { try { // Initiate a blank 'select' and register it. Select select = mapperObjFactory.createSelect(); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate attributes of Select. select.setId(selectId); select.setParameterType(paramTypeName); String resultMapId = MapperFormatter.getResultMapIdOfMultiTab(ancesResultMapConfig, descOtoIdxList); select.setResultMap(resultMapId); // Find Table corresponding to current Select, if no Table found, then return Select without elements. String ancesTableName = ancesResultMapConfig.getTableName(); OrmTable ancesTable = CtxCacheFacade.lookupOrmTable(ancesTableName); if (ancesTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + ancesTableName); return; } // Refer to common sql clause in 'select'. String sqlId = MapperFormatter.getSqlIdOfMultiTabSel(ancesResultMapConfig, descOtoIdxList, true); Include include = mapperObjFactory.createInclude(); include.setRefid(sqlId); select.getInclude().add(include); // Populate primary key clause. MapperSql mapperSql = new MapperSql(); computeWhereClauseWithPK(mapperSql, mapperProfile, ancesTable, ancesResultMapConfig, paramTypeName); StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); // Define join type according to the association. int joinType = -1; if (descOtoIdxList == null || descOtoIdxList.size() == 0) { joinType = MapperSql.JOIN_TYPE_NONE; } else if (descOtoIdxList != null && descOtoIdxList.size() != 0 && hasOuterJoin(descOtoIdxList) == true) { joinType = MapperSql.JOIN_TYPE_OUTER; } else { joinType = MapperSql.JOIN_TYPE_PUBLIC_INNER; } mapperSql.setJoinType(joinType); if (joinType == MapperSql.JOIN_TYPE_NONE) { computeSqlElmtForSingle(mapperSql, mapperProfile, ancesResultMapConfig); MapperFormatter.insertWhereStatement(primaryKeyClause); } else if (joinType == MapperSql.JOIN_TYPE_OUTER) { // Compute the select clause. computeSelectClause(mapperSql, mapperProfile, null, ancesResultMapConfig, ancesTable); // For outer join, join condition was included inside 'fromClause'. computeSqlElmtForJoin(mapperSql, mapperProfile, ancesResultMapConfig, descOtoIdxList); MapperFormatter.insertWhereStatement(primaryKeyClause); } else { // Compute the select clause. computeSelectClause(mapperSql, mapperProfile, null, ancesResultMapConfig, ancesTable); // For inner join, join condition was included inside separate 'joinClause'. computeSqlElmtForJoin(mapperSql, mapperProfile, ancesResultMapConfig, descOtoIdxList); StringBuffer joinClause = mapperSql.getJoinClause(); if (StringUtils.isNotBlank(joinClause)) { MapperFormatter.insertAndStatement(primaryKeyClause); } else { MapperFormatter.insertWhereStatement(primaryKeyClause); } } // Append different kinds of clause as usable sql clause. defineReusableSelectFrom4MultiTab(mapperSql, mapper, mapperArtifact, sqlId); // Append where clause into mapper. StringBuffer whereClause = mapperSql.getWhereClause(); select.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + primaryKeyClause.toString() + whereClause.toString() + MapperElm.CDATA_ANCHOR_END); // Register a DAO method. List<String> paramTypeNameList = new ArrayList<String>(); paramTypeNameList.add(paramTypeName); String ancesClassName = ancesResultMapConfig.getClassName(); String comments = ancesResultMapConfig.getComments() + JavaSrcElm.QUERY_MULTI_TABLE; CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, ancesTableName, selectId, paramTypeNameList, ancesClassName, comments); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } private void computeSelectClause(MapperSql mapperSql, MapperProfile mapperProfile, OneToOneIdx oneToOneIndex, ResultMapConfig resultMapConfig, OrmTable ormTable) throws AppException { // Get table name and table alias. String tableName = null; String tableAlias = null; if (oneToOneIndex != null) { tableName = oneToOneIndex.getSonTableName(); tableAlias = oneToOneIndex.getSonTableAlias(); } else { tableName = resultMapConfig.getTableName(); tableAlias = resultMapConfig.getTableAlias(); } // Compute the select clause according to the the OrmClass definition. HashSet<String> includedAttr = ProfileHelper.getIncludedAttrName(resultMapConfig); HashSet<String> excludedAttr = ProfileHelper.getExcludedAttrName(resultMapConfig); List<OrmColumn> ormColumnList = ormTable.getColumnList(); OrmColumn ormColumn = null; String columnName = null; String attrName = null; StringBuffer selectClause = mapperSql.getSelectClause(); StringBuffer columnNameClause = mapperSql.getColumnNameClause(); StringBuffer columnAliasClause = mapperSql.getColumnAliasClause(); for (int i = 0; i < ormColumnList.size(); i++) { ormColumn = ormColumnList.get(i); columnName = ormColumn.getName(); attrName = JavaFormatter.getJavaStyle(columnName, false); // Check inclusion and exclusion, inclusion take higher preference. if (includedAttr.size() != 0) { if (includedAttr.contains(attrName) == false) { logger.debug( "INCLUDE PROPERTY: Property '" + attrName + "' is NOT in the inclusion list, skipped."); continue; } } else if (excludedAttr.size() != 0) { if (excludedAttr.contains(attrName) == true) { logger.debug( "EXCLUDE PROPERTY: Property '" + attrName + "' is in the exclusion list, skipped."); continue; } } // Handle the select clause, considering the case of the first column. if (StringUtils.isBlank(selectClause)) { selectClause.append(MapperFormatter.getSelectStmtWithPrefix(resultMapConfig)); } else { selectClause.append(MapperElm.COMMA + MapperElm.WHITE_SPACE); } selectClause .append(MapperFormatter.getColumnNamePair(mapperProfile, tableName, tableAlias, columnName)); MapperFormatter.checkWidth(selectClause); // Handle the column name clause if (StringUtils.isNotBlank(columnNameClause)) { columnNameClause.append(MapperElm.COMMA + MapperElm.WHITE_SPACE); } columnNameClause .append(MapperFormatter.getColumnNamePair(mapperProfile, tableName, tableAlias, columnName)); MapperFormatter.checkWidth(columnNameClause); // Handle the column alias clause. if (StringUtils.isNotBlank(columnAliasClause)) { columnAliasClause.append(MapperElm.COMMA + MapperElm.WHITE_SPACE); } columnAliasClause .append(MapperFormatter.getColumnAlias(mapperProfile, tableName, tableAlias, columnName)); MapperFormatter.checkWidth(columnAliasClause); } } private void computeFromClause(MapperSql mapperSql, MapperProfile mapperProfile, ResultMapConfig resultMapConfig) { String rootTableName = resultMapConfig.getTableName(); String rootTableAlias = resultMapConfig.getTableAlias(); StringBuffer fromClause = mapperSql.getFromClause(); MapperFormatter.beginFromStatement(fromClause); fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, rootTableName, rootTableAlias)); } private void computeWhereClauseWithPK(MapperSql mapperSql, MapperProfile mapperProfile, OrmTable ormTable, ResultMapConfig resultMapConfig, String paramTypeName) throws AppException { List<OrmColumn> ormColumnList = ormTable.getColumnList(); OrmColumn ormColumn = null; String columnName = null; String attrName = null; String tableName = resultMapConfig.getTableName(); String tableAlias = resultMapConfig.getTableAlias(); String voName = JavaFormatter.getVoSimpleName(resultMapConfig, false); KeyWordsTransformer keyWordsTransformer = KeyWordsTransformer .getInstance(mapperProfile.getAllMapperProfile()); // Populate sql according to the the OrmClass definition. StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); for (int i = 0; i < ormColumnList.size(); i++) { ormColumn = ormColumnList.get(i); columnName = ormColumn.getName(); attrName = JavaFormatter.getJavaStyle(columnName, false); // Look up corresponding Column with columnName. // if (StringUtils.isNotBlank(columnName) == true) { // ormColumn = ormTable.getColumnIdx().get(columnName); // } else { // ormColumn = null; // } if (ormColumn != null && ormColumn.isPrimaryKey() == true) { if (StringUtils.isNotBlank(primaryKeyClause)) { primaryKeyClause.append(MapperElm.SQL_AND_FULL); } primaryKeyClause.append(MapperFormatter.getColumnFullName(mapperProfile, tableName, tableAlias, keyWordsTransformer.getTransferredStr(columnName))); primaryKeyClause.append(MapperElm.EQUAL); primaryKeyClause.append(MapperElm.POUND); primaryKeyClause.append(MapperElm.LEFT_BRACE); if (paramTypeName.startsWith(JavaSrcElm.JAVA_LANG_PKG_PREFIX) == true) { primaryKeyClause.append(MapperElm.MAPPER_PK_VAL_ID); } else { primaryKeyClause.append(voName); primaryKeyClause.append(MapperElm.DOT); primaryKeyClause.append(attrName); } primaryKeyClause.append(MapperElm.RIGHT_BRACE); logger.info("FIND MAPPING: Find primary key mapping between property '" + attrName + "' and column '" + columnName + "'"); } } } /** * This method is used to generate separate <sql> element for 'resultMapConfig' without one to one join association. * */ private void computeSqlElmtForSingle(MapperSql mapperSql, MapperProfile mapperProfile, ResultMapConfig ancesResultMapConfig) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeSqlClauseForSingle'."); /****************************************************************************************** * Handle the single 'resultMapConfig'. ******************************************************************************************/ computeSelectClauseForSingle(mapperSql, mapperProfile, ancesResultMapConfig); /********************************************************************************************** * Handle 'filter' from 'ancesResultMapConfig' for higher performance. **********************************************************************************************/ List<FilterConfig> filterList = ancesResultMapConfig.getFilterConfig(); if (filterList != null) { logger.debug("FILTER: 'filterList' of current 'ancesResultMapConfig' is not null."); StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); StringBuffer whereClause = mapperSql.getWhereClause(); if (StringUtils.isNotBlank(primaryKeyClause) || StringUtils.isNotBlank(whereClause)) { populateFilterConfig(mapperProfile, whereClause, ancesResultMapConfig, MapperElm.SQL_AND_SIMPLE); } else { populateFilterConfig(mapperProfile, whereClause, ancesResultMapConfig, MapperElm.SQL_WHERE_SIMPLE); } } else { logger.debug("FILTER: 'filterList' of current 'ancesResultMapConfig' is null."); } } private void computeSelectClauseForSingle(MapperSql mapperSql, MapperProfile mapperProfile, ResultMapConfig ancesResultMapConfig) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeSelectClauseForSingle'."); try { /****************************************************************************************** * Build select clause. ******************************************************************************************/ // Get table name and table alias. String tableName = ancesResultMapConfig.getTableName(); String tableAlias = ancesResultMapConfig.getTableAlias(); // If no DB table exist in cache according to the right table name, then return. OrmTable rightOrmTable = CtxCacheFacade.lookupOrmTable(tableName); if (rightOrmTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + tableName); return; } // Compute the select clause. computeSelectClause(mapperSql, mapperProfile, null, ancesResultMapConfig, rightOrmTable); /****************************************************************************************** * Build from clause. ******************************************************************************************/ StringBuffer fromClause = mapperSql.getFromClause(); if (StringUtils.isNotBlank(fromClause)) { StringHelper.newLine(fromClause, JavaSrcElm.UNIT_OF_INDENT, 3); fromClause.append(MapperElm.COMMA + MapperElm.WHITE_SPACE); } else { MapperFormatter.beginFromStatement(fromClause); } fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, tableName, tableAlias)); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } /** * This method is used to generate separate <sql> element for join. For outer join, join condition was included inside 'fromClause'. For inner * join, join condition was included inside separate 'joinClause'. */ private void computeSqlElmtForJoin(MapperSql mapperSql, MapperProfile mapperProfile, ResultMapConfig ancesResultMapConfig, List<OneToOneIdx> descOtoIdxList) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeSqlClauseForJoin'."); /********************************************************************************************** * Iterate from the last to the first for higher performance. **********************************************************************************************/ OneToOneIdx descOtoIdx = null; OneToOneIdx fatherOtoIndex = null; boolean hasPeer = false; int breakpoint = 0; int fatherLoc = 0; boolean isFirst = true; // Get 'descOtoIdx' in the descendant order. for (int i = descOtoIdxList.size() - 1; i >= 0; i--) { /****************************************************************************************** * Get current element and handle it. ******************************************************************************************/ logger.debug("DESCENDANT: Get element at index '" + i + "'"); descOtoIdx = descOtoIdxList.get(i); computeSelectClauseForJoin(mapperSql, mapperProfile, ancesResultMapConfig, descOtoIdx, isFirst, true); // Set the flat 'the first one to one association' to false. isFirst = false; // If no peer, than continue to loop. hasPeer = descOtoIdx.isHasPeer(); if (hasPeer == false) { continue; } logger.debug("HAS PEER: Father table name '" + descOtoIdx.getFatherTableName() + "', son table name '" + descOtoIdx.getSonTableName() + "'"); // Set break point as current element. breakpoint = i; logger.debug("BREAK: Break at index '" + breakpoint + "'"); // If 'fatherOtoIndex' is not null, then begin with next element of the 'fatherOtoIndex'. fatherOtoIndex = descOtoIdx.getFatherOtoIndex(); if (fatherOtoIndex != null) { fatherLoc = descOtoIdx.getFatherOtoIndexLoc(); } else { fatherLoc = -1; } logger.debug("LOC FATHER: Locate father at '" + fatherLoc + "'"); // Get 'descOtoIdx' in the ascendant order. for (int j = fatherLoc + 1; j < breakpoint; j++) { /********************************************************************************************** * Get current element and handle it. **********************************************************************************************/ logger.debug("ASCENDANT: Get element at index '" + j + "'"); descOtoIdx = descOtoIdxList.get(j); computeSelectClauseForJoin(mapperSql, mapperProfile, ancesResultMapConfig, descOtoIdx, isFirst, false); } // If 'fatherOtoIndex' is not null, then continue with the location of 'fatherOtoIndex'. if (fatherOtoIndex == null) { logger.debug("EXIT TREE: Exit because no father available."); break; } else { i = fatherLoc + 1; logger.debug("CONTINUE DESC: Continue descendant '" + fatherLoc + "'"); } } /********************************************************************************************** * Handle 'filter' from 'ancesResultMapConfig' for higher performance. **********************************************************************************************/ List<FilterConfig> filterList = ancesResultMapConfig.getFilterConfig(); if (filterList != null) { StringBuffer joinClause = mapperSql.getJoinClause(); StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); StringBuffer whereClause = mapperSql.getWhereClause(); logger.debug("FILTER: 'filterList' of current 'ancesResultMapConfig' is not null."); if (StringUtils.isNotBlank(joinClause) || StringUtils.isNotBlank(primaryKeyClause) || StringUtils.isNotBlank(whereClause)) { populateFilterConfig(mapperProfile, whereClause, ancesResultMapConfig, MapperElm.SQL_AND_SIMPLE); } else { populateFilterConfig(mapperProfile, whereClause, ancesResultMapConfig, MapperElm.SQL_WHERE_SIMPLE); } } else { logger.debug("FILTER: 'filterList' of current 'ancesResultMapConfig' is null."); } } /** * ??? join select ?? * * @param mapperSql * @param mapperProfile * @param ancesResultMapConfig * @param descOtoIdx * @param isFirst * @param reverse * @throws AppException */ private void computeSelectClauseForJoin(MapperSql mapperSql, MapperProfile mapperProfile, ResultMapConfig ancesResultMapConfig, OneToOneIdx descOtoIdx, boolean isFirst, boolean reverse) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeSelectClauseForJoin'."); try { /****************************************************************************************** * Build select clause. ******************************************************************************************/ // Left table and right table are used to describe join relationship in SQL. // And left table name is 'mediTableName' or 'fatherTableName', 'mediTableName' takes higher preference. String leftTableName = OneToOneIdxFacade.getRelLeftTableName(descOtoIdx); String leftTableAlias = OneToOneIdxFacade.getRelLeftTableAlias(descOtoIdx); String rightTableName = descOtoIdx.getSonTableName(); String rightTableAlias = descOtoIdx.getSonTableAlias(); // If no DB table exist in cache according to the right table name, then return. OrmTable rightOrmTable = CtxCacheFacade.lookupOrmTable(rightTableName); if (rightOrmTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + rightTableName); return; } // Compute the select clause. RelConfig descOtoConfig = descOtoIdx.getOneToOne(); computeSelectClause(mapperSql, mapperProfile, descOtoIdx, descOtoConfig.getResultMapConfig(), rightOrmTable); /****************************************************************************************** * Build from clause. ******************************************************************************************/ int joinType = mapperSql.getJoinType(); StringBuffer fromClause = mapperSql.getFromClause(); if (joinType == MapperSql.JOIN_TYPE_PUBLIC_INNER || joinType == MapperSql.JOIN_TYPE_PRIVATE_INNER) { if (StringUtils.isNotBlank(fromClause)) { StringHelper.newLine(fromClause, JavaSrcElm.UNIT_OF_INDENT, 3); fromClause.append(MapperElm.COMMA + MapperElm.WHITE_SPACE); } else { MapperFormatter.beginFromStatement(fromClause); } // If it is the first one to one association for reverse, then append right table then left table. if (isFirst == true && reverse == true) { fromClause.append( MapperFormatter.getTableNamePair(mapperProfile, rightTableName, rightTableAlias)); StringHelper.newLine(fromClause, JavaSrcElm.UNIT_OF_INDENT, 3); fromClause.append(MapperElm.COMMA + MapperElm.WHITE_SPACE); fromClause .append(MapperFormatter.getTableNamePair(mapperProfile, leftTableName, leftTableAlias)); } // If it is not the first one to one association for reverse, then append left table only. else if (isFirst == false && reverse == true) { fromClause .append(MapperFormatter.getTableNamePair(mapperProfile, leftTableName, leftTableAlias)); } // Otherwise, append right table. else { fromClause.append( MapperFormatter.getTableNamePair(mapperProfile, rightTableName, rightTableAlias)); } if (joinType == MapperSql.JOIN_TYPE_PUBLIC_INNER) { computeJoinClauseForPublicInnerJoin(mapperSql, mapperProfile, descOtoIdx, reverse); } else { computeJoinClauseForIntnlInnerJoin(mapperSql, mapperProfile, descOtoIdx, reverse); } } else { computeJoinClauseForOuterJoin(mapperSql, mapperProfile, descOtoIdx, isFirst, reverse); } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } /** * ? * * @param mapperSql * @param mapperProfile * @param descOtoIdx * @param reverse * @throws AppException */ private void computeJoinClauseForPublicInnerJoin(MapperSql mapperSql, MapperProfile mapperProfile, OneToOneIdx descOtoIdx, boolean reverse) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeJoinClauseForPublicInnerJoin'."); /****************************************************************************************** * Build join clause. ******************************************************************************************/ StringBuffer joinClause = mapperSql.getJoinClause(); if (StringUtils.isNotBlank(joinClause)) { MapperFormatter.beginAndStatement(joinClause); } else { MapperFormatter.beginWhereStatement(joinClause); } // Attribute name of Java class, mapped to column name in DB table. RelConfig descOtoConfig = descOtoIdx.getOneToOne(); String leftTableName = OneToOneIdxFacade.getRelLeftTableName(descOtoIdx); String leftTableAlias = OneToOneIdxFacade.getRelLeftTableAlias(descOtoIdx); String rightTableName = descOtoIdx.getSonTableName(); String rightTableAlias = descOtoIdx.getSonTableAlias(); String leftAttrName = OneToOneIdxFacade.getRelLeftAttrName(descOtoIdx); String rightAttrName = descOtoConfig.getSonAttr(); String leftColumnName = JavaFormatter.getDbStyle(leftAttrName); String rightColumnName = JavaFormatter.getDbStyle(rightAttrName); // Change the column name into full name containing alias. leftColumnName = MapperFormatter.getColumnFullName(mapperProfile, leftTableName, leftTableAlias, leftColumnName); rightColumnName = MapperFormatter.getColumnFullName(mapperProfile, rightTableName, rightTableAlias, rightColumnName); // Reverse the order because of handling tables from the last to the first. if (reverse == true) { joinClause.append(rightColumnName); joinClause.append(MapperElm.EQUAL); joinClause.append(leftColumnName); } else { joinClause.append(leftColumnName); joinClause.append(MapperElm.EQUAL); joinClause.append(rightColumnName); } /********************************************************************************************** * Handle 'filter' from 'descResultMapConfig' in every one to one. **********************************************************************************************/ ResultMapConfig descResultMapConfig = descOtoConfig.getResultMapConfig(); List<FilterConfig> filterList = descResultMapConfig.getFilterConfig(); StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); StringBuffer whereClause = mapperSql.getWhereClause(); if (filterList != null) { logger.debug("FILTER: 'filterList' of current 'descResultMapConfig' is not null."); if (StringUtils.isNotBlank(joinClause) || StringUtils.isNotBlank(primaryKeyClause) || StringUtils.isNotBlank(whereClause)) { populateFilterConfig(mapperProfile, whereClause, descResultMapConfig, MapperElm.SQL_AND_SIMPLE); } else { populateFilterConfig(mapperProfile, whereClause, descResultMapConfig, MapperElm.SQL_WHERE_SIMPLE); } } else { logger.debug("FILTER: 'filterList' of current 'descResultMapConfig' is null."); } } /** * ? * * @param mapperSql * @param mapperProfile * @param descOtoIdx * @param reverse * @throws AppException */ private void computeJoinClauseForIntnlInnerJoin(MapperSql mapperSql, MapperProfile mapperProfile, OneToOneIdx descOtoIdx, boolean reverse) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeJoinClauseForPrivateInnerJoin'."); /****************************************************************************************** * Build join clause. ******************************************************************************************/ // Append join condition into where clause. StringBuffer whereClause = mapperSql.getWhereClause(); if (StringUtils.isNotBlank(whereClause)) { MapperFormatter.beginAndStatement(whereClause); } else { MapperFormatter.beginWhereStatement(whereClause); } // Attribute name of Java class, mapped to column name in DB table. RelConfig descOtoConfig = descOtoIdx.getOneToOne(); String leftTableName = OneToOneIdxFacade.getRelLeftTableName(descOtoIdx); String leftTableAlias = OneToOneIdxFacade.getRelLeftTableAlias(descOtoIdx); String rightTableName = descOtoIdx.getSonTableName(); String rightTableAlias = descOtoIdx.getSonTableAlias(); String leftAttrName = OneToOneIdxFacade.getRelLeftAttrName(descOtoIdx); String rightAttrName = descOtoConfig.getSonAttr(); String leftColumnName = JavaFormatter.getDbStyle(leftAttrName); String rightColumnName = JavaFormatter.getDbStyle(rightAttrName); // Change the column name into full name containing alias. leftColumnName = MapperFormatter.getColumnFullName(mapperProfile, leftTableName, leftTableAlias, leftColumnName); rightColumnName = MapperFormatter.getColumnFullName(mapperProfile, rightTableName, rightTableAlias, rightColumnName); // Reverse the order because of handling tables from the last to the first. if (reverse == true) { whereClause.append(rightColumnName); whereClause.append(MapperElm.EQUAL); whereClause.append(leftColumnName); } else { whereClause.append(leftColumnName); whereClause.append(MapperElm.EQUAL); whereClause.append(rightColumnName); } /********************************************************************************************** * Handle 'filter' from 'descResultMapConfig' in every one to one. **********************************************************************************************/ ResultMapConfig descResultMapConfig = descOtoConfig.getResultMapConfig(); List<FilterConfig> filterList = descResultMapConfig.getFilterConfig(); if (filterList != null) { logger.debug("FILTER: 'filterList' of current 'descResultMapConfig' is not null."); if (StringUtils.isNotBlank(whereClause)) { populateFilterConfig(mapperProfile, whereClause, descResultMapConfig, MapperElm.SQL_AND_SIMPLE); } else { populateFilterConfig(mapperProfile, whereClause, descResultMapConfig, MapperElm.SQL_WHERE_SIMPLE); } } else { logger.debug("FILTER: 'filterList' of current 'descResultMapConfig' is null."); } } // private void computeJoinClauseForOuterJoin(MapperProfile mapperProfile, OneToOneIdx descOtoIdx, StringBuffer fromClause, // StringBuffer primaryKeyClause, StringBuffer whereClause, boolean isFirst, boolean reverse) throws AppException { private void computeJoinClauseForOuterJoin(MapperSql mapperSql, MapperProfile mapperProfile, OneToOneIdx descOtoIdx, boolean isFirst, boolean reverse) throws AppException { logger.debug("ENTRY: Prepare to execute 'computeJoinClauseForOuterJoin'."); /****************************************************************************************** * Build from clause. ******************************************************************************************/ StringBuffer fromClause = mapperSql.getFromClause(); if (StringUtils.isNotBlank(fromClause)) { StringHelper.newLine(fromClause, JavaSrcElm.UNIT_OF_INDENT, 3); } else { MapperFormatter.beginFromStatement(fromClause); } // If it is the first one to one association for reverse, then append right table then left table. String rightTableName = descOtoIdx.getSonTableName(); String rightTableAlias = descOtoIdx.getSonTableAlias(); if (isFirst == true && reverse == true) { fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, rightTableName, rightTableAlias)); StringHelper.newLine(fromClause, JavaSrcElm.UNIT_OF_INDENT, 3); fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, descOtoIdx, true)); } // If it is not the first one to one association for reverse, then append left table only. else if (isFirst == false && reverse == true) { fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, descOtoIdx, true)); } // Otherwise, append right table. else { fromClause.append(MapperFormatter.getTableNamePair(mapperProfile, descOtoIdx, false)); } /********************************************************************************************** * Handle 'filter' from 'descResultMapConfig' in every one to one. **********************************************************************************************/ RelConfig descOtoConfig = descOtoIdx.getOneToOne(); ResultMapConfig descResultMapConfig = descOtoConfig.getResultMapConfig(); List<FilterConfig> filterList = descResultMapConfig.getFilterConfig(); // StringBuffer primaryKeyClause = mapperSql.getPrimaryKeyClause(); // StringBuffer whereClause = mapperSql.getWhereClause(); // If the primaryKeyClause is not blank, then ignore the filter config. // if (primaryKeyClause == null || primaryKeyClause.length() == 0) { // populateFilterConfig(whereClause, descResultMapConfig, MapperElm.SQL_WHERE_SIMPLE); // } if (filterList != null) { // logger.debug("FILTER: 'filterList' of current 'descResultMapConfig' is not null."); // if (primaryKeyClause != null && primaryKeyClause.length() > 0 || whereClause.length() > 0) { populateFilterConfig(mapperProfile, fromClause, descResultMapConfig, MapperElm.SQL_AND_SIMPLE); // } else { // populateFilterConfig(mapperProfile, whereClause, descResultMapConfig, MapperElm.SQL_WHERE_SIMPLE); // } } else { logger.debug("FILTER: 'filterList' of current 'descResultMapConfig' is null."); } } private void populateFilterConfig(MapperProfile mapperProfile, StringBuffer filterConfition, ResultMapConfig resultMapConfig, String filterPrefix) throws AppException { try { // Get 'filter' from current resultMapConfig. List<FilterConfig> filterList = resultMapConfig.getFilterConfig(); if (filterList == null) { return; } String tableName = resultMapConfig.getTableName(); String tableAlias = resultMapConfig.getTableAlias(); FilterConfig filterConfig = null; String begin = null; String attribute = null; String comparator = null; String value = null; String constant = null; String end = null; ClassAnalyzer classAnalyzer = new ClassAnalyzer(); logger.debug("FILTER: The size of current 'filterList' is: " + filterList.size()); for (int j = 0; j < filterList.size(); j++) { filterConfig = filterList.get(j); begin = filterConfig.getBegin(); attribute = filterConfig.getAttribute(); comparator = filterConfig.getComparator(); value = filterConfig.getValue(); constant = filterConfig.getConstant(); end = filterConfig.getEnd(); StringHelper.newLine(filterConfition, JavaSrcElm.UNIT_OF_INDENT, 3); // Automatically set prefix for where clause according to filter. if (j == 0) { // whereClause.append(MapperElm.WHITE_SPACE); filterConfition.append(filterPrefix); if (StringUtils.isNotBlank(begin) == true) { filterConfition.append(MapperElm.WHITE_SPACE); filterConfition.append(begin); } } else { if (StringUtils.isNotBlank(begin) == true) { // filterConfition.append(MapperElm.WHITE_SPACE); filterConfition.append(begin); } } if (StringUtils.isNotBlank(attribute) == true) { String columnName = JavaFormatter.getDbStyle(attribute); String columnFullName = MapperFormatter.getColumnFullName(mapperProfile, tableName, tableAlias, columnName); filterConfition.append(MapperElm.WHITE_SPACE); filterConfition.append(columnFullName); } if (StringUtils.isNotBlank(comparator) == true) { filterConfition.append(MapperElm.WHITE_SPACE); filterConfition.append(comparator); } if (StringUtils.isNotBlank(value) == true) { filterConfition.append(MapperElm.WHITE_SPACE); filterConfition.append(value); } else if (StringUtils.isNotBlank(constant) == true) { Object objValue = classAnalyzer.getConstValue(constant); filterConfition.append(MapperElm.WHITE_SPACE); if (objValue.getClass().getName().equals(JavaSrcElm.LANG_STRING_FULL) == true) { filterConfition.append(JavaSrcElm.SINGLE_QUOTATION); filterConfition.append(objValue.toString()); filterConfition.append(JavaSrcElm.SINGLE_QUOTATION); } else { filterConfition.append(objValue.toString()); } } if (StringUtils.isNotBlank(end) == true) { filterConfition.append(MapperElm.WHITE_SPACE); filterConfition.append(end); } } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } private void defineReusableSelectFrom4RootTab(MapperSql mapperSql, Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig resultMapConfig, OrmTable rootTable, String sqlId) throws AppException { // Lookup 'sql' element with 'sqlId', if not found, then create one. Sql sql = CtxCacheFacade.lookupSql(mapperArtifact, sqlId); if (sql != null) { return; } // Initiate a blank 'sql'. And register the new 'sql' element. sql = mapperObjFactory.createSql(); mapper.getSql().add(sql); sql.setId(sqlId); CtxCacheFacade.addSql(mapperArtifact, sqlId, sql); // Compute the select clause. computeSelectClause(mapperSql, mapperProfile, null, resultMapConfig, rootTable); // Populate from clause. computeFromClause(mapperSql, mapperProfile, resultMapConfig); // Set select clause and from clause into mapper. StringBuffer selectClause = mapperSql.getSelectClause(); StringBuffer fromClause = mapperSql.getFromClause(); sql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + selectClause.toString() + fromClause.toString() + MapperElm.CDATA_ANCHOR_END); // Define separate column name clause for easy to reuse. String columnNameId = sqlId + MapperElm.MAPPER_COL_NM; StringBuffer columnNameClause = mapperSql.getColumnNameClause(); Sql columnNameSql = mapperObjFactory.createSql(); mapper.getSql().add(columnNameSql); columnNameSql.setId(columnNameId); columnNameSql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + columnNameClause + MapperElm.CDATA_ANCHOR_END); // Define separate column alias clause for easy to reuse. String columnAliasId = sqlId + MapperElm.MAPPER_COL_ALIAS; StringBuffer columnAliasClause = mapperSql.getColumnAliasClause(); Sql columnAliasSql = mapperObjFactory.createSql(); mapper.getSql().add(columnAliasSql); columnAliasSql.setId(columnAliasId); columnAliasSql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + columnAliasClause + MapperElm.CDATA_ANCHOR_END); // Define separate from clause for easy to reuse. String fromId = sqlId + MapperElm.MAPPER_FROM; Sql fromSql = mapperObjFactory.createSql(); mapper.getSql().add(fromSql); fromSql.setId(fromId); fromSql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + fromClause + MapperElm.CDATA_ANCHOR_END); } private void defineReusableSelectFrom4MultiTab(MapperSql mapperSql, Mapper mapper, MapperArtifact mapperArtifact, String sqlId) { // Lookup 'sql' element with 'sqlId', if not found, then create one. Sql sql = CtxCacheFacade.lookupSql(mapperArtifact, sqlId); if (sql == null) { // Initiate a blank 'sql'. And register the new 'sql' element. sql = mapperObjFactory.createSql(); mapper.getSql().add(sql); sql.setId(sqlId); CtxCacheFacade.addSql(mapperArtifact, sqlId, sql); // For outer join, join condition was included inside'fromClause'. StringBuffer selectClause = mapperSql.getSelectClause(); StringBuffer fromClause = mapperSql.getFromClause(); StringBuffer joinClause = mapperSql.getJoinClause(); int joinType = mapperSql.getJoinType(); if (joinType == MapperSql.JOIN_TYPE_OUTER) { sql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + selectClause.toString() + fromClause.toString() + MapperElm.CDATA_ANCHOR_END); } // For inner join, join condition was included inside 'joinClause'. else { sql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + selectClause.toString() + fromClause.toString() + joinClause.toString() + MapperElm.CDATA_ANCHOR_END); } // Define separate column name clause for easy to reuse. String columnNameId = sqlId + MapperElm.MAPPER_COL_NM; StringBuffer columnNameClause = mapperSql.getColumnNameClause(); // String columnClause = selectClause.substring((MapperElm.SQL_SELECT + MapperElm.WHITE_SPACE).length()); Sql columnNameSql = mapperObjFactory.createSql(); mapper.getSql().add(columnNameSql); columnNameSql.setId(columnNameId); columnNameSql .setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + columnNameClause + MapperElm.CDATA_ANCHOR_END); // Define separate column alias clause for easy to reuse. String columnAliasId = sqlId + MapperElm.MAPPER_COL_ALIAS; StringBuffer columnAliasClause = mapperSql.getColumnAliasClause(); Sql columnAliasSql = mapperObjFactory.createSql(); mapper.getSql().add(columnAliasSql); columnAliasSql.setId(columnAliasId); columnAliasSql .setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + columnAliasClause + MapperElm.CDATA_ANCHOR_END); // Define separate from clause for easy to reuse. String fromId = sqlId + MapperElm.MAPPER_FROM; Sql fromSql = mapperObjFactory.createSql(); mapper.getSql().add(fromSql); fromSql.setId(fromId); // For outer join, join condition was included inside'fromClause'. if (joinType == MapperSql.JOIN_TYPE_OUTER) { fromSql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + fromClause + MapperElm.CDATA_ANCHOR_END); } // For inner join, join condition was included inside 'joinClause'. else { fromSql.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + fromClause + joinClause.toString() + MapperElm.CDATA_ANCHOR_END); } } } /** * Whether or not the including join are all inner join. * * @param descOtoIdxList * @return */ private boolean hasOuterJoin(List<OneToOneIdx> otoIndexList) throws AppException { boolean result = false; try { if (otoIndexList == null || otoIndexList.size() == 0) { throw new AppException("The given 'otoIndexList' could not be null or blank."); } OneToOneIdx otoIndex = null; RelConfig otoConfig = null; String joinType = null; for (int i = 0; i < otoIndexList.size(); i++) { otoIndex = otoIndexList.get(i); otoConfig = otoIndex.getOneToOne(); joinType = otoConfig.getJoinType(); if (StringUtils.isNotBlank(joinType) == true && (otoConfig.getJoinType().equalsIgnoreCase(MapperElm.SQL_JOIN_LEFT) == true || otoConfig.getJoinType().equalsIgnoreCase(MapperElm.SQL_JOIN_RIGHT) == true || otoConfig.getJoinType().equalsIgnoreCase(MapperElm.SQL_JOIN_FULL) == true)) { result = true; } } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } return result; } /** * TODO ??? * * @param mapper * @param mapperProfile * @param mapperArtifact * @param ancesResultMapConfig * @param descOtoIdxList * @throws AppException */ public void buildMultiTabCountBySql(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig, List<OneToOneIdx> descOtoIdxList) throws AppException { try { UserFilter userfilter = mapperProfile.getSingleMapperProfile().get(0).getUserFilter(); // The expected 'id' of 'select'. String selectId = MapperFormatter.getSelIdOfMultiTabBySql(ancesResultMapConfig, descOtoIdxList); String selectId2 = MapperFormatter.getSelIdOfRootTabBySql(ancesResultMapConfig); if (selectId.equalsIgnoreCase(selectId2)) return; selectId = MapperElm.SQL_COUNT + StringUtils.capitalize(selectId); logger.debug("SELECT: Prepare to build select with id '" + selectId + "'."); // Lookup 'select' element with id. Select select = CtxCacheFacade.lookupSelect(mapperArtifact, selectId); if (select != null) { return; } // Initiate a blank 'select' and register it. select = mapperObjFactory.createSelect(); mapper.getSelect().add(select); CtxCacheFacade.addSelect(mapperArtifact, selectId, select); // Populate attributes of select. select.setId(selectId); select.setParameterType(JavaSrcElm.SQL_CLAUSE_FULL); // Populate the 'resultClass' attribute for Select. select.setResultType(JavaSrcElm.LANG_INTEGER_FULL); // Find Table corresponding to current Select, if no Table found, then return Select without elements. String ancesTableName = ancesResultMapConfig.getTableName(); OrmTable ancesTable = CtxCacheFacade.lookupOrmTable(ancesTableName); if (ancesTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + ancesTableName); return; } // Compute the select clause. MapperSql mapperSql = new MapperSql(); computeSelectClause(mapperSql, mapperProfile, null, ancesResultMapConfig, ancesTable); // Define join type according to the association. int joinType = -1; if (descOtoIdxList == null || descOtoIdxList.size() == 0) { joinType = MapperSql.JOIN_TYPE_NONE; } else if (descOtoIdxList != null && descOtoIdxList.size() != 0 && hasOuterJoin(descOtoIdxList) == true) { joinType = MapperSql.JOIN_TYPE_OUTER; } else { joinType = MapperSql.JOIN_TYPE_PUBLIC_INNER; } mapperSql.setJoinType(joinType); // Populate different kinds of clause according to join tyoe. computeSqlElmtForJoin(mapperSql, mapperProfile, ancesResultMapConfig, descOtoIdxList); String wherecause = mapperSql.getJoinClause() + mapperSql.getWhereClause().toString(); if (wherecause.indexOf(MapperElm.SQL_WHERE_SIMPLE) == -1) { wherecause = wherecause.replaceFirst(MapperElm.SQL_AND_SIMPLE, MapperElm.SQL_WHERE_SIMPLE); } String fromcause = mapperSql.getFromClause().toString(); if (StringUtils.isBlank(fromcause)) { fromcause = " from " + ancesResultMapConfig.getTableName() + " " + ancesResultMapConfig .getTableName().replace(JavaSrcElm.DOT, JavaSrcElm.UNDER_LINE + JavaSrcElm.UNDER_LINE) + " "; } select.setCDataBegin(MapperElm.CDATA_ANCHOR_BEGIN + "select count(1) " + fromcause + wherecause + MapperElm.CDATA_ANCHOR_END); Trim overAllTrim = mapperObjFactory.createTrim(); select.getTrim().add(overAllTrim); If trimIf = mapperObjFactory.createIf(); trimIf.setTest(MapperElm.ATTR__WHERE_CLAUSE + JavaSrcElm.EXPR_OBJ_NOT_NULL); overAllTrim.getIf().add(trimIf); Trim whereTrim = mapperObjFactory.createTrim(); trimIf.getTrim().add(whereTrim); // TODO Changed at 2015.05.27??? if (joinType == MapperSql.JOIN_TYPE_OUTER || joinType == MapperSql.JOIN_TYPE_NONE) { if (wherecause.indexOf(MapperElm.SQL_WHERE_SIMPLE) == -1) { whereTrim.setPrefix(MapperElm.SQL_WHERE_FULL); } else { whereTrim.setPrefix(MapperElm.SQL_AND_FULL); } } else { whereTrim.setPrefix(MapperElm.SQL_AND_FULL); } whereTrim.setPrefixOverrides(MapperElm.SQL_AND_SIMPLE + MapperElm.WHITE_SPACE); whereTrim.setCDataBegin( MapperElm.CDATA_ANCHOR_BEGIN + MapperElm.ANCHOR_WHERE_CLAUSE + MapperElm.CDATA_ANCHOR_END); if (userfilter != null) { if (whereTrim.getPrefix().equals(MapperElm.SQL_AND_FULL)) { select.getChoose().add( UserFilterBulider.buildFilter(MapperElm.SQL_AND_FULL, mapperObjFactory, userfilter)); } else { whereTrim.getChoose().add( UserFilterBulider.buildFilter(MapperElm.SQL_AND_FULL, mapperObjFactory, userfilter)); If noWhereIf = mapperObjFactory.createIf(); noWhereIf.setTest(MapperElm.ATTR__WHERE_CLAUSE + JavaSrcElm.EXPR_OBJ_IS_NULL); select.getIf().add(noWhereIf); noWhereIf.getChoose().add( UserFilterBulider.buildFilter(whereTrim.getPrefix(), mapperObjFactory, userfilter)); } } // Register DAO methods. List<String> paramTypeNameList = new ArrayList<String>(); paramTypeNameList.add(JavaSrcElm.SQL_CLAUSE_FULL); String comments = ancesResultMapConfig.getComments() + JavaSrcElm.COUNT_MULTI_TABLE; CtxCacheFacade.addDaoMethod(mapperProfile, mapperArtifact, ancesTableName, selectId, paramTypeNameList, JavaSrcElm.LANG_INTEGER_FULL, comments); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } }