org.mybatisorm.EntityManager.java Source code

Java tutorial

Introduction

Here is the source code for org.mybatisorm.EntityManager.java

Source

/* Copyright 2012 The MyBatisORM Team
 * 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 org.mybatisorm;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.mybatisorm.annotation.handler.SqlCommandAnnotation;
import org.mybatisorm.exception.InvalidSqlSourceException;
import org.mybatisorm.exception.MyBatisOrmException;
import org.mybatisorm.sql.builder.SqlBuilder;
import org.mybatisorm.sql.source.ValueGenerator;
import org.mybatisorm.sql.source.ValueGeneratorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;

/**
 * @author Donghyeok Kang(wolfkang@gmail.com)
 */
public class EntityManager extends SqlSessionDaoSupport implements InitializingBean {

    private static Logger logger = Logger.getLogger(EntityManager.class);

    private static final String SOURCE_COUNT = "Count";
    private static final String SOURCE_DELETE = "Delete";
    private static final String SOURCE_INCREMENT = "Increment";
    private static final String SOURCE_LIST = "List";
    private static final String SOURCE_UPDATE = "Update";
    private static final String SOURCE_LOAD = "Load";
    private static final String SOURCE_PAGE = "Page";
    private static final String SOURCE_INSERT = "Insert";
    private static final String SOURCE_ROWNUM = "Rownum";
    private static final String SOURCE_LIMIT = "Limit";
    private static final String SOURCE_GENERATOR = "Generator";

    private Configuration configuration;
    private SqlSession sqlSession;
    private SqlSourceBuilder sqlSourceBuilder;
    private String sourceType = "mysql"; //  ? "mysql"
    private Map<String, Class<?>> sqlSourceClassMap;
    private ValueGenerator valueGenerator;

    public String getSourceType() {
        return sourceType;
    }

    public void setSourceType(String sourceType) {
        this.sourceType = sourceType;
    }

    public <T> T getDao(Class<T> clazz) {
        return getSqlSession().getMapper(clazz);
    }

    protected void initDao() throws Exception {
        sqlSession = getSqlSession();
        configuration = sqlSession.getConfiguration();
        sqlSourceBuilder = new SqlSourceBuilder(configuration);
        sqlSourceClassMap = new HashMap<String, Class<?>>();

        ResourceBundle bundle = new PropertyResourceBundle(
                this.getClass().getClassLoader().getResourceAsStream("sql-sources.properties"));
        // ClassLoader.getSystemResourceAsStream("SqlSources.properties"));
        for (String source : bundle.getString(sourceType + ".sqlsources").split(",")) {
            sqlSourceClassMap.put(source, Class.forName(bundle.getString(sourceType + "." + source)));
        }
        valueGenerator = (ValueGeneratorImpl) getSourceTypeClass(SOURCE_GENERATOR).newInstance();
        valueGenerator.setConfiguration(configuration);
    }

    private Class<?> getSourceTypeClass(String className) {
        return sqlSourceClassMap.get(className);
    }

    /**
     * condition where ? ?  ?? rownum? .
     * 
     * @param parameter
     * @param condition
     * @param orderBy
     * @return rownum 
     */
    public int rownum(Object parameter, Condition condition, String orderBy) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_ROWNUM, clazz);
        Object result = sqlSession.selectOne(statementName, new Query(parameter, condition, orderBy));
        return (result == null) ? 0 : (Integer) result;
    }

    /**
     * object? null?  ? ? ?. ? ?? ??.
     * 
     * @param parameter
     */
    public void increment(Object parameter) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_INCREMENT, clazz);
        sqlSession.update(statementName, parameter);
    }

    /**
     * object? null ?   ?? insert .
     * 
     * @param parameter
     */
    public void insert(Object parameter) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_INSERT, clazz);
        sqlSession.insert(statementName, parameter);
    }

    /**
     * object? primaryKey true?  ? ??, null ?    ?? update .
     * 
     * @param parameter
     */
    public void update(Object parameter) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_UPDATE, clazz);
        sqlSession.update(statementName, parameter);
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? delete .
     * 
     * @param parameter
     */
    public void delete(Object parameter) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_DELETE, clazz);
        sqlSession.delete(statementName, parameter);
    }

    /**
     * condition where ? ?  ?? delete .
     * 
     * @param parameter
     * @param condition
     * @since 0.2.2
     */
    public void delete(Object parameter, String condition) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_DELETE, clazz);
        sqlSession.delete(statementName, new Query(parameter, condition, null));
    }

    /**
     * condition where ? ?  ?? delete .
     * 
     * @param parameter
     * @param condition
     * @since 0.2.2
     */
    public void delete(Object parameter, Condition condition) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_DELETE, clazz);
        sqlSession.delete(statementName, new Query(parameter, condition, null));
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? 1 row select ?,
     * parameter ?? ? setting .
     * 
     * @param parameter
     * @return select   true,  false
     */
    public boolean load(Object parameter) {
        Object result = get(parameter);
        if (result != null) {
            BeanUtils.copyProperties(result, parameter);
            return true;
        }
        return false;
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? 1 row select.
     * 
     * @param parameter
     * @return select  object
     */
    @SuppressWarnings("unchecked")
    public <T> T get(T parameter) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_LOAD, clazz);
        T result = (T) sqlSession.selectOne(statementName, parameter);
        return result;
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? select count(*) .
     * 
     * @param parameter
     * @return select count(*) 
     */
    public int count(Object parameter) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_COUNT, clazz);
        return (Integer) sqlSession.selectOne(statementName, parameter);
    }

    /**
     * condition where ? ?  ?? select count(*) .
     * 
     * @param parameter
     * @param condition
     * @return select count(*) 
     */
    public int count(Object parameter, String condition) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_COUNT, clazz);
        return (Integer) sqlSession.selectOne(statementName, new Query(parameter, condition, null));
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? select count(*) .
     * 
     * @param parameter
     * @return select count(*) 
     */
    public int count(Object parameter, Condition condition) {
        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_COUNT, clazz);
        return (Integer) sqlSession.selectOne(statementName, new Query(parameter, condition, null));
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? select,
     * object ?? ? ? java.util.List ?  .
     * )
     * Comment comment = new Comment();
     * comment.setPlusCount(1);
     * comment.setCommentKey(10);
     * entityManager.list(comment,"register_date ASC");
     * ? SQL
     * SELECT * FROM plus_count = 1 AND comment_key = 10
     * 
     * @param parameter
     * @return select  
     */
    public <T> List<T> list(T parameter) {
        return list(new Query(parameter));
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? select,
     * orderBy? ? ,
     * object ?? ? ? java.util.List ?  .
     * )
     * Comment comment = new Comment();
     * comment.setPlusCount(1);
     * comment.setCommentKey(10);
     * entityManager.list(comment,"register_date ASC");
     * ? SQL
     * SELECT * FROM plus_count = 1 AND comment_key = 10 ORDER BY register_date ASC
     * 
     * @param parameter
     * @param orderBy
     * @return
     */
    public <T> List<T> list(T parameter, String orderBy) {
        return list(new Query(parameter, orderBy));
    }

    public <T> List<T> list(T parameter, String orderBy, int rows) {
        return list(parameter, null, orderBy, 1, rows);
    }

    /**
     * condition where ? ?  ?? select ?,
     * object ?? ? ? java.util.List ?  .
     * )
     * Comment comment = new Comment();
     * comment.setPlusCount(1);
     * entityManager.list(comment,"plus_count >= #{plusCount}",null);
     * ? SQL
     * SELECT * FROM plus_count >= 1
     * 
     * @param parameter
     * @param condition
     * @param orderBy
     * @return select  List ?
     */
    public <T> List<T> list(T parameter, String condition, String orderBy) {
        return list(new Query(parameter, condition, orderBy));
    }

    /**
     * @param parameter
     * @param condition
     * @param orderBy
     * @return
     */
    public <T> List<T> list(T parameter, Condition condition, String orderBy) {
        return list(new Query(parameter, condition, orderBy));
    }

    /**
     * @param parameter
     * @param condition
     * @return
     */
    public <T> List<T> list(T parameter, Condition condition) {
        return list(new Query(parameter, condition, null));
    }

    /**
     * @param parameter
     * @param condition
     * @param orderBy
     * @return
     */
    private <T> List<T> list(Query query) {
        String statementName = addStatement(SOURCE_LIST, query.getParameter().getClass());
        return sqlSession.selectList(statementName, query);
    }

    /**
     * @param parameter
     * @param condition
     * @param orderBy
     * @param rows
     * @return
     */
    public <T> List<T> list(T parameter, Condition condition, String orderBy, int rows) {
        return list(parameter, condition, orderBy, 1, rows);
    }

    /**
     * @param parameter
     * @param condition
     * @param orderBy
     * @param start
     * @param rows
     * @return
     */
    public <T> List<T> list(T parameter, Condition condition, String orderBy, int start, int rows) {
        if (orderBy == null)
            throw new MyBatisOrmException("The orderBy cannot be null.");

        Class<?> clazz = parameter.getClass();
        String statementName = addStatement(SOURCE_LIMIT, clazz);
        Query query = new Query(parameter, condition, orderBy);
        query.setStart(start);
        query.setRows(rows);
        List<T> list = sqlSession.selectList(statementName, query);
        return list;
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? count()  ?,
     * ?? select , java.util.List? , ? Page ??  .
     * 
     * @param parameter ? ?
     * @param pageNumber ? 
     * @param rows ?  ? 
     * @return select  Page ?
     */
    public <T> Page<T> page(T parameter, int pageNumber, int rows) {
        return page(parameter, null, pageNumber, rows);
    }

    /**
     * object? null?  field?  AND  where ? ?  ?? count()  ?,
     * ?? select , java.util.List? , ? Page ??  .
     * 
     * @param parameter ? ?
     * @param orderBy  ?
     * @param pageNumber ? 
     * @param rows ?  ? 
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> Page<T> page(T parameter, String orderBy, int pageNumber, int rows) {
        int count = count(parameter);
        Page<T> page = new Page<T>(pageNumber, rows, count);
        if (count > (pageNumber - 1) * rows) {
            Class<?> clazz = parameter.getClass();
            String statementName = addStatement(SOURCE_PAGE, clazz);
            page.setList((List<T>) sqlSession.selectList(statementName,
                    new Query(parameter, orderBy, pageNumber, rows)));
        }
        return page;
    }

    /**
     * condition where ? ?  ?? count()  ?,
     * ?? select , java.util.List? , ? Page ??  .
     * object? field ? where ? ? .
     * 
     * @param clazz  ?
     * @param condition 
     * @param orderBy  ?
     * @param pageNumber ? 
     * @param rows ?  ? 
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> Page<T> page(T parameter, String condition, String orderBy, int pageNumber, int rows) {
        int count = count(parameter, condition);
        Page<T> page = new Page<T>(pageNumber, rows, count);
        if (count > (pageNumber - 1) * rows) {
            Class<?> clazz = parameter.getClass();
            String statementName = addStatement(SOURCE_PAGE, clazz);
            page.setList((List<T>) sqlSession.selectList(statementName,
                    new Query(parameter, condition, orderBy, pageNumber, rows)));
        }
        return page;
    }

    /**
     * condition where ? ?  ?? count()  ?,
     * ?? select , java.util.List? , ? Page ??  .
     * object? field ? where ? ? .
     * 
     * @param clazz  ?
     * @param condition 
     * @param orderBy  ?
     * @param pageNumber ? 
     * @param rows ?  ? 
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> Page<T> page(T parameter, Condition condition, String orderBy, int pageNumber, int rows) {
        int count = count(parameter, condition);
        Page<T> page = new Page<T>(pageNumber, rows, count);
        if (count > (pageNumber - 1) * rows) {
            Class<?> clazz = parameter.getClass();
            String statementName = addStatement(SOURCE_PAGE, clazz);
            page.setList((List<T>) sqlSession.selectList(statementName,
                    new Query(parameter, condition, orderBy, pageNumber, rows)));
        }
        return page;
    }

    private synchronized String addStatement(String sourceName, Class<?> type) {
        Class<?> sqlSourceClass = getSourceTypeClass(sourceName);
        String id = "_" + sqlSourceClass.getSimpleName() + type.getSimpleName();
        if (!configuration.hasStatement(id)) {
            if (logger.isDebugEnabled())
                logger.debug("add a mapped statement, " + id);
            Constructor<?> constructor = null;
            try {
                constructor = sqlSourceClass.getDeclaredConstructor(SqlSourceBuilder.class, Class.class);
            } catch (Exception e) {
                throw new InvalidSqlSourceException(e);
            }
            SqlBuilder sqlBuilder = (SqlBuilder) BeanUtils.instantiateClass(constructor, sqlSourceBuilder, type);
            SqlCommandType sqlType = SqlCommandAnnotation.getSqlCommand(sqlSourceClass).value();
            MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlBuilder,
                    sqlType);
            statementBuilder.timeout(configuration.getDefaultStatementTimeout());
            Class<?> resultType = sqlBuilder.getResultType();
            if (resultType != null) {
                List<ResultMap> resultMaps = new ArrayList<ResultMap>();
                ResultMap.Builder resultMapBuilder = new ResultMap.Builder(configuration,
                        statementBuilder.id() + "-Inline", resultType, sqlBuilder.getResultMappingList());
                resultMaps.add(resultMapBuilder.build());
                // if (logger.isDebugEnabled()) logger.debug("add a resultMap [" + statementBuilder.id() + "-Inline] ==> [" + id + "]");
                statementBuilder.resultMaps(resultMaps);
            }
            if (SqlCommandType.INSERT.equals(sqlType)) {
                valueGenerator.generate(statementBuilder, id, type);
            }
            MappedStatement statement = statementBuilder.build();
            configuration.addMappedStatement(statement);
        }
        return id;
    }
}