Java tutorial
/* 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; } }