├── .editorconfig ├── .gitignore ├── README.md ├── doc └── 时序图-Mybatis-Ext.png ├── license.txt ├── mybatis-ext-core ├── pom.xml └── src │ ├── main │ └── java │ │ └── tech │ │ └── wetech │ │ └── mybatis │ │ ├── EntityMapperRegistry.java │ │ ├── ExtConfiguration.java │ │ ├── ExtSqlSessionFactoryBuilder.java │ │ ├── ExtXMLConfigBuilder.java │ │ ├── PagingExecutor.java │ │ ├── ParametersFinder.java │ │ ├── annotation │ │ ├── DeleteEntityProvider.java │ │ ├── EntityProviderSqlCommandType.java │ │ ├── InsertEntityProvider.java │ │ ├── LogicDelete.java │ │ ├── SelectEntityKey.java │ │ ├── SelectEntityProvider.java │ │ ├── UpdateEntityProvider.java │ │ └── Where.java │ │ ├── builder │ │ ├── EntityMapperAnnotationResolver.java │ │ ├── EntityMapperBuilder.java │ │ ├── EntityMapping.java │ │ └── EntityMappingBuilder.java │ │ ├── dialect │ │ ├── Dialect.java │ │ ├── DialectClient.java │ │ ├── DialectType.java │ │ └── db │ │ │ ├── DB2Dialect.java │ │ │ ├── DerbyDialect.java │ │ │ ├── H2Dialect.java │ │ │ ├── HSQLDialect.java │ │ │ ├── MySQLDialect.java │ │ │ ├── OracleDialect.java │ │ │ ├── PostgreSQLDialect.java │ │ │ ├── SQLServerDialect.java │ │ │ └── SqlServer2012Dialect.java │ │ ├── domain │ │ ├── Page.java │ │ ├── Property.java │ │ └── Sort.java │ │ ├── example │ │ ├── Criteria.java │ │ ├── Example.java │ │ ├── MapperCriteria.java │ │ ├── MapperExample.java │ │ └── Sort.java │ │ ├── mapper │ │ ├── BaseEntitySqlBuilder.java │ │ ├── BaseMapper.java │ │ └── Mapper.java │ │ └── util │ │ └── EntityMappingUtil.java │ └── test │ ├── java │ └── tech │ │ └── wetech │ │ └── mybatis │ │ ├── BaseDataTest.java │ │ ├── databases │ │ └── goods │ │ │ ├── goods-derby-dataload.sql │ │ │ ├── goods-derby-schema.sql │ │ │ └── goods-derby.properties │ │ ├── entity │ │ └── Goods.java │ │ ├── generator │ │ ├── RoleExample.java │ │ └── RoleMapper.xml │ │ └── mapper │ │ ├── GoodsMapper.java │ │ ├── GoodsMapper.xml │ │ └── GoodsMapperTest.java │ └── resources │ └── log4j.properties ├── mybatis-ext-parent └── pom.xml ├── mybatis-ext-simple ├── mybatis-ext-simple-java │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── tech │ │ │ └── wetech │ │ │ └── mybatis │ │ │ └── simple │ │ │ ├── Simple.java │ │ │ ├── entity │ │ │ └── User.java │ │ │ └── mapper │ │ │ ├── UserMapper.java │ │ │ └── UserMapper.xml │ │ └── resources │ │ ├── data.sql │ │ └── schema.sql ├── mybatis-ext-simple-springboot │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── tech │ │ │ │ └── wetech │ │ │ │ └── mybatis │ │ │ │ └── simple │ │ │ │ ├── MybatisExtSimpleSpringbootApplication.java │ │ │ │ ├── controller │ │ │ │ └── UserController.java │ │ │ │ ├── entity │ │ │ │ └── User.java │ │ │ │ ├── mapper │ │ │ │ └── UserMapper.java │ │ │ │ └── service │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── data.sql │ │ │ ├── mapper │ │ │ └── UserMapper.xml │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── tech │ │ └── wetech │ │ └── mybatis │ │ └── simple │ │ └── MybatisExtSimpleSpringbootApplicationTests.java ├── mybatis-ext-simple-springmvc │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── tech │ │ │ └── wetech │ │ │ └── mybatis │ │ │ └── simple │ │ │ ├── controller │ │ │ └── UserController.java │ │ │ ├── entity │ │ │ └── User.java │ │ │ ├── mapper │ │ │ ├── UserMapper.java │ │ │ └── UserMapper.xml │ │ │ └── service │ │ │ ├── UserService.java │ │ │ └── UserServiceImpl.java │ │ ├── resources │ │ ├── data.sql │ │ └── schema.sql │ │ └── webapp │ │ └── WEB-INF │ │ ├── applicationContext.xml │ │ ├── dispatcher-servlet.xml │ │ ├── jsp │ │ └── index.jsp │ │ └── web.xml └── pom.xml ├── mybatis-ext-spring-boot-autoconfigure ├── pom.xml └── src │ ├── main │ ├── java │ │ └── tech │ │ │ └── wetech │ │ │ └── mybatis │ │ │ └── spring │ │ │ └── boot │ │ │ └── autoconfigure │ │ │ ├── ConfigurationCustomizer.java │ │ │ ├── MybatisAutoConfiguration.java │ │ │ ├── MybatisLanguageDriverAutoConfiguration.java │ │ │ ├── MybatisProperties.java │ │ │ ├── SpringBootVFS.java │ │ │ └── package-info.java │ └── resources │ │ └── META-INF │ │ ├── additional-spring-configuration-metadata.json │ │ └── spring.factories │ └── test │ ├── java │ └── tech │ │ └── wetech │ │ └── mybatis │ │ ├── MybatisExtSpringBootApplication.java │ │ ├── MybatisExtSpringBootTests.java │ │ ├── entity │ │ └── User.java │ │ └── mapper │ │ ├── UserMapper.java │ │ └── UserMapper.xml │ └── resources │ ├── application.properties │ ├── data.sql │ └── schema.sql ├── mybatis-ext-spring-boot-starter └── pom.xml ├── mybatis-ext-spring ├── pom.xml └── src │ ├── main │ └── java │ │ └── tech │ │ └── wetech │ │ └── mybatis │ │ └── spring │ │ └── ExtSqlSessionFactoryBean.java │ └── test │ ├── java │ └── tech │ │ └── wetech │ │ └── mybatis │ │ └── spring │ │ ├── MybatisExtSpringTests.java │ │ ├── MybatisSpringTests.java │ │ ├── custom │ │ ├── CustomMapper.java │ │ └── SelectUserByUserNameMethod.java │ │ ├── entity │ │ └── User.java │ │ └── mapper │ │ ├── UserMapper.java │ │ └── UserMapper.xml │ └── resources │ ├── beans.xml │ ├── beans2.xml │ ├── data.sql │ ├── log4j.properties │ └── schema.sql └── pom.xml /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *target/ 2 | 3 | ### STS ### 4 | .apt_generated 5 | .classpath 6 | .factorypath 7 | .project 8 | .settings 9 | .springBeans 10 | .sts4-cache 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | /nbproject/private/ 20 | /nbbuild/ 21 | /dist/ 22 | /nbdist/ 23 | /.nb-gradle/ 24 | /build/ 25 | 26 | # These are needed if running in IDE without properties set 27 | **/ibderby 28 | derby.log 29 | /bin/ 30 | -------------------------------------------------------------------------------- /doc/时序图-Mybatis-Ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cjbi/mybatis-ext/dba3a8a1eba8cb560da40e286ed2138f2158b66f/doc/时序图-Mybatis-Ext.png -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019-2022, cjbi 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /mybatis-ext-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mybatis-ext-parent 7 | tech.wetech.mybatis 8 | 1.6.9 9 | ../mybatis-ext-parent 10 | 11 | 4.0.0 12 | 13 | mybatis-ext-core 14 | 1.6.9 15 | 16 | 17 | 3.5.9 18 | 2.2 19 | 20 | 21 | 22 | 23 | org.mybatis 24 | mybatis 25 | ${mybatis.version} 26 | 27 | 28 | javax.persistence 29 | javax.persistence-api 30 | ${javax.persistence-api.version} 31 | 32 | 33 | 34 | org.slf4j 35 | slf4j-simple 36 | 1.6.1 37 | test 38 | 39 | 40 | org.slf4j 41 | slf4j-log4j12 42 | 1.6.1 43 | test 44 | 45 | 46 | org.apache.derby 47 | derby 48 | 10.14.2.0 49 | test 50 | 51 | 52 | junit 53 | junit 54 | 4.13.1 55 | test 56 | 57 | 58 | mysql 59 | mysql-connector-java 60 | 8.0.16 61 | test 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-surefire-plugin 71 | 3.0.0-M5 72 | 73 | -Dfile.encoding=UTF-8 74 | 75 | 76 | derby.stream.error.file 77 | ${project.build.directory}/derby.log 78 | 79 | 80 | derby.system.home 81 | ${project.build.directory} 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | src/test/resources 90 | 91 | 92 | src/test/java 93 | 94 | **/*.xml 95 | **/*.sql 96 | **/*.properties 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/EntityMapperRegistry.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import org.apache.ibatis.binding.BindingException; 4 | import org.apache.ibatis.binding.MapperProxyFactory; 5 | import org.apache.ibatis.binding.MapperRegistry; 6 | import org.apache.ibatis.session.SqlSession; 7 | import tech.wetech.mybatis.builder.EntityMapperBuilder; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * 实体类Mapper注册类 14 | * 15 | * @author cjbi 16 | */ 17 | public class EntityMapperRegistry extends MapperRegistry { 18 | 19 | private final Map, MapperProxyFactory> knownMappers = new HashMap<>(); 20 | private final ExtConfiguration config; 21 | public EntityMapperRegistry(ExtConfiguration config) { 22 | super(config); 23 | this.config = config; 24 | } 25 | 26 | @Override 27 | public T getMapper(Class type, SqlSession sqlSession) { 28 | final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get(type); 29 | if (mapperProxyFactory == null) { 30 | throw new BindingException("Type " + type + " is not known to the MapperRegistry."); 31 | } 32 | try { 33 | return mapperProxyFactory.newInstance(sqlSession); 34 | } catch (Exception e) { 35 | throw new BindingException("Error getting mapper instance. Cause: " + e, e); 36 | } 37 | } 38 | 39 | @Override 40 | public boolean hasMapper(Class type) { 41 | return knownMappers.containsKey(type); 42 | } 43 | 44 | @Override 45 | public void addMapper(Class type) { 46 | if (type.isInterface()) { 47 | if (hasMapper(type)) { 48 | throw new BindingException("Type " + type + " is already known to the MapperRegistry."); 49 | } 50 | boolean loadCompleted = false; 51 | try { 52 | knownMappers.put(type, new MapperProxyFactory<>(type)); 53 | // It's important that the type is added before the parser is run 54 | // otherwise the binding may automatically be attempted by the 55 | // mapper parser. If the type is already known, it won't try. 56 | //EntityMapperBuilder added here. 57 | EntityMapperBuilder parser = new EntityMapperBuilder(config, type); 58 | parser.parse(); 59 | loadCompleted = true; 60 | } finally { 61 | if (!loadCompleted) { 62 | knownMappers.remove(type); 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/ExtConfiguration.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import org.apache.ibatis.executor.Executor; 4 | import org.apache.ibatis.mapping.Environment; 5 | import org.apache.ibatis.session.Configuration; 6 | import org.apache.ibatis.session.ExecutorType; 7 | import org.apache.ibatis.session.SqlSession; 8 | import org.apache.ibatis.transaction.Transaction; 9 | import tech.wetech.mybatis.dialect.Dialect; 10 | import tech.wetech.mybatis.dialect.DialectClient; 11 | import tech.wetech.mybatis.dialect.DialectType; 12 | import tech.wetech.mybatis.mapper.Mapper; 13 | 14 | import java.lang.reflect.InvocationTargetException; 15 | import java.sql.SQLException; 16 | 17 | /** 18 | * 增强配置类 19 | * 20 | * @author cjbi 21 | */ 22 | public class ExtConfiguration extends Configuration { 23 | 24 | protected final EntityMapperRegistry entityMapperRegistry = new EntityMapperRegistry(this); 25 | protected Dialect dialect = null; 26 | private boolean noAutoDialect; 27 | 28 | public ExtConfiguration() { 29 | super(); 30 | } 31 | 32 | public Dialect getDialect() { 33 | return dialect; 34 | } 35 | 36 | public void setDialect(Class dialect) { 37 | try { 38 | this.dialect = dialect.getDeclaredConstructor().newInstance(); 39 | } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { 40 | throw new IllegalArgumentException("Cannot set Dialect.", e); 41 | } 42 | } 43 | 44 | public ExtConfiguration(Environment environment) { 45 | this(); 46 | this.environment = environment; 47 | } 48 | 49 | @Override 50 | public void addMapper(Class type) { 51 | entityMapperRegistry.addMapper(type); 52 | } 53 | 54 | @Override 55 | public void addMappers(String packageName, Class superType) { 56 | entityMapperRegistry.addMappers(packageName, superType); 57 | } 58 | 59 | @Override 60 | public void addMappers(String packageName) { 61 | entityMapperRegistry.addMappers(packageName); 62 | } 63 | 64 | @Override 65 | public T getMapper(Class type, SqlSession sqlSession) { 66 | return entityMapperRegistry.getMapper(type, sqlSession); 67 | } 68 | 69 | @Override 70 | public boolean hasMapper(Class type) { 71 | return type == Mapper.class || entityMapperRegistry.hasMapper(type); 72 | } 73 | 74 | @Override 75 | public Executor newExecutor(Transaction transaction, ExecutorType executorType) { 76 | Executor executor = super.newExecutor(transaction, executorType); 77 | if (dialect == null) { 78 | dialect = getAutoDialect(transaction); 79 | } 80 | return dialect == null ? executor : new PagingExecutor(executor, dialect); 81 | } 82 | 83 | 84 | private Dialect getAutoDialect(Transaction transaction) { 85 | Dialect dialect = null; 86 | if (!noAutoDialect) { 87 | try { 88 | String url = transaction.getConnection().getMetaData().getURL(); 89 | for (DialectType dialectType : DialectType.values()) { 90 | if (url.toUpperCase().indexOf(String.format(":%s:", dialectType)) != -1) { 91 | dialect = DialectClient.getDialect(dialectType); 92 | } 93 | } 94 | } catch (SQLException | UnsupportedOperationException e) { 95 | noAutoDialect = true; 96 | } 97 | } 98 | return dialect; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/ExtSqlSessionFactoryBuilder.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import org.apache.ibatis.exceptions.ExceptionFactory; 4 | import org.apache.ibatis.executor.ErrorContext; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.apache.ibatis.session.SqlSessionFactoryBuilder; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.Reader; 11 | import java.util.Properties; 12 | 13 | /** 14 | * 增强SqlSessionFactoryBuilder 15 | * 16 | * @author cjbi 17 | */ 18 | public class ExtSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder { 19 | 20 | @Override 21 | public SqlSessionFactory build(Reader reader, String environment, Properties properties) { 22 | try { 23 | ExtXMLConfigBuilder parser = new ExtXMLConfigBuilder(reader, environment, properties); 24 | return build(parser.parse()); 25 | } catch (Exception e) { 26 | throw ExceptionFactory.wrapException("Error building SqlSession.", e); 27 | } finally { 28 | ErrorContext.instance().reset(); 29 | try { 30 | reader.close(); 31 | } catch (IOException e) { 32 | // Intentionally ignore. Prefer previous error. 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { 39 | try { 40 | ExtXMLConfigBuilder parser = new ExtXMLConfigBuilder(inputStream, environment, properties); 41 | return build(parser.parse()); 42 | } catch (Exception e) { 43 | throw ExceptionFactory.wrapException("Error building SqlSession.", e); 44 | } finally { 45 | ErrorContext.instance().reset(); 46 | try { 47 | inputStream.close(); 48 | } catch (IOException e) { 49 | // Intentionally ignore. Prefer previous error. 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/ParametersFinder.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import java.lang.reflect.Array; 4 | import java.util.Collection; 5 | import java.util.Map; 6 | 7 | /** 8 | * 参数查找 9 | * 10 | * @author cjbi 11 | */ 12 | public class ParametersFinder { 13 | 14 | private static ParametersFinder parametersFinder = null; 15 | 16 | public static ParametersFinder getInstance() { 17 | if (parametersFinder != null) { 18 | return parametersFinder; 19 | } 20 | return new ParametersFinder(); 21 | } 22 | 23 | /** 24 | * 根据类型查找参数 25 | * 26 | * @param parameterObject MyBatis入参 27 | * @param clazz 要查找的类类型 28 | * @param 要查找的类型返回 29 | * @return 实体类型参数 30 | */ 31 | public T findParameter(Object parameterObject, Class clazz) { 32 | return findParameterFromObject(parameterObject, clazz); 33 | } 34 | 35 | public T findParameterFromObject(Object parameterObject, Class clazz) { 36 | if (parameterObject == null) { 37 | return null; 38 | } 39 | Class pClass = parameterObject.getClass(); 40 | if (clazz == pClass || clazz.isAssignableFrom(pClass)) { 41 | return (T) parameterObject; 42 | } else if (parameterObject instanceof Map) { 43 | return findParameterFromMap((Map) parameterObject, clazz); 44 | } else if (parameterObject instanceof Collection) { 45 | return findParameterFromCollection((Collection) parameterObject, clazz); 46 | } else if (pClass.isArray()) { 47 | return findParameterFromArray(parameterObject, clazz); 48 | } 49 | return null; 50 | } 51 | 52 | public T findParameterFromMap(Map map, Class clazz) { 53 | for (Object value : map.values()) { 54 | T parameterFromObject = findParameterFromObject(value, clazz); 55 | if (parameterFromObject != null) { 56 | return parameterFromObject; 57 | } 58 | } 59 | return null; 60 | } 61 | 62 | public T findParameterFromCollection(Collection collection, Class clazz) { 63 | for (Object value : collection) { 64 | T parameterFromObject = findParameterFromObject(value, clazz); 65 | if (parameterFromObject != null) { 66 | return parameterFromObject; 67 | } 68 | } 69 | return null; 70 | } 71 | 72 | private T findParameterFromArray(Object array, Class clazz) { 73 | for (int i = 0; i < Array.getLength(array); i++) { 74 | T parameterFromObject = findParameterFromObject(Array.get(array, i), clazz); 75 | if (parameterFromObject != null) { 76 | return parameterFromObject; 77 | } 78 | } 79 | return null; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/DeleteEntityProvider.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import org.apache.ibatis.mapping.SqlCommandType; 4 | import tech.wetech.mybatis.builder.EntityMapping; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * 指定提供用于删除记录的SQL的实体类映射方法 10 | *
11 | *
12 | * 怎样使用: 13 | *
14 |  * public interface MyMapper<T> {
15 |  *     @SelectEntityProvider(type = MyEntitySqlBuilder.class, method = "deleteById")
16 |  *     int deleteById(Integer id);
17 |  *
18 |  *     class MyEntitySqlBuilder {
19 |  *       public String deleteById(EntityMapping entityMapping) {
20 |  *           return ""DELETE FROM "+entityMapping.getTableName()+ " WHERE id = #{id}"";
21 |  *      }
22 |  * }
23 |  * 
24 | * 25 | * @author cjbi 26 | * @see tech.wetech.mybatis.mapper.BaseEntitySqlBuilder#deleteByPrimaryKey(EntityMapping) 27 | * @see tech.wetech.mybatis.mapper.BaseEntitySqlBuilder#deleteByExample(EntityMapping) 28 | */ 29 | @Documented 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.METHOD) 32 | @EntityProviderSqlCommandType(SqlCommandType.DELETE) 33 | public @interface DeleteEntityProvider { 34 | /** 35 | * 提供提供SQL的实体类映射类 36 | * 37 | * @return 类类型 38 | */ 39 | Class type(); 40 | 41 | /** 42 | * 指定提供SQL的实体类映射方法 43 | * 44 | * @return 方法名称 45 | */ 46 | String method(); 47 | } 48 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/EntityProviderSqlCommandType.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import org.apache.ibatis.mapping.SqlCommandType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 指定提供的实体类注解SQL指令类型 9 | * 10 | * @author cjbi 11 | * @see SelectEntityProvider 12 | * @see DeleteEntityProvider 13 | * @see InsertEntityProvider 14 | * @see UpdateEntityProvider 15 | */ 16 | @Documented 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.ANNOTATION_TYPE) 19 | public @interface EntityProviderSqlCommandType { 20 | /** 21 | * 指定SQL指令类型 22 | * 23 | * @return SQL指令类型 24 | */ 25 | SqlCommandType value(); 26 | } 27 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/InsertEntityProvider.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import org.apache.ibatis.mapping.SqlCommandType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 指定提供用于删除记录的SQL的实体类映射方法 9 | *
10 | *
11 | * 怎样使用: 12 | *
13 |  * public interface MyMapper<T> {
14 |  *     @InsertEntityProvider(type = MyEntitySqlBuilder.class, method = "insert")
15 |  *     int insert(Integer id);
16 |  *
17 |  *     class MyEntitySqlBuilder {
18 |  *       public String insert(EntityMapping entityMapping) {
19 |  *           StringBuilder builder = new StringBuilder("<script>");
20 |  *           StringBuilder columnsBuilder = new StringBuilder("<trim prefix='(' suffix=')' suffixOverrides=','>");
21 |  *           StringBuilder valuesBuilder = new StringBuilder("<trim prefix='(' suffix=')' suffixOverrides=','>");
22 |  *           for (EntityMapping.ColumnProperty columnProperty : entityMapping.getColumnProperties()) {
23 |  *             columnsBuilder.append(columnProperty.getColumnName()).append(" , ");
24 |  *             valuesBuilder.append("#{").append(columnProperty.getPropertyName()).append("}").append(" , ");
25 |  *           }
26 |  *           columnsBuilder.append("</trim>");
27 |  *           valuesBuilder.append("</trim>");
28 |  *           builder.append(String.format("INSERT INTO %s %s VALUES%s", entityMapping.getTableName(), columnsBuilder, valuesBuilder));
29 |  *           builder.append("</script>");
30 |  *           return builder.toString();
31 |  *     }
32 |  * }
33 |  * 
34 | * 35 | * @author cjbi 36 | */ 37 | @Documented 38 | @Retention(RetentionPolicy.RUNTIME) 39 | @Target(ElementType.METHOD) 40 | @EntityProviderSqlCommandType(SqlCommandType.INSERT) 41 | public @interface InsertEntityProvider { 42 | /** 43 | * 提供提供SQL的实体类映射类 44 | * 45 | * @return 类类型 46 | */ 47 | Class type(); 48 | 49 | /** 50 | * 指定提供SQL的实体类映射方法 51 | * 52 | * @return 方法名称 53 | */ 54 | String method(); 55 | } 56 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/LogicDelete.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.Target; 5 | 6 | import static java.lang.annotation.ElementType.FIELD; 7 | import static java.lang.annotation.ElementType.METHOD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * 该注解标识字段逻辑删除 12 | * 默认"0"为正常状态,"1"为删除状态 13 | * 14 | * @author cjbi 15 | * @deprecated 请使用@Where注解实现 16 | */ 17 | @Deprecated 18 | @Target({METHOD, FIELD}) 19 | @Retention(RUNTIME) 20 | public @interface LogicDelete { 21 | /** 22 | * 设置正常状态的值 23 | * 24 | * @return 正常状态的值 25 | */ 26 | String normalValue() default "0"; 27 | 28 | /** 29 | * 设置删除状态的值 30 | * 31 | * @return 删除状态的值 32 | */ 33 | String deletedValue() default "1"; 34 | } 35 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/SelectEntityKey.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import org.apache.ibatis.mapping.StatementType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 指定实体类字段返回查询的主键 9 | * 10 | * @author cjbi 11 | * @see org.apache.ibatis.annotations.SelectKey 12 | */ 13 | @Documented 14 | @Target({ElementType.METHOD, ElementType.FIELD}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface SelectEntityKey { 17 | /** 18 | * Returns an SQL for retrieving a key value. 19 | * 20 | * @return an SQL for retrieving a key value 21 | */ 22 | String[] statement(); 23 | 24 | /** 25 | * Returns whether retrieves a key value before executing insert/update statement. 26 | * 27 | * @return {@code true} if execute before; {@code false} if otherwise 28 | */ 29 | boolean before(); 30 | 31 | /** 32 | * Returns the statement type to use. 33 | * 34 | * @return the statement type 35 | */ 36 | StatementType statementType() default StatementType.PREPARED; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/SelectEntityProvider.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import org.apache.ibatis.mapping.SqlCommandType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 指定提供用于删除记录的SQL的实体类映射方法 9 | *
10 | *
11 | * 怎样使用: 12 | *
13 |  * public interface MyMapper<T> {
14 |  *     @SelectEntityProvider(type = MyEntitySqlBuilder.class, method = "selectById")
15 |  *     T selectById(Integer id);
16 |  *
17 |  *     class MyEntitySqlBuilder {
18 |  *       public String selectById(EntityMapping entityMapping) {
19 |  *           return "SELECT * FROM "+entityMapping.getTableName()+ " WHERE id = #{id}";
20 |  *      }
21 |  * }
22 |  * 
23 | * 24 | * @author cjbi 25 | */ 26 | @Documented 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.METHOD) 29 | @EntityProviderSqlCommandType(SqlCommandType.SELECT) 30 | public @interface SelectEntityProvider { 31 | /** 32 | * 提供提供SQL的实体类映射类 33 | * 34 | * @return 类类型 35 | */ 36 | Class type(); 37 | 38 | /** 39 | * 指定提供SQL的实体类映射方法 40 | * 41 | * @return 方法名称 42 | */ 43 | String method(); 44 | } 45 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/UpdateEntityProvider.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import org.apache.ibatis.mapping.SqlCommandType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 指定提供用于删除记录的SQL的实体类映射方法 9 | *
10 | *
11 | * 怎样使用: 12 | *
13 |  * public interface MyMapper<T> {
14 |  *     @SelectEntityProvider(type = MyEntitySqlBuilder.class, method = "updateByPrimaryKey")
15 |  *     T updateByPrimaryKey(Integer id);
16 |  *     class MyEntitySqlBuilder {
17 |  *       public String updateByPrimaryKey(EntityMapping entityMapping) {
18 |  *         EntityMapping.ColumnProperty logicDeleteProperty = EntityMappingUtil.findAnnotationColumnPropertyOne(entityMapping, LogicDelete.class);
19 |  *         EntityMapping.ColumnProperty versionProperty = EntityMappingUtil.findAnnotationColumnPropertyOne(entityMapping, Version.class);
20 |  *         StringBuilder builder = new StringBuilder("<script>");
21 |  *         StringBuilder setBuilder = new StringBuilder("<set>");
22 |  *         for (EntityMapping.ColumnProperty columnProperty : entityMapping.getColumnProperties()) {
23 |  *             if (versionProperty != null && versionProperty.getPropertyName().equals(columnProperty.getPropertyName())) {
24 |  *                 setBuilder.append(String.format("%s = %s + 1,", columnProperty.getColumnName(), columnProperty.getColumnName()));
25 |  *                 continue;
26 |  *             }
27 |  *             setBuilder.append(String.format("%s = #{%s},", columnProperty.getColumnName(), columnProperty.getPropertyName()));
28 |  *         }
29 |  *         setBuilder.append("</set>");
30 |  *         builder.append(String.format("UPDATE %s %s WHERE %s = #{%s}", entityMapping.getTableName(), setBuilder, entityMapping.getKeyColumn(), entityMapping.getKeyProperty()));
31 |  *         if (logicDeleteProperty != null) {
32 |  *             builder.append(String.format(" and %s = %s", logicDeleteProperty.getColumnName(), logicDeleteProperty.getAnnotation(LogicDelete.class).normalValue()));
33 |  *         }
34 |  *         if (versionProperty != null) {
35 |  *             builder.append(String.format("<if test='%s != null'> and %s = #{%s}</if>", versionProperty.getPropertyName(), versionProperty.getColumnName(), versionProperty.getPropertyName()));
36 |  *         }
37 |  *         builder.append("</script>");
38 |  *         return builder.toString();
39 |  *     }
40 |  * }
41 |  * 
42 | * 43 | * @author cjbi 44 | */ 45 | @Documented 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.METHOD) 48 | @EntityProviderSqlCommandType(SqlCommandType.UPDATE) 49 | public @interface UpdateEntityProvider { 50 | /** 51 | * 提供提供SQL的实体类映射类 52 | * 53 | * @return 类类型 54 | */ 55 | Class type(); 56 | 57 | /** 58 | * 指定提供SQL的实体类映射方法 59 | * 60 | * @return 方法名称 61 | */ 62 | String method(); 63 | } 64 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/annotation/Where.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 给实体类查询增加where条件 10 | * 常见用法如用来做来软删除 11 | *

12 | * 示例:@Where(clause="del_flag = 0 ") 13 | * 14 | * @author cjbi 15 | */ 16 | @Target({ElementType.TYPE}) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface Where { 19 | /** 20 | * The where-clause predicate. 21 | */ 22 | String clause(); 23 | } 24 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/builder/EntityMapperAnnotationResolver.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.builder; 2 | 3 | import org.apache.ibatis.builder.BuilderException; 4 | import org.apache.ibatis.logging.Log; 5 | import org.apache.ibatis.logging.LogFactory; 6 | import org.apache.ibatis.mapping.SqlCommandType; 7 | import tech.wetech.mybatis.ExtConfiguration; 8 | import tech.wetech.mybatis.annotation.*; 9 | 10 | import java.lang.annotation.Annotation; 11 | import java.lang.reflect.InvocationTargetException; 12 | import java.lang.reflect.Method; 13 | import java.lang.reflect.Parameter; 14 | import java.util.*; 15 | import java.util.stream.Collectors; 16 | import java.util.stream.Stream; 17 | 18 | /** 19 | * 实体类映射注解解析器 20 | * 21 | * @author cjbi 22 | * @see SelectEntityProvider 23 | * @see InsertEntityProvider 24 | * @see UpdateEntityProvider 25 | * @see DeleteEntityProvider 26 | */ 27 | public class EntityMapperAnnotationResolver { 28 | 29 | private final Method method; 30 | private final ExtConfiguration configuration; 31 | private final EntityMapping entityMapping; 32 | private boolean isEntityMethodProvider; 33 | private SqlCommandType sqlCommandType; 34 | private String script; 35 | 36 | private final Log log = LogFactory.getLog(EntityMapperAnnotationResolver.class); 37 | private static final Set> SQL_ENTITY_PROVIDER_ANNOTATION_TYPES = new HashSet<>(); 38 | private final Map injectArgsMap = new HashMap<>(); 39 | 40 | static { 41 | SQL_ENTITY_PROVIDER_ANNOTATION_TYPES.add(SelectEntityProvider.class); 42 | SQL_ENTITY_PROVIDER_ANNOTATION_TYPES.add(InsertEntityProvider.class); 43 | SQL_ENTITY_PROVIDER_ANNOTATION_TYPES.add(UpdateEntityProvider.class); 44 | SQL_ENTITY_PROVIDER_ANNOTATION_TYPES.add(DeleteEntityProvider.class); 45 | } 46 | 47 | public EntityMapperAnnotationResolver(Method method, ExtConfiguration configuration, EntityMapping entityMapping) { 48 | this.method = method; 49 | this.configuration = configuration; 50 | this.entityMapping = entityMapping; 51 | injectArgsMap.put(configuration.getClass(), configuration); 52 | injectArgsMap.put(entityMapping.getClass(), entityMapping); 53 | 54 | Class sqlEntityProviderAnnotationType = getSqlEntityProviderAnnotationType(method); 55 | if (sqlEntityProviderAnnotationType != null) { 56 | Annotation annotation = method.getAnnotation(sqlEntityProviderAnnotationType); 57 | try { 58 | Class providerMethodClass = (Class) sqlEntityProviderAnnotationType.getMethod("type").invoke(annotation); 59 | String providerMethodName = (String) sqlEntityProviderAnnotationType.getMethod("method").invoke(annotation); 60 | sqlCommandType = sqlEntityProviderAnnotationType.getAnnotation(EntityProviderSqlCommandType.class).value(); 61 | isEntityMethodProvider = true; 62 | List providerMethods = Stream.of(providerMethodClass.getMethods()).filter(m -> providerMethodName.equals(m.getName())).collect(Collectors.toList()); 63 | if (providerMethods.size() == 0) { 64 | String msg = String.format("Not found method %s in class %s", providerMethodName, providerMethodClass); 65 | log.error(msg); 66 | throw new BuilderException(msg); 67 | } 68 | if (providerMethods.size() > 1) { 69 | String msg = String.format("Found multi method %s in class %s", providerMethodName, providerMethodClass); 70 | log.error(msg); 71 | throw new BuilderException(msg); 72 | } 73 | Method providerMethod = providerMethods.get(0); 74 | Parameter[] parameters = providerMethod.getParameters(); 75 | Object[] args = new Object[parameters.length]; 76 | //inject 77 | for (int i = 0; i < parameters.length; i++) { 78 | args[i] = injectArgsMap.get(parameters[i].getType()); 79 | } 80 | script = providerMethod.invoke(providerMethodClass.newInstance(), args).toString(); 81 | isEntityMethodProvider = true; 82 | } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException e) { 83 | throw new BuilderException(e); 84 | } 85 | } else { 86 | isEntityMethodProvider = false; 87 | } 88 | 89 | } 90 | 91 | public boolean isEntityMethodProvider() { 92 | return isEntityMethodProvider; 93 | } 94 | 95 | public SqlCommandType getSqlCommandType() { 96 | return sqlCommandType; 97 | } 98 | 99 | public String getScript() { 100 | return script; 101 | } 102 | 103 | public Method getMethod() { 104 | return method; 105 | } 106 | 107 | public ExtConfiguration getConfiguration() { 108 | return configuration; 109 | } 110 | 111 | public EntityMapping getEntityMapping() { 112 | return entityMapping; 113 | } 114 | 115 | private Class chooseAnnotationType(Method method, Set> types) { 116 | for (Class type : types) { 117 | Annotation annotation = method.getAnnotation(type); 118 | if (annotation != null) { 119 | return type; 120 | } 121 | } 122 | return null; 123 | } 124 | 125 | private Class getSqlEntityProviderAnnotationType(Method method) { 126 | return chooseAnnotationType(method, SQL_ENTITY_PROVIDER_ANNOTATION_TYPES); 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/builder/EntityMapping.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.builder; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | /** 8 | * 实体类映射 9 | * 10 | * @author cjbi 11 | */ 12 | public class EntityMapping { 13 | /** 14 | * 实体类类型 15 | */ 16 | private Class entityClass; 17 | /** 18 | * 表名称 19 | */ 20 | private String tableName; 21 | /** 22 | * 字段属性列表 23 | */ 24 | private List columnProperties; 25 | /** 26 | * 主键对应实体属性 27 | */ 28 | private String keyProperty; 29 | /** 30 | * 主键字段 31 | */ 32 | private String keyColumn; 33 | /** 34 | * 主键返回类型 35 | */ 36 | private Class keyResultType; 37 | /** 38 | * 字段属性映射Map 39 | */ 40 | private Map columnPropertyMap; 41 | /** 42 | * 注解映射Map 43 | */ 44 | private Map, ? extends Annotation> annotationMap; 45 | /** 46 | * 查询条件 47 | */ 48 | private String whereClause; 49 | 50 | public Class getEntityClass() { 51 | return entityClass; 52 | } 53 | 54 | public void setEntityClass(Class entityClass) { 55 | this.entityClass = entityClass; 56 | } 57 | 58 | public String getTableName() { 59 | return tableName; 60 | } 61 | 62 | public void setTableName(String tableName) { 63 | this.tableName = tableName; 64 | } 65 | 66 | public List getColumnProperties() { 67 | return columnProperties; 68 | } 69 | 70 | public void setColumnProperties(List columnProperties) { 71 | this.columnProperties = columnProperties; 72 | } 73 | 74 | public String getKeyProperty() { 75 | return keyProperty; 76 | } 77 | 78 | public void setKeyProperty(String keyProperty) { 79 | this.keyProperty = keyProperty; 80 | } 81 | 82 | public String getKeyColumn() { 83 | return keyColumn; 84 | } 85 | 86 | public void setKeyColumn(String keyColumn) { 87 | this.keyColumn = keyColumn; 88 | } 89 | 90 | public Map getColumnPropertyMap() { 91 | return columnPropertyMap; 92 | } 93 | 94 | public void setColumnPropertyMap(Map columnPropertyMap) { 95 | this.columnPropertyMap = columnPropertyMap; 96 | } 97 | 98 | public ColumnProperty getColumnProperty(String property) { 99 | return this.columnPropertyMap.get(property); 100 | } 101 | 102 | public Class getKeyResultType() { 103 | return keyResultType; 104 | } 105 | 106 | public void setKeyResultType(Class keyResultType) { 107 | this.keyResultType = keyResultType; 108 | } 109 | 110 | public Map, ? extends Annotation> getAnnotationMap() { 111 | return annotationMap; 112 | } 113 | 114 | public void setAnnotationMap(Map, ? extends Annotation> annotationMap) { 115 | this.annotationMap = annotationMap; 116 | } 117 | 118 | public T getAnnotation(Class clazz) { 119 | return (T) this.annotationMap.get(clazz); 120 | } 121 | 122 | public String getWhereClause() { 123 | return whereClause; 124 | } 125 | 126 | public void setWhereClause(String whereClause) { 127 | this.whereClause = whereClause; 128 | } 129 | 130 | /** 131 | * 字段属性 132 | */ 133 | public static class ColumnProperty { 134 | /** 135 | * 字段名称 136 | */ 137 | private String columnName; 138 | /** 139 | * 属性名称 140 | */ 141 | private String propertyName; 142 | /** 143 | * 主键字段 144 | */ 145 | private boolean identity; 146 | /** 147 | * 对应Java类型 148 | */ 149 | private Class javaType; 150 | /** 151 | * 注解映射Map 152 | */ 153 | private Map, ? extends Annotation> annotationMap; 154 | 155 | public String getColumnName() { 156 | return columnName; 157 | } 158 | 159 | public void setColumnName(String columnName) { 160 | this.columnName = columnName; 161 | } 162 | 163 | public String getPropertyName() { 164 | return propertyName; 165 | } 166 | 167 | public void setPropertyName(String propertyName) { 168 | this.propertyName = propertyName; 169 | } 170 | 171 | public boolean isIdentity() { 172 | return identity; 173 | } 174 | 175 | public void setIdentity(boolean identity) { 176 | this.identity = identity; 177 | } 178 | 179 | public Class getJavaType() { 180 | return javaType; 181 | } 182 | 183 | public void setJavaType(Class javaType) { 184 | this.javaType = javaType; 185 | } 186 | 187 | public Map, ? extends Annotation> getAnnotationMap() { 188 | return annotationMap; 189 | } 190 | 191 | public void setAnnotationMap(Map, ? extends Annotation> annotationMap) { 192 | this.annotationMap = annotationMap; 193 | } 194 | 195 | public T getAnnotation(Class clazz) { 196 | return (T) this.annotationMap.get(clazz); 197 | } 198 | } 199 | 200 | } 201 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/Dialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect; 2 | 3 | /** 4 | * 方言接口 5 | * 6 | * @author cjbi 7 | */ 8 | public interface Dialect { 9 | 10 | /** 11 | * 将sql转换为分页sql 12 | * 13 | * @param sql sql语句 14 | * @param offset 偏移量 15 | * @param limit 分页数 16 | * @return 分页的sql 17 | */ 18 | String getLimitString(String sql, int offset, int limit); 19 | 20 | /** 21 | * 将sql转换为总记录数sql 22 | * 23 | * @param sql sql语句 24 | * @return 总记录数的sql 25 | */ 26 | default String getCountString(String sql) { 27 | return "SELECT COUNT(*) FROM (" + sql + ") tmp_count"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/DialectClient.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect; 2 | 3 | import tech.wetech.mybatis.dialect.db.*; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * 方言转换查找 10 | * 11 | * @author cjbi 12 | */ 13 | public class DialectClient { 14 | 15 | private static final Map DBMS_DIALECT = new HashMap<>(); 16 | 17 | public static Dialect getDialect(DialectType dialectType) { 18 | if (DBMS_DIALECT.containsKey(dialectType)) { 19 | return DBMS_DIALECT.get(dialectType); 20 | } 21 | Dialect dialect = createDialect(dialectType); 22 | DBMS_DIALECT.put(dialectType, dialect); 23 | return dialect; 24 | 25 | } 26 | 27 | private static Dialect createDialect(DialectType dialectType) { 28 | switch (dialectType) { 29 | case MYSQL: 30 | return new MySQLDialect(); 31 | case ORACLE: 32 | return new OracleDialect(); 33 | case DB2: 34 | return new DB2Dialect(); 35 | case POSTGRE: 36 | return new PostgreSQLDialect(); 37 | case H2: 38 | return new H2Dialect(); 39 | case HSQL: 40 | return new HSQLDialect(); 41 | case SQLSERVER: 42 | return new SQLServerDialect(); 43 | case SQLSERVER2012: 44 | return new SqlServer2012Dialect(); 45 | case DERBY: 46 | return new DerbyDialect(); 47 | default: 48 | throw new UnsupportedOperationException("This database is not supported"); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/DialectType.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect; 2 | 3 | /** 4 | * 方言种类 5 | * 6 | * @author cjbi 7 | */ 8 | public enum DialectType { 9 | MYSQL, 10 | ORACLE, 11 | DB2, 12 | H2, 13 | HSQL, 14 | POSTGRE, 15 | SQLSERVER, 16 | SQLSERVER2012, 17 | DERBY 18 | } 19 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/DB2Dialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | public class DB2Dialect implements Dialect { 6 | 7 | private static String getRowNumber(String sql) { 8 | StringBuilder rownumber = new StringBuilder(50) 9 | .append("rownumber() over("); 10 | 11 | int orderByIndex = sql.toLowerCase().indexOf("order by"); 12 | 13 | if (orderByIndex > 0 && !hasDistinct(sql)) { 14 | rownumber.append(sql.substring(orderByIndex)); 15 | } 16 | 17 | rownumber.append(") as rownumber_,"); 18 | 19 | return rownumber.toString(); 20 | } 21 | 22 | private static boolean hasDistinct(String sql) { 23 | return sql.toLowerCase().contains("select distinct"); 24 | } 25 | 26 | 27 | @Override 28 | public String getLimitString(String sql, int offset, int limit) { 29 | return getLimitString(sql, offset, Integer.toString(offset), Integer.toString(limit)); 30 | } 31 | 32 | /** 33 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 34 | *

35 |      * 如mysql
36 |      * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
37 |      * select * from user limit :offset,:limit
38 |      * 
39 | * 40 | * @param sql 实际SQL语句 41 | * @param offset 分页开始纪录条数 42 | * @param offsetPlaceholder 分页开始纪录条数-占位符号 43 | * @param limitPlaceholder 分页纪录条数占位符号 44 | * @return 包含占位符的分页sql 45 | */ 46 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) { 47 | int startOfSelect = sql.toLowerCase().indexOf("select"); 48 | 49 | StringBuilder pagingSelect = new StringBuilder(sql.length() + 100) 50 | .append(sql.substring(0, startOfSelect)) //add the comment 51 | .append("select * from ( select ") //nest the main query in an outer select 52 | .append(getRowNumber(sql)); //add the rownnumber bit into the outer query select list 53 | 54 | if (hasDistinct(sql)) { 55 | pagingSelect.append(" row_.* from ( ") //add another (inner) nested select 56 | .append(sql.substring(startOfSelect)) //add the main query 57 | .append(" ) as row_"); //close off the inner nested select 58 | } else { 59 | pagingSelect.append(sql.substring(startOfSelect + 6)); //add the main query 60 | } 61 | 62 | pagingSelect.append(" ) as temp_ where rownumber_ "); 63 | 64 | //add the restriction to the outer select 65 | if (offset > 0) { 66 | // int end = offset + limit; 67 | String endString = offsetPlaceholder + "+" + limitPlaceholder; 68 | pagingSelect.append("between ").append(offsetPlaceholder) 69 | .append("+1 and ").append(endString); 70 | } else { 71 | pagingSelect.append("<= ").append(limitPlaceholder); 72 | } 73 | 74 | return pagingSelect.toString(); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/DerbyDialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | public class DerbyDialect implements Dialect { 6 | @Override 7 | public String getLimitString(String sql, int offset, int limit) { 8 | return String.format(sql + " OFFSET %s ROWS FETCH NEXT %s ROWS ONLY ", offset, limit); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/H2Dialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | public class H2Dialect implements Dialect { 6 | 7 | /** 8 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 9 | *
10 |      * 如mysql
11 |      * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
12 |      * select * from user limit :offset,:limit
13 |      * 
14 | * 15 | * @param sql 实际SQL语句 16 | * @param offset 分页开始纪录条数 17 | * @param offsetPlaceholder 分页开始纪录条数-占位符号 18 | * @param limit 分页每页显示纪录条数 19 | * @param limitPlaceholder 分页纪录条数占位符号 20 | * @return 包含占位符的分页sql 21 | */ 22 | private String getLimitString(String sql, int offset, String offsetPlaceholder, int limit, String limitPlaceholder) { 23 | return sql + ((offset > 0) ? " limit " + limitPlaceholder + " offset " 24 | + offsetPlaceholder : " limit " + limitPlaceholder); 25 | } 26 | 27 | @Override 28 | public String getLimitString(String sql, int offset, int limit) { 29 | return getLimitString(sql, offset, Integer.toString(offset), limit, Integer.toString(limit)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/HSQLDialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | public class HSQLDialect implements Dialect { 6 | @Override 7 | public String getLimitString(String sql, int offset, int limit) { 8 | return getLimitString(sql, offset, Integer.toString(offset), 9 | Integer.toString(limit)); 10 | } 11 | 12 | /** 13 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 14 | *
15 |      * 如mysql
16 |      * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
17 |      * select * from user limit :offset,:limit
18 |      *
19 |      * select limit :offset,:limit * from user
20 |      * 
21 | * 22 | * @param sql 实际SQL语句 23 | * @param offset 分页开始纪录条数 24 | * @param offsetPlaceholder 分页开始纪录条数-占位符号 25 | * @param limitPlaceholder 分页纪录条数占位符号 26 | * @return 包含占位符的分页sql 27 | */ 28 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) { 29 | boolean hasOffset = offset > 0; 30 | return 31 | new StringBuffer(sql.length() + 10) 32 | .append(sql) 33 | .insert(sql.toLowerCase().indexOf("select") + 6, hasOffset ? " limit " + offsetPlaceholder + " " + limitPlaceholder : " top " + limitPlaceholder) 34 | .toString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/MySQLDialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | /** 6 | * @author cjbi 7 | */ 8 | public class MySQLDialect implements Dialect { 9 | 10 | @Override 11 | public String getLimitString(String sql, int offset, int limit) { 12 | return getLimitString(sql, offset, Integer.toString(offset), 13 | Integer.toString(limit)); 14 | } 15 | /** 16 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 17 | *
18 |      * 如mysql
19 |      * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
20 |      * select * from user limit :offset,:limit
21 |      * 
22 | * 23 | * @param sql 实际SQL语句 24 | * @param offset 分页开始纪录条数 25 | * @param offsetPlaceholder 分页开始纪录条数-占位符号 26 | * @param limitPlaceholder 分页纪录条数占位符号 27 | * @return 包含占位符的分页sql 28 | */ 29 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) { 30 | StringBuilder stringBuilder = new StringBuilder(sql); 31 | stringBuilder.append(" limit "); 32 | if (offset > 0) { 33 | stringBuilder.append(offsetPlaceholder).append(",").append(limitPlaceholder); 34 | } else { 35 | stringBuilder.append(limitPlaceholder); 36 | } 37 | return stringBuilder.toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/OracleDialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | /** 6 | * @author cjbi 7 | */ 8 | public class OracleDialect implements Dialect { 9 | @Override 10 | public String getLimitString(String sql, int offset, int limit) { 11 | return getLimitString(sql, offset, Integer.toString(offset), Integer.toString(limit)); 12 | } 13 | 14 | /** 15 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 16 | *
17 |      * 如mysql
18 |      * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
19 |      * select * from user limit :offset,:limit
20 |      * 
21 | * 22 | * @param sql 实际SQL语句 23 | * @param offset 分页开始纪录条数 24 | * @param offsetPlaceholder 分页开始纪录条数-占位符号 25 | * @param limitPlaceholder 分页纪录条数占位符号 26 | * @return 包含占位符的分页sql 27 | */ 28 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) { 29 | sql = sql.trim(); 30 | boolean isForUpdate = false; 31 | if (sql.toLowerCase().endsWith(" for update")) { 32 | sql = sql.substring(0, sql.length() - 11); 33 | isForUpdate = true; 34 | } 35 | StringBuilder pagingSelect = new StringBuilder(sql.length() + 100); 36 | if (offset >= 0) { 37 | pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); 38 | } else { 39 | pagingSelect.append("select * from ( "); 40 | } 41 | pagingSelect.append(sql); 42 | if (offset >= 0) { 43 | String endString = offsetPlaceholder + "+" + limitPlaceholder; 44 | pagingSelect.append(" ) row_ ) where rownum_ <= ") 45 | .append(endString).append(" and rownum_ > ").append(offsetPlaceholder); 46 | } else { 47 | pagingSelect.append(" ) where rownum <= ").append(limitPlaceholder); 48 | } 49 | 50 | if (isForUpdate) { 51 | pagingSelect.append(" for update"); 52 | } 53 | 54 | return pagingSelect.toString(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/PostgreSQLDialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | /** 6 | * @author cjbi 7 | */ 8 | public class PostgreSQLDialect implements Dialect { 9 | @Override 10 | public String getLimitString(String sql, int offset, int limit) { 11 | return getLimitString(sql, offset, Integer.toString(offset), 12 | Integer.toString(limit)); 13 | } 14 | 15 | /** 16 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 17 | *
18 |      * 如mysql
19 |      * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
20 |      * select * from user limit :offset,:limit
21 |      * 
22 | * 23 | * @param sql 实际SQL语句 24 | * @param offset 分页开始纪录条数 25 | * @param offsetPlaceholder 分页开始纪录条数-占位符号 26 | * @param limitPlaceholder 分页纪录条数占位符号 27 | * @return 包含占位符的分页sql 28 | */ 29 | public String getLimitString(String sql, int offset, 30 | String offsetPlaceholder, String limitPlaceholder) { 31 | StringBuilder pageSql = new StringBuilder().append(sql); 32 | pageSql = offset <= 0 33 | ? pageSql.append(" limit ").append(limitPlaceholder) : 34 | pageSql.append(" limit ").append(limitPlaceholder).append(" offset ").append(offsetPlaceholder); 35 | return pageSql.toString(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/SQLServerDialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | /** 6 | * MSSQLServer 数据库实现分页方言 7 | * 8 | */ 9 | public class SQLServerDialect implements Dialect { 10 | 11 | static int getAfterSelectInsertPoint(String sql) { 12 | int selectIndex = sql.toLowerCase().indexOf("select"); 13 | final int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct"); 14 | return selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6); 15 | } 16 | 17 | @Override 18 | public String getLimitString(String sql, int offset, int limit) { 19 | return getLimit(sql, offset, limit); 20 | } 21 | 22 | /** 23 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换. 24 | *
25 | 	 * 如mysql
26 | 	 * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
27 | 	 * select * from user limit :offset,:limit
28 | 	 * 
29 | * 30 | * @param sql 实际SQL语句 31 | * @param offset 分页开始纪录条数 32 | * @param limit 分页每页显示纪录条数 33 | * @return 包含占位符的分页sql 34 | */ 35 | public String getLimit(String sql, int offset, int limit) { 36 | if (offset > 0) { 37 | throw new UnsupportedOperationException("sql server has no offset"); 38 | } 39 | return new StringBuffer(sql.length() + 8) 40 | .append(sql) 41 | .insert(getAfterSelectInsertPoint(sql), " top " + limit) 42 | .toString(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/dialect/db/SqlServer2012Dialect.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.dialect.db; 2 | 3 | import tech.wetech.mybatis.dialect.Dialect; 4 | 5 | /** 6 | * @author cjbi 7 | */ 8 | public class SqlServer2012Dialect implements Dialect { 9 | @Override 10 | public String getLimitString(String sql, int offset, int limit) { 11 | StringBuilder sqlBuilder = new StringBuilder(sql.length() + 64); 12 | sqlBuilder.append(String.format(" offset %s rows fetch next %s rows only ", limit, offset)); 13 | sqlBuilder.append(sql); 14 | return sqlBuilder.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/domain/Page.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.domain; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.function.Supplier; 6 | 7 | /** 8 | *

对请求进行分页

9 | * 使用示例: 10 | *
 11 |  * // 用法一:Mapper拦截方式
 12 |  * // 查询分页,支持任何列表查询方法拦截
 13 |  * Page page = Page.of(1, 10).list(()-> userMapper.selectAll());
 14 |  * // 总数
 15 |  * int total = page.getTotal();
 16 |  * Assert.assertEquals(page.size(),10);
 17 |  *
 18 |  * // 用法二:作为入参方式
 19 |  * public interface UserMapper {
 20 |  *     List<User> selectByNameLike(String nameLike,Page page);
 21 |  * }
 22 |  * // 使用Page
 23 |  * Page page = new Page();
 24 |  * // 第几页
 25 |  * page.setPageNum(1);
 26 |  * // 分页数
 27 |  * page.setPageSize(10);
 28 |  * // 开启总数查询,默认为true
 29 |  * page.setCountable(false);
 30 |  * List list = userMapper.selectByNameLike("zh",page);
 31 |  * Assert.assertEquals(list.size(), 10);
 32 |  * 
33 | * 34 | * @param 实体类 35 | * @author cjbi 36 | */ 37 | public class Page extends ArrayList { 38 | /** 39 | * 第几页 40 | */ 41 | private int pageNumber; 42 | /** 43 | * 分页数 44 | */ 45 | private int pageSize; 46 | /** 47 | * 开启总数查询,默认为true 48 | */ 49 | private boolean countable; 50 | /** 51 | * 总数 52 | */ 53 | private long total; 54 | /** 55 | * 分页的ThreadLocal 56 | */ 57 | private static final ThreadLocal PAGE = new ThreadLocal<>(); 58 | 59 | public Page(int pageNumber, int pageSize) { 60 | this(pageNumber, pageSize, true); 61 | } 62 | 63 | public Page(int pageNumber, int pageSize, boolean countable) { 64 | this.pageNumber = pageNumber; 65 | this.pageSize = pageSize; 66 | this.countable = countable; 67 | } 68 | 69 | public static Page of(int pageNumber, int pageSize) { 70 | return new Page(pageNumber, pageSize, true); 71 | } 72 | 73 | public static Page of(int pageNumber, int pageSize, boolean countable) { 74 | return new Page(pageNumber, pageSize, countable); 75 | } 76 | 77 | public Page list(Supplier> supplier) { 78 | PAGE.set(this); 79 | return supplier.get(); 80 | } 81 | 82 | public Page() { 83 | } 84 | 85 | public Page(Collection c, long total) { 86 | super(c); 87 | this.total = total; 88 | } 89 | 90 | public void setPageNumber(int pageNumber) { 91 | this.pageNumber = pageNumber; 92 | } 93 | 94 | public void setPageSize(int pageSize) { 95 | this.pageSize = pageSize; 96 | } 97 | 98 | public int getPageNumber() { 99 | return this.pageNumber; 100 | } 101 | 102 | public int getPageSize() { 103 | return this.pageSize; 104 | } 105 | 106 | public int getOffset() { 107 | return ((this.pageNumber - 1) * this.pageSize); 108 | } 109 | 110 | public boolean isCountable() { 111 | return countable; 112 | } 113 | 114 | public void setCountable(boolean countable) { 115 | this.countable = countable; 116 | } 117 | 118 | public boolean isFirst() { 119 | return !hasPrevious(); 120 | } 121 | 122 | public boolean isLast() { 123 | return !hasNext(); 124 | } 125 | 126 | public boolean hasNext() { 127 | return this.pageNumber < getTotalPages(); 128 | } 129 | 130 | public int getTotalPages() { 131 | return this.pageSize == 0 ? 1 : (int) Math.ceil((double) this.total / (double) this.pageSize); 132 | } 133 | 134 | public boolean hasPrevious() { 135 | return this.pageNumber > 1; 136 | } 137 | 138 | public long getTotal() { 139 | return total; 140 | } 141 | 142 | public void setTotal(int total) { 143 | this.total = total; 144 | } 145 | 146 | @Override 147 | public String toString() { 148 | return "Page{" + 149 | "pageNumber=" + pageNumber + 150 | ", pageSize=" + pageSize + 151 | ", countable=" + countable + 152 | ", total=" + total + 153 | ", list=" + super.toString() + 154 | '}'; 155 | } 156 | 157 | public static Page getThreadPage() { 158 | return PAGE.get(); 159 | } 160 | 161 | public void remove() { 162 | PAGE.remove(); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/domain/Property.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.domain; 2 | 3 | import tech.wetech.mybatis.util.EntityMappingUtil; 4 | 5 | import java.io.Serializable; 6 | import java.util.function.Function; 7 | 8 | /** 9 | * 属性 10 | * 11 | * @author cjbi 12 | */ 13 | public interface Property extends Function, Serializable { 14 | /** 15 | * 获取字段名称 16 | * 17 | * @param className 类名称 例如:tech.wetech.mybatis.entity.Goods 18 | * @return 字段名称 19 | */ 20 | default String getColumnName(String className) { 21 | return EntityMappingUtil.getColumnName(className, this); 22 | } 23 | 24 | /** 25 | * 获取属性名称 26 | * 27 | * @return 属性名称 28 | */ 29 | default String getPropertyName() { 30 | return EntityMappingUtil.getFunctionName(this); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/domain/Sort.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.domain; 2 | 3 | import tech.wetech.mybatis.util.EntityMappingUtil; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | *

对请求进行排序

10 | *

用法:

11 | * 12 | *
 13 |  * Sort sort = Sort.by("name").and("age", Direction.DESC);
 14 |  * Sort sort2 = Sort.by("id","name").desc();
 15 |  * Sort sort3 = Sort.asc("name", "age");
 16 |  * Sort sort4 = Sort.desc("name", "age");
 17 |  * Sort sort5 = Sort.by(Goods::getName, Direction.DESC).and(Goods::getId);
 18 |  * 
19 | * 20 | * @author cjbi 21 | */ 22 | public class Sort { 23 | 24 | /** 25 | * 排序方式 26 | * 27 | * @author cjbi 28 | */ 29 | public enum Direction { 30 | /** 31 | * 升序(默认) 32 | */ 33 | ASC, 34 | /** 35 | * 降序 36 | */ 37 | DESC 38 | } 39 | 40 | /** 41 | * 排序对象 42 | * 43 | * @author cjbi 44 | */ 45 | public class Order { 46 | /** 47 | * 属性字段 48 | */ 49 | private String property; 50 | /** 51 | * 排序方式 52 | */ 53 | private Direction direction; 54 | 55 | public Order(String property, Direction direction) { 56 | this.property = property; 57 | this.direction = direction; 58 | } 59 | 60 | public Order(String property) { 61 | this(property, Direction.ASC); 62 | } 63 | 64 | public void setProperty(String property) { 65 | this.property = property; 66 | } 67 | 68 | public String getProperty() { 69 | return property; 70 | } 71 | 72 | public void setDirection(Direction direction) { 73 | this.direction = direction; 74 | } 75 | 76 | public Sort.Direction getDirection() { 77 | return direction; 78 | } 79 | } 80 | 81 | private List orders = new ArrayList<>(); 82 | 83 | private Sort() { 84 | } 85 | 86 | public static Sort by(String property) { 87 | return new Sort().and(property); 88 | } 89 | 90 | public static Sort by(Property property) { 91 | return by(property.getPropertyName()); 92 | } 93 | 94 | public static Sort by(String property, Direction direction) { 95 | return new Sort().and(property, direction); 96 | } 97 | 98 | public static Sort by(Property property, Direction direction) { 99 | return by(property.getPropertyName(), direction); 100 | } 101 | 102 | public static Sort by(String... properties) { 103 | Sort sort = new Sort<>(); 104 | for (String property : properties) { 105 | sort.and(property); 106 | } 107 | return sort; 108 | } 109 | 110 | public static Sort by(Property... properties) { 111 | return by(EntityMappingUtil.getStringProperties(properties)); 112 | } 113 | 114 | public static Sort asc(String... properties) { 115 | return by(properties); 116 | } 117 | 118 | public static Sort asc(Property... properties) { 119 | return asc(EntityMappingUtil.getStringProperties(properties)); 120 | } 121 | 122 | public static Sort desc(String... properties) { 123 | Sort sort = new Sort<>(); 124 | for (String property : properties) { 125 | sort.and(property, Direction.DESC); 126 | } 127 | return sort; 128 | } 129 | 130 | public static Sort desc(Property... properties) { 131 | return desc(EntityMappingUtil.getStringProperties(properties)); 132 | } 133 | 134 | public Sort desc() { 135 | return direction(Direction.DESC); 136 | } 137 | 138 | public Sort asc() { 139 | return direction(Direction.ASC); 140 | } 141 | 142 | public Sort direction(Direction direction) { 143 | for (Sort.Order order : this.orders) { 144 | order.direction = direction; 145 | } 146 | return this; 147 | } 148 | 149 | public Sort and(String property) { 150 | this.orders.add(new Sort.Order(property)); 151 | return this; 152 | } 153 | 154 | public Sort and(Property property) { 155 | and(property.getPropertyName()); 156 | return this; 157 | } 158 | 159 | public Sort and(String property, Direction direction) { 160 | this.orders.add(new Order(property, direction)); 161 | return this; 162 | } 163 | 164 | public Sort and(Property property, Direction direction) { 165 | and(property.getPropertyName(), direction); 166 | return this; 167 | } 168 | 169 | public List getOrders() { 170 | return orders; 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/example/Example.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.example; 2 | 3 | import tech.wetech.mybatis.domain.Property; 4 | import tech.wetech.mybatis.domain.Sort; 5 | import tech.wetech.mybatis.util.EntityMappingUtil; 6 | 7 | import java.io.Serializable; 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | *

Example条件查询,灵感由MyBatis Generator而来

15 | * 使用示例: 16 | *
 17 |  *  // 一、简单的条件查询:
 18 |  *  Example<User> example = Example.of(User.class);
 19 |  *  example.createCriteria()
 20 |  *            .andEqualTo(User::getId, 1)
 21 |  *            .orEqualTo(User::getUsername, "张三")
 22 |  *            .orNotLike("avatar", "aaa")
 23 |  *            .orIsNull(User::getBirthday)
 24 |  *            .orBetween(User::getRegisterTime, new Date(), new Date())
 25 |  *            .orIn("mobile", Arrays.asList(111, "aaa", 222));
 26 |  *  example.setDistinct(true);
 27 |  *  mapper.selectByExample(example)
 28 |  *
 29 |  * // SQL语句:
 30 |  * // select distinct id, username, birthday, register_time, avatar
 31 |  * // from weshop_user
 32 |  * // WHERE (id = ? and username = ? or avatar not like ? or birthday is null or register_time between ? and ? or mobile in (?, ?, ?))
 33 |  *
 34 |  * // 二、多个Criteria语句
 35 |  * Example<User> example = Example.of(User.class);
 36 |  * example.or()
 37 |  *             .orEqualTo(User::getUsername, "bbb")
 38 |  *             .andEqualTo(User::getId, 2);
 39 |  * example.or()
 40 |  *            .andEqualTo(User::getUsername, "aaa");
 41 |  * example.and()
 42 |  *           .andLessThanOrEqualTo(User::getId, 1000)
 43 |  *           .andGreaterThanOrEqualTo(User::getId, 1);
 44 |  * Criteria<User> criteria = new Criteria<>();
 45 |  * criteria.andIsNull("mobile").andLessThan(User::getNickname,"测试");
 46 |  * example.and(criteria);
 47 |  * // 排序
 48 |  * example.setSort(Sort.by("name").and("age", Direction.DESC));
 49 |  * // 可以和Page对象一起使用
 50 |  * List<User> users = Page.of(1,3).list(()-> mapper.selectByExample(example));
 51 |  *
 52 |  * // SQL语句:
 53 |  * // select  id, username, birthday, register_time, avatar
 54 |  * // from weshop_user
 55 |  * // WHERE  (username = ? and id = ?)
 56 |  * //       or   (username = ?)
 57 |  * //      and   (id <= ? and id >= ?)
 58 |  * //      and   ( mobile is null and nickname < ? )
 59 |  * 
60 | * 61 | * @author cjbi 62 | */ 63 | public class Example implements Serializable { 64 | 65 | protected List columns; 66 | protected boolean distinct; 67 | protected String orderByClause; 68 | protected final Class entityClass; 69 | protected List oredCriteria; 70 | 71 | public Criteria or() { 72 | Criteria criteria = createCriteriaInternal(); 73 | oredCriteria.add(criteria); 74 | return criteria; 75 | } 76 | 77 | public Criteria or(Criteria criteria) { 78 | oredCriteria.add(criteria); 79 | return criteria; 80 | } 81 | 82 | public Criteria and() { 83 | Criteria criteria = createCriteriaInternal(); 84 | criteria.andOr("AND"); 85 | oredCriteria.add(criteria); 86 | return criteria; 87 | } 88 | 89 | public Criteria and(Criteria criteria) { 90 | oredCriteria.add(criteria); 91 | criteria.andOr("AND"); 92 | return criteria; 93 | } 94 | 95 | public static Example of(Class entityClass) { 96 | return new Example<>(entityClass); 97 | } 98 | 99 | public Criteria createCriteria() { 100 | Criteria criteria = createCriteriaInternal(); 101 | if (oredCriteria.size() == 0) { 102 | oredCriteria.add(criteria); 103 | } 104 | return criteria; 105 | } 106 | 107 | protected Criteria createCriteriaInternal() { 108 | Criteria criteria = new Criteria<>(); 109 | return criteria; 110 | } 111 | 112 | public Example(Class entityClass) { 113 | this.entityClass = entityClass; 114 | this.oredCriteria = new ArrayList<>(); 115 | } 116 | 117 | public void clear() { 118 | oredCriteria.clear(); 119 | orderByClause = null; 120 | distinct = false; 121 | } 122 | 123 | @Deprecated 124 | public List getColumns() { 125 | return columns; 126 | } 127 | 128 | /** 129 | * 为了保证数据完整性,不推荐自定义查询字段 130 | * 131 | * @param properties 132 | * @return 133 | * @since 1.6.6 134 | */ 135 | @Deprecated 136 | public Example setSelects(Property... properties) { 137 | this.columns = Arrays.stream(properties) 138 | .map(p -> p.getColumnName(entityClass.getName())) 139 | .collect(Collectors.toList()); 140 | return this; 141 | } 142 | 143 | /** 144 | * 为了保证数据完整性,不推荐自定义查询字段 145 | * 146 | * @param properties 147 | * @return 148 | * @since 1.6.6 149 | */ 150 | @Deprecated 151 | public Example setSelects(String... properties) { 152 | this.columns = Arrays.asList(properties); 153 | return this; 154 | } 155 | 156 | public boolean isDistinct() { 157 | return distinct; 158 | } 159 | 160 | public Example setDistinct(boolean distinct) { 161 | this.distinct = distinct; 162 | return this; 163 | } 164 | 165 | public Example setOrderByClause(String orderByClause) { 166 | this.orderByClause = orderByClause; 167 | return this; 168 | } 169 | 170 | public String getOrderByClause() { 171 | return orderByClause; 172 | } 173 | 174 | public Example setSort(Sort sort) { 175 | if (sort.getOrders() != null && sort.getOrders().size() > 0) { 176 | List orders = sort.getOrders(); 177 | this.orderByClause = orders.stream() 178 | .map(order -> EntityMappingUtil.getColumnName(entityClass.getName(), order.getProperty()).concat(" ").concat(order.getDirection().toString())) 179 | .collect(Collectors.joining(",")); 180 | } 181 | return this; 182 | } 183 | 184 | @Deprecated 185 | public Example setSort(tech.wetech.mybatis.example.Sort sort) { 186 | if (sort.getOrders() != null && sort.getOrders().size() > 0) { 187 | this.orderByClause = sort.getOrders().stream() 188 | .map(order -> EntityMappingUtil.getColumnName(entityClass.getName(), order.getProperty()).concat(" ").concat(order.getDirection().toString())) 189 | .collect(Collectors.joining(",")); 190 | } 191 | return this; 192 | } 193 | 194 | public List getOredCriteria() { 195 | return oredCriteria; 196 | } 197 | 198 | @Override 199 | public String toString() { 200 | return "Example{" + 201 | "columns=" + columns + 202 | ", distinct=" + distinct + 203 | ", orderByClause='" + orderByClause + '\'' + 204 | ", oredCriteria=" + oredCriteria + 205 | ", entityClass=" + entityClass + 206 | '}'; 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/example/MapperExample.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.example; 2 | 3 | import tech.wetech.mybatis.domain.Property; 4 | import tech.wetech.mybatis.mapper.BaseMapper; 5 | import tech.wetech.mybatis.util.EntityMappingUtil; 6 | 7 | /** 8 | *

Example条件查询,灵感由MyBatis Generator而来

9 | * 10 | * @author cjbi 11 | * @see Example 12 | */ 13 | public final class MapperExample extends Example { 14 | 15 | private final BaseMapper mapper; 16 | 17 | @Override 18 | public MapperCriteria or() { 19 | return (MapperCriteria) super.or(); 20 | } 21 | 22 | @Override 23 | public MapperCriteria or(Criteria criteria) { 24 | return (MapperCriteria) super.or(criteria); 25 | } 26 | 27 | @Override 28 | public MapperCriteria and() { 29 | return (MapperCriteria) super.and(); 30 | } 31 | 32 | @Override 33 | public MapperCriteria and(Criteria criteria) { 34 | return (MapperCriteria) super.and(criteria); 35 | } 36 | 37 | public MapperExample(BaseMapper mapper) { 38 | super(EntityMappingUtil.extractEntityClass(mapper.getClass().getInterfaces()[0])); 39 | this.mapper = mapper; 40 | } 41 | 42 | @Override 43 | public MapperCriteria createCriteria() { 44 | return (MapperCriteria) super.createCriteria(); 45 | } 46 | 47 | @Override 48 | protected MapperCriteria createCriteriaInternal() { 49 | MapperCriteria mapperCriteria = new MapperCriteria<>(mapper, this); 50 | return mapperCriteria; 51 | } 52 | 53 | @Override 54 | public MapperExample setSelects(Property... properties) { 55 | super.setSelects(properties); 56 | return this; 57 | } 58 | 59 | @Override 60 | public MapperExample setSelects(String... properties) { 61 | super.setSelects(properties); 62 | return this; 63 | } 64 | 65 | @Override 66 | public MapperExample setDistinct(boolean distinct) { 67 | super.setDistinct(distinct); 68 | return this; 69 | } 70 | 71 | @Override 72 | public MapperExample setOrderByClause(String orderByClause) { 73 | super.setOrderByClause(orderByClause); 74 | return this; 75 | } 76 | 77 | @Override 78 | public MapperExample setSort(Sort sort) { 79 | super.setSort(sort); 80 | return this; 81 | } 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/example/Sort.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.example; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | /** 9 | * 此类已经过时,请使用tech.wetech.mybatis.domain.Sort替代 10 | * 11 | * @author cjbi 12 | * @see tech.wetech.mybatis.domain.Sort 13 | */ 14 | @Deprecated 15 | public class Sort implements Serializable { 16 | 17 | public static final Sort.Direction DEFAULT_DIRECTION; 18 | private final List orders; 19 | 20 | static { 21 | DEFAULT_DIRECTION = Sort.Direction.ASC; 22 | } 23 | 24 | public Sort(List orders) { 25 | this.orders = orders; 26 | } 27 | 28 | public Sort(Direction direction, String... properties) { 29 | this(direction, properties == null ? new ArrayList<>() : Arrays.asList(properties)); 30 | } 31 | 32 | public Sort(String... properties) { 33 | this(DEFAULT_DIRECTION, properties); 34 | } 35 | 36 | public Sort(Direction direction, List properties) { 37 | if (properties == null || properties.isEmpty()) { 38 | throw new IllegalArgumentException("You have to provide at least one property to sort by!"); 39 | } 40 | this.orders = new ArrayList<>(properties.size()); 41 | for (String property : properties) { 42 | this.orders.add(new Order(direction, property)); 43 | } 44 | } 45 | 46 | public List getOrders() { 47 | return orders; 48 | } 49 | 50 | public static enum Direction { 51 | ASC, 52 | DESC 53 | } 54 | 55 | public static class Order implements Serializable { 56 | 57 | private final String property; 58 | private final Direction direction; 59 | 60 | public Order(Direction direction, String property) { 61 | this.direction = direction; 62 | this.property = property; 63 | } 64 | 65 | public Order(String property) { 66 | this(DEFAULT_DIRECTION, property); 67 | } 68 | 69 | public String getProperty() { 70 | return property; 71 | } 72 | 73 | public Direction getDirection() { 74 | return direction; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/mapper/BaseMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.mapper; 2 | 3 | import org.apache.ibatis.annotations.Param; 4 | import tech.wetech.mybatis.annotation.DeleteEntityProvider; 5 | import tech.wetech.mybatis.annotation.InsertEntityProvider; 6 | import tech.wetech.mybatis.annotation.SelectEntityProvider; 7 | import tech.wetech.mybatis.annotation.UpdateEntityProvider; 8 | import tech.wetech.mybatis.example.Example; 9 | import tech.wetech.mybatis.example.MapperCriteria; 10 | import tech.wetech.mybatis.example.MapperExample; 11 | 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | /** 16 | * 基础语句SQL实体Mapper映射 17 | * 18 | * @author cjbi 19 | */ 20 | public interface BaseMapper extends Mapper { 21 | 22 | /** 23 | * 通过主键id删除一条记录 24 | * @param id 主键 25 | * @return 受影响的行数 26 | */ 27 | @DeleteEntityProvider(type = BaseEntitySqlBuilder.class, method = "deleteByPrimaryKey") 28 | int deleteByPrimaryKey(Object id); 29 | 30 | /** 31 | * 插入记录 32 | * @param record 要插入的记录 33 | * @param 实体类 34 | * @return 受影响的行数 35 | */ 36 | @InsertEntityProvider(type = BaseEntitySqlBuilder.class, method = "insert") 37 | int insert(S record); 38 | 39 | /** 40 | * 插入非null的记录 41 | * @param record 要插入的记录 42 | * @param 实体类 43 | * @return 受影响的行数 44 | */ 45 | @InsertEntityProvider(type = BaseEntitySqlBuilder.class, method = "insertSelective") 46 | int insertSelective(S record); 47 | 48 | /** 49 | * 通过主键查询返回{@link java.util.Optional}包裹的记录 50 | * @param id 主键 51 | * @param 实体类 52 | * @return 返回的记录 53 | */ 54 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectByPrimaryKey") 55 | S selectByPrimaryKey(Object id); 56 | 57 | /** 58 | * 通过主键查询返回{@link java.util.Optional}包裹的记录 59 | * @param id 主键 60 | * @param 实体类 61 | * @return 受影响的行数 62 | */ 63 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectByPrimaryKeyWithOptional") 64 | Optional selectByPrimaryKeyWithOptional(Object id); 65 | 66 | /** 67 | * 通过主键更新非null的记录 68 | * @param record 记录 69 | * @param 实体类 70 | * @return 受影响的行数 71 | */ 72 | @UpdateEntityProvider(type = BaseEntitySqlBuilder.class, method = "updateByPrimaryKey") 73 | int updateByPrimaryKey(S record); 74 | 75 | /** 76 | * 通过主键更新非null的记录 77 | * @param record 记录 78 | * @param 实体类 79 | * @return 受影响的行数 80 | */ 81 | @UpdateEntityProvider(type = BaseEntitySqlBuilder.class, method = "updateByPrimaryKeySelective") 82 | int updateByPrimaryKeySelective(S record); 83 | 84 | /** 85 | * 查询所有记录 86 | * @param 实体类 87 | * @return 返回的记录 88 | */ 89 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectAll") 90 | List selectAll(); 91 | 92 | /** 93 | * 查询多条记录 94 | * @param record 条件 95 | * @param 实体类 96 | * @return 返回的记录 97 | */ 98 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectList") 99 | List selectList(S record); 100 | 101 | /** 102 | * 查询一条记录 103 | * @param record 条件 104 | * @param 实体类 105 | * @return 返回的记录 106 | */ 107 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectOne") 108 | S selectOne(S record); 109 | 110 | /** 111 | * 查询一条记录通过{@link java.util.Optional}包裹 112 | * @param record 条件 113 | * @param 实体类 114 | * @return 返回的记录 115 | */ 116 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectOneWithOptional") 117 | Optional selectOneWithOptional(S record); 118 | 119 | /** 120 | * 通过主键判断记录是否存在 121 | * @param id 主键 122 | * @return 是否存在 123 | */ 124 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "existsByPrimaryKey") 125 | boolean existsByPrimaryKey(Object id); 126 | 127 | /** 128 | * 统计记录 129 | * @param record 条件 130 | * @param 实体类 131 | * @return 记录数 132 | */ 133 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "count") 134 | int count(S record); 135 | 136 | /** 137 | * 通过{@link tech.wetech.mybatis.example.Example}查询记录 138 | * 139 | * @param example 条件查询 140 | * @param 实体类 141 | * @return 返回的记录 142 | */ 143 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "selectByExample") 144 | List selectByExample(Example example); 145 | 146 | /** 147 | * 通过{@link tech.wetech.mybatis.example.Example}统计记录 148 | * 149 | * @param example 条件查询 150 | * @param 实体类 151 | * @return 记录数 152 | */ 153 | @SelectEntityProvider(type = BaseEntitySqlBuilder.class, method = "countByExample") 154 | int countByExample(Example example); 155 | 156 | /** 157 | * 通过{@link tech.wetech.mybatis.example.Example}删除记录 158 | * 159 | * @param example 条件查询 160 | * @param 实体类 161 | * @return 受影响的行数 162 | */ 163 | @DeleteEntityProvider(type = BaseEntitySqlBuilder.class, method = "deleteByExample") 164 | int deleteByExample(Example example); 165 | 166 | /** 167 | * 通过{@link tech.wetech.mybatis.example.Example}更新记录 168 | * 169 | * @param record 记录 170 | * @param example 条件 171 | * @param 实体类 172 | * @return 受影响的行数 173 | */ 174 | @UpdateEntityProvider(type = BaseEntitySqlBuilder.class, method = "updateByExample") 175 | int updateByExample(@Param("record") S record, @Param("example") Example example); 176 | 177 | /** 178 | * 通过{@link tech.wetech.mybatis.example.Example}更新非null的记录 179 | * 180 | * @param record 记录 181 | * @param example 条件 182 | * @param 实体类 183 | * @return 受影响的行数 184 | */ 185 | @UpdateEntityProvider(type = BaseEntitySqlBuilder.class, method = "updateByExampleSelective") 186 | int updateByExampleSelective(@Param("record") S record, @Param("example") Example example); 187 | 188 | /** 189 | * 创建Criteria条件 190 | * 191 | * @param 实体类 192 | * @return Criteria条件 193 | */ 194 | default MapperCriteria createCriteria() { 195 | return new MapperCriteria(this); 196 | } 197 | 198 | /** 199 | * 创建Example条件 200 | * 201 | * @param 实体类 202 | * @return Example条件 203 | */ 204 | default MapperExample createExample() { 205 | return new MapperExample(this); 206 | } 207 | 208 | } 209 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/mapper/Mapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.mapper; 2 | 3 | /** 4 | * 实体mapper的公共接口 5 | * 6 | * @author cjbi 7 | */ 8 | public interface Mapper { 9 | } 10 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/main/java/tech/wetech/mybatis/util/EntityMappingUtil.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.util; 2 | 3 | import org.apache.ibatis.binding.BindingException; 4 | import tech.wetech.mybatis.builder.EntityMapperBuilder; 5 | import tech.wetech.mybatis.builder.EntityMapping; 6 | import tech.wetech.mybatis.domain.Property; 7 | 8 | import java.beans.Introspector; 9 | import java.lang.annotation.Annotation; 10 | import java.lang.invoke.SerializedLambda; 11 | import java.lang.reflect.*; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.function.Function; 15 | import java.util.stream.Collectors; 16 | 17 | /** 18 | * 实体类映射工具类 19 | * 20 | * @author cjbi 21 | */ 22 | public class EntityMappingUtil { 23 | 24 | /** 25 | * 通过注解查找实体属性 26 | * 27 | * @param entityMapping 实体类映射 28 | * @param clazz 实体类类型 29 | * @return 查找到的实体属性 30 | */ 31 | public static List findAnnotationColumnProperty(EntityMapping entityMapping, Class clazz) { 32 | return entityMapping.getColumnProperties() 33 | .stream() 34 | .filter(columnProperty -> columnProperty.getAnnotation(clazz) != null) 35 | .collect(Collectors.toList()); 36 | } 37 | 38 | /** 39 | * 通过注解查找一个实体属性 40 | * 41 | * @param entityMapping 实体类映射 42 | * @param clazz 实体类类型 43 | * @return 查找到的一个实体属性 44 | */ 45 | public static EntityMapping.ColumnProperty findAnnotationColumnPropertyOne(EntityMapping entityMapping, Class clazz) { 46 | return entityMapping.getColumnProperties() 47 | .stream() 48 | .filter(columnProperty -> columnProperty.getAnnotation(clazz) != null) 49 | .findFirst() 50 | .orElse(null); 51 | } 52 | 53 | /** 54 | * 获取表字段名 55 | * 56 | * @param className 实体类名 57 | * @param property 实体类属性 58 | * @return 表字段名 59 | */ 60 | public static String getColumnName(String className, String property) { 61 | EntityMapping entityMapping = EntityMapperBuilder.TABLE_ENTITY_CACHE.get(className); 62 | Map columnPropertyMap = entityMapping.getColumnPropertyMap(); 63 | EntityMapping.ColumnProperty columnProperty = columnPropertyMap.get(property); 64 | if (columnProperty == null) { 65 | throw new BindingException("Property " + property + " is not mapping to the EntityMapping."); 66 | } 67 | return columnProperty.getColumnName(); 68 | } 69 | 70 | /** 71 | * 获取表字段名 72 | * 73 | * @param className 实体类名 74 | * @param fn 函数参数 75 | * @param 函数名 76 | * @return 表字段名 77 | */ 78 | public static String getColumnName(String className, FN fn) { 79 | return getColumnName(className, getFunctionName(fn)); 80 | } 81 | 82 | /** 83 | * 提取实体Mapper的类类型 84 | * 85 | * @param mapperClass 实体Mapper 86 | * @return 实体类类型 87 | */ 88 | public static Class extractEntityClass(Class mapperClass) { 89 | Type[] types = mapperClass.getGenericInterfaces(); 90 | ParameterizedType target = null; 91 | for (Type type : types) { 92 | if (type instanceof ParameterizedType) { 93 | Type[] typeArray = ((ParameterizedType) type).getActualTypeArguments(); 94 | if (typeArray != null && typeArray.length > 0) { 95 | for (Type t : typeArray) { 96 | if (t instanceof TypeVariable || t instanceof WildcardType) { 97 | break; 98 | } else { 99 | target = (ParameterizedType) type; 100 | break; 101 | } 102 | } 103 | } 104 | break; 105 | } 106 | } 107 | return target == null ? null : (Class) target.getActualTypeArguments()[0]; 108 | } 109 | 110 | /** 111 | * 获取属性名 112 | * 113 | * @param fn 函数参数 114 | * @param 函数名 115 | * @return 表字段名 116 | */ 117 | public static String getFunctionName(FN fn) { 118 | try { 119 | Method declaredMethod = fn.getClass().getDeclaredMethod("writeReplace"); 120 | declaredMethod.setAccessible(Boolean.TRUE); 121 | SerializedLambda serializedLambda = (SerializedLambda) declaredMethod.invoke(fn); 122 | String method = serializedLambda.getImplMethodName(); 123 | String attr = null; 124 | if (method.startsWith("get")) { 125 | attr = method.substring(3); 126 | } else { 127 | attr = method.substring(2); 128 | } 129 | return Introspector.decapitalize(attr); 130 | } catch (ReflectiveOperationException var6) { 131 | throw new RuntimeException(var6); 132 | } 133 | } 134 | 135 | /** 136 | * 获取字符串形式属性列表 137 | * 138 | * @param properties 属性列表 139 | * @return 字符串形式属性列表 140 | */ 141 | public static String[] getStringProperties(Property... properties) { 142 | String[] stringProperties = new String[properties.length]; 143 | for (int i = 0; i < properties.length; i++) { 144 | stringProperties[i] = properties[i].getPropertyName(); 145 | } 146 | return stringProperties; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/test/java/tech/wetech/mybatis/BaseDataTest.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import org.apache.ibatis.datasource.pooled.PooledDataSource; 4 | import org.apache.ibatis.io.Resources; 5 | import org.apache.ibatis.jdbc.ScriptRunner; 6 | 7 | import javax.sql.DataSource; 8 | import java.io.IOException; 9 | import java.io.Reader; 10 | import java.sql.Connection; 11 | import java.sql.SQLException; 12 | import java.util.Properties; 13 | 14 | public abstract class BaseDataTest { 15 | 16 | public static final String DERBY_PROPERTIES = "tech/wetech/mybatis/databases/goods/goods-derby.properties"; 17 | public static final String SCHEMA_SQL = "tech/wetech/mybatis/databases/goods/goods-derby-schema.sql"; 18 | public static final String DATA_SQL = "tech/wetech/mybatis/databases/goods/goods-derby-dataload.sql"; 19 | 20 | public static void runScript(DataSource ds, String resource) throws IOException, SQLException { 21 | try (Connection connection = ds.getConnection()) { 22 | ScriptRunner runner = new ScriptRunner(connection); 23 | runner.setAutoCommit(true); 24 | runner.setStopOnError(false); 25 | runner.setLogWriter(null); 26 | runner.setErrorLogWriter(null); 27 | runScript(runner, resource); 28 | } 29 | } 30 | 31 | public static void runScript(ScriptRunner runner, String resource) throws IOException, SQLException { 32 | try (Reader reader = Resources.getResourceAsReader(resource)) { 33 | runner.runScript(reader); 34 | } 35 | } 36 | 37 | public static DataSource createPooledDataSource(String resource) throws IOException, SQLException { 38 | Properties props = Resources.getResourceAsProperties(resource); 39 | PooledDataSource ds = new PooledDataSource(); 40 | ds.setDriver(props.getProperty("driver")); 41 | ds.setUrl(props.getProperty("url")); 42 | ds.setUsername(props.getProperty("username")); 43 | ds.setPassword(props.getProperty("password")); 44 | return ds; 45 | } 46 | 47 | public static DataSource createDataSource() throws IOException, SQLException { 48 | DataSource ds = createPooledDataSource(DERBY_PROPERTIES); 49 | runScript(ds, SCHEMA_SQL); 50 | runScript(ds, DATA_SQL); 51 | return ds; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/test/java/tech/wetech/mybatis/databases/goods/goods-derby-schema.sql: -------------------------------------------------------------------------------- 1 | drop table T_GOODS; 2 | create table T_GOODS 3 | ( 4 | ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 10000) PRIMARY KEY, 5 | CATEGORY_ID INTEGER default 0, 6 | GOODS_SN VARCHAR(255), 7 | NAME VARCHAR(255), 8 | BRAND_ID INTEGER default 0, 9 | GOODS_UNIT VARCHAR(255), 10 | GOODS_BRIEF VARCHAR(255), 11 | GOODS_DESC CLOB, 12 | IS_ON_SALE INTEGER default 1, 13 | CREATE_TIME TIMESTAMP default CURRENT_TIMESTAMP, 14 | SORT_ORDER INTEGER default 100, 15 | IS_DELETE INTEGER default 0, 16 | ATTRIBUTE_CATEGORY INTEGER default 0, 17 | COUNTER_PRICE DECIMAL(10,2) default 0.00, 18 | EXTRA_PRICE DECIMAL(10,2) default 0.00, 19 | IS_NEW INTEGER default 0, 20 | KEYWORDS VARCHAR(255) default 'NULL', 21 | GOODS_NUMBER INTEGER default 0, 22 | LIST_PIC_URL VARCHAR(255), 23 | RETAIL_PRICE DECIMAL(10,2) default 0.00, 24 | SELL_VOLUME INTEGER default 0, 25 | PRIMARY_PRODUCT_ID INTEGER default 0, 26 | UNIT_PRICE DECIMAL(10,2) default 0.00, 27 | PROMOTION_DESC VARCHAR(255), 28 | PROMOTION_TAG VARCHAR(255), 29 | APP_EXCLUSIVE_PRICE DECIMAL(10,2), 30 | IS_APP_EXCLUSIVE INTEGER, 31 | IS_LIMITED INTEGER, 32 | IS_HOT INTEGER default 0, 33 | PRIMARY_PIC_URL VARCHAR(255), 34 | VERSION INTEGER default 0 35 | ); 36 | 37 | create index BRAND_ID 38 | on T_GOODS (BRAND_ID); 39 | 40 | create index CAT_ID 41 | on T_GOODS (CATEGORY_ID); 42 | 43 | create index GOODS_NUMBER 44 | on T_GOODS (GOODS_NUMBER); 45 | 46 | create index GOODS_SN 47 | on T_GOODS (GOODS_SN); 48 | 49 | create index SORT_ORDER 50 | on T_GOODS (SORT_ORDER); 51 | 52 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/test/java/tech/wetech/mybatis/databases/goods/goods-derby.properties: -------------------------------------------------------------------------------- 1 | driver=org.apache.derby.jdbc.EmbeddedDriver 2 | url=jdbc:derby:ibderby;create=true 3 | username= 4 | password= -------------------------------------------------------------------------------- /mybatis-ext-core/src/test/java/tech/wetech/mybatis/mapper/GoodsMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.mapper; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import tech.wetech.mybatis.domain.Page; 5 | import tech.wetech.mybatis.entity.Goods; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public interface GoodsMapper extends BaseMapper { 11 | List> selectAllGoods(); 12 | 13 | List> selectAllGoodsWithPage(Page page); 14 | 15 | @Select("select * from t_goods") 16 | List selectAllGoodsWithAnnotation(); 17 | } 18 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/test/java/tech/wetech/mybatis/mapper/GoodsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /mybatis-ext-core/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Global logging configuration 2 | log4j.rootLogger=DEBUG, stdout 3 | # MyBatis logging configuration... 4 | #log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 | # Console output... 6 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=[%5p] %d{yyyy-MM-dd HH:mm:ss} [%F:%L] %m %n -------------------------------------------------------------------------------- /mybatis-ext-parent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | tech.wetech.mybatis 8 | mybatis-ext-parent 9 | 1.6.9 10 | mybatis-ext-parent 11 | Mybatis Extensions Parent. 12 | https://github.com/cjbi/mybatis-ext 13 | pom 14 | 15 | 1.8 16 | UTF-8 17 | UTF-8 18 | 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-javadoc-plugin 27 | 3.1.0 28 | 29 | UTF-8 30 | 31 | 32 | 33 | attach-javadocs 34 | 35 | jar 36 | 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-source-plugin 43 | 3.1.0 44 | 45 | 46 | attach-sources 47 | 48 | jar 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-compiler-plugin 56 | 3.8.1 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-gpg-plugin 61 | 1.6 62 | 63 | 64 | verify 65 | 66 | sign 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | cjbi 76 | cjbi@outlook.com 77 | https://github.com/cjbi 78 | 79 | Owner 80 | Committer 81 | 82 | 83 | 84 | 85 | 86 | The Apache Software License, Version 2.0 87 | http://www.apache.org/licenses/LICENSE-2.0.txt 88 | 89 | 90 | 91 | scm:git:https://github.com/cjbi/mybatis-ext.git 92 | scm:git:https://github.com/cjbi/mybatis-ext.git 93 | scm:git:https://github.com/cjbi 94 | 95 | 96 | 97 | 98 | public-distribute 99 | 100 | 101 | sonatype-snapshot 102 | https://oss.sonatype.org/content/repositories/snapshots 103 | 104 | 105 | sonatype-release 106 | https://oss.sonatype.org/service/local/staging/deploy/maven2 107 | 108 | 109 | 110 | true 111 | 112 | 113 | 114 | qy-distribute 115 | 116 | 117 | qy-maven-snapshots 118 | http://mvn.qpaas.com:2233/repository/qy-maven-snapshots/ 119 | 120 | 121 | qy-maven-releases 122 | http://mvn.qpaas.com:2233/repository/qy-maven-releases/ 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | tech.wetech.mybatis.simple 8 | mybatis-ext-simple-java 9 | 1.6.9 10 | 11 | 12 | 1.8 13 | UTF-8 14 | UTF-8 15 | 16 | 1.8 17 | 1.8 18 | true 19 | 20 | 21 | 22 | 23 | tech.wetech.mybatis 24 | mybatis-ext-core 25 | 1.6.9 26 | 27 | 28 | mysql 29 | mysql-connector-java 30 | 8.0.16 31 | runtime 32 | 33 | 34 | org.slf4j 35 | slf4j-simple 36 | 1.6.1 37 | 38 | 39 | org.slf4j 40 | slf4j-log4j12 41 | 1.6.1 42 | 43 | 44 | 45 | 46 | 47 | src/main/java 48 | 49 | **/*.xml 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/src/main/java/tech/wetech/mybatis/simple/Simple.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple; 2 | 3 | import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory; 4 | import org.apache.ibatis.logging.log4j.Log4jImpl; 5 | import org.apache.ibatis.mapping.Environment; 6 | import org.apache.ibatis.session.SqlSession; 7 | import org.apache.ibatis.session.SqlSessionFactory; 8 | import org.apache.ibatis.transaction.TransactionFactory; 9 | import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import tech.wetech.mybatis.ExtConfiguration; 13 | import tech.wetech.mybatis.ExtSqlSessionFactoryBuilder; 14 | import tech.wetech.mybatis.simple.mapper.UserMapper; 15 | 16 | import javax.sql.DataSource; 17 | import java.util.Properties; 18 | 19 | public class Simple { 20 | 21 | public static final SqlSessionFactory sqlSessionFactory; 22 | 23 | public static final Logger log = LoggerFactory.getLogger(Simple.class); 24 | 25 | static { 26 | //新建一个连接池方式的数据源工厂 27 | PooledDataSourceFactory pooledDataSourceFactory = new PooledDataSourceFactory(); 28 | //设置数据源 29 | Properties systemProperties = System.getProperties(); 30 | //-Ddriver=<驱动> -Durl=<数据库连接> -Dusername=<用户名> -Dpassword=<密码> 31 | String driver = systemProperties.getProperty("driver"); 32 | String url = systemProperties.getProperty("url"); 33 | String username = systemProperties.getProperty("username"); 34 | String password = systemProperties.getProperty("password"); 35 | assert driver != null : "driver cannot be null"; 36 | assert url != null : "url cannot be null"; 37 | assert username != null : "username cannot be null"; 38 | assert password != null : "password cannot be null"; 39 | Properties properties = new Properties(); 40 | properties.setProperty("driver", driver); 41 | properties.setProperty("url", url); 42 | properties.setProperty("username", username); 43 | properties.setProperty("password", password); 44 | pooledDataSourceFactory.setProperties(properties); 45 | DataSource dataSource = pooledDataSourceFactory.getDataSource(); 46 | //新建会话工厂 47 | TransactionFactory transactionFactory = new JdbcTransactionFactory(); 48 | Environment environment = new Environment("development", transactionFactory, dataSource); 49 | ExtConfiguration configuration = new ExtConfiguration(environment); 50 | configuration.setLogImpl(Log4jImpl.class); 51 | //添加Mapper映射 52 | configuration.addMapper(UserMapper.class); 53 | sqlSessionFactory = new ExtSqlSessionFactoryBuilder().build(configuration); 54 | } 55 | 56 | public static SqlSession getSqlSession() { 57 | return sqlSessionFactory.openSession(); 58 | } 59 | 60 | public static void main(String[] args) { 61 | SqlSession sqlSession = Simple.getSqlSession(); 62 | UserMapper mapper = sqlSession.getMapper(UserMapper.class); 63 | log.info("mybatis-ext查询出的所有用户:{}",mapper.selectAll()); 64 | log.info("注解方式查询出的所有用户:{}",mapper.selectAllUserWithAnnotation()); 65 | log.info("xml方式查询出的所有用户:{}",mapper.selectAllUser()); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/src/main/java/tech/wetech/mybatis/simple/entity/User.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Id; 5 | import javax.persistence.Table; 6 | import java.util.Date; 7 | 8 | @Table(name = "weshop_user") 9 | public class User { 10 | @Id 11 | private Integer id; 12 | 13 | private String username; 14 | 15 | private String password; 16 | 17 | @Column(name = "gender") 18 | private String gender; 19 | 20 | private Date birthday; 21 | 22 | @Column(name = "register_time") 23 | private Date registerTime; 24 | 25 | @Column(name = "last_login_time") 26 | private Date lastLoginTime; 27 | 28 | @Column(name = "last_login_ip") 29 | private String lastLoginIp; 30 | 31 | @Column(name = "user_level_id") 32 | private Byte userLevelId; 33 | 34 | private String nickname; 35 | 36 | private String mobile; 37 | 38 | @Column(name = "register_ip") 39 | private String registerIp; 40 | 41 | private String avatar; 42 | 43 | @Column(name = "wechat_open_id") 44 | private String wechatOpenId; 45 | 46 | public Integer getId() { 47 | return id; 48 | } 49 | 50 | public User setId(Integer id) { 51 | this.id = id; 52 | return this; 53 | } 54 | 55 | public String getUsername() { 56 | return username; 57 | } 58 | 59 | public User setUsername(String username) { 60 | this.username = username; 61 | return this; 62 | } 63 | 64 | public String getPassword() { 65 | return password; 66 | } 67 | 68 | public User setPassword(String password) { 69 | this.password = password; 70 | return this; 71 | } 72 | 73 | public String getGender() { 74 | return gender; 75 | } 76 | 77 | public User setGender(String gender) { 78 | this.gender = gender; 79 | return this; 80 | } 81 | 82 | public Date getBirthday() { 83 | return birthday; 84 | } 85 | 86 | public User setBirthday(Date birthday) { 87 | this.birthday = birthday; 88 | return this; 89 | } 90 | 91 | public Date getRegisterTime() { 92 | return registerTime; 93 | } 94 | 95 | public User setRegisterTime(Date registerTime) { 96 | this.registerTime = registerTime; 97 | return this; 98 | } 99 | 100 | public Date getLastLoginTime() { 101 | return lastLoginTime; 102 | } 103 | 104 | public User setLastLoginTime(Date lastLoginTime) { 105 | this.lastLoginTime = lastLoginTime; 106 | return this; 107 | } 108 | 109 | public String getLastLoginIp() { 110 | return lastLoginIp; 111 | } 112 | 113 | public User setLastLoginIp(String lastLoginIp) { 114 | this.lastLoginIp = lastLoginIp; 115 | return this; 116 | } 117 | 118 | public Byte getUserLevelId() { 119 | return userLevelId; 120 | } 121 | 122 | public User setUserLevelId(Byte userLevelId) { 123 | this.userLevelId = userLevelId; 124 | return this; 125 | } 126 | 127 | public String getNickname() { 128 | return nickname; 129 | } 130 | 131 | public User setNickname(String nickname) { 132 | this.nickname = nickname; 133 | return this; 134 | } 135 | 136 | public String getMobile() { 137 | return mobile; 138 | } 139 | 140 | public User setMobile(String mobile) { 141 | this.mobile = mobile; 142 | return this; 143 | } 144 | 145 | public String getRegisterIp() { 146 | return registerIp; 147 | } 148 | 149 | public User setRegisterIp(String registerIp) { 150 | this.registerIp = registerIp; 151 | return this; 152 | } 153 | 154 | public String getAvatar() { 155 | return avatar; 156 | } 157 | 158 | public User setAvatar(String avatar) { 159 | this.avatar = avatar; 160 | return this; 161 | } 162 | 163 | public String getWechatOpenId() { 164 | return wechatOpenId; 165 | } 166 | 167 | public User setWechatOpenId(String wechatOpenId) { 168 | this.wechatOpenId = wechatOpenId; 169 | return this; 170 | } 171 | 172 | @Override 173 | public String toString() { 174 | return "User{" + 175 | "id=" + id + 176 | ", username='" + username + '\'' + 177 | ", password='" + password + '\'' + 178 | ", gender='" + gender + '\'' + 179 | ", birthday=" + birthday + 180 | ", registerTime=" + registerTime + 181 | ", lastLoginTime=" + lastLoginTime + 182 | ", lastLoginIp='" + lastLoginIp + '\'' + 183 | ", userLevelId=" + userLevelId + 184 | ", nickname='" + nickname + '\'' + 185 | ", mobile='" + mobile + '\'' + 186 | ", registerIp='" + registerIp + '\'' + 187 | ", avatar='" + avatar + '\'' + 188 | ", wechatOpenId='" + wechatOpenId + '\'' + 189 | '}'; 190 | } 191 | } -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/src/main/java/tech/wetech/mybatis/simple/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.mapper; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import org.apache.ibatis.annotations.Update; 5 | import tech.wetech.mybatis.mapper.BaseMapper; 6 | import tech.wetech.mybatis.simple.entity.User; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public interface UserMapper extends BaseMapper { 12 | 13 | // @Select("select * from weshop_user") 14 | List> selectAllUser(); 15 | 16 | @Select("select * from weshop_user") 17 | List selectAllUserWithAnnotation(); 18 | 19 | @Select("select * from weshop_user where id=#{id}") 20 | User selectById(Integer id); 21 | 22 | @Update("update weshop_user set username='dddd' where id=#{id}") 23 | int updateById(Integer id); 24 | 25 | @Select("select count(*) from weshop_user where id=#{id}") 26 | Boolean existById(Integer id); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/src/main/java/tech/wetech/mybatis/simple/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `weshop_user` VALUES (1, 'aaa', '2323', 2, '2018-11-23', '2018-11-17 11:54:56', '2018-11-17 11:54:56', '127.0.0.1', 1, '222', '18054071681', '127.0.0.1', '', 'dssdsdsd'); 2 | INSERT INTO `weshop_user` VALUES (2, 'bbb', '22332', 1, '1936-07-17', '2018-11-17 16:02:05', '2018-11-17 16:02:05', '', 1, 'eee', '18054071681', '123232', '1212', '32323'); -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-java/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for weshop_user 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS `weshop_user`; 5 | CREATE TABLE `weshop_user` ( 6 | `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 7 | `username` varchar(60) NOT NULL DEFAULT '', 8 | `password` varchar(32) NOT NULL DEFAULT '', 9 | `gender` tinyint(2) unsigned DEFAULT 0, 10 | `birthday` date DEFAULT NULL, 11 | `register_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 12 | `last_login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 13 | `last_login_ip` varchar(15) NOT NULL DEFAULT '', 14 | `user_level_id` tinyint(3) unsigned NOT NULL DEFAULT '0', 15 | `nickname` varchar(60) NOT NULL DEFAULT '', 16 | `mobile` varchar(20) NOT NULL, 17 | `register_ip` varchar(45) NOT NULL DEFAULT '', 18 | `avatar` varchar(255) NOT NULL DEFAULT '', 19 | `wechat_open_id` varchar(50) NOT NULL DEFAULT '', 20 | PRIMARY KEY (`id`), 21 | UNIQUE KEY `user_name` (`username`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if (mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if (mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if (!outputFile.getParentFile().exists()) { 87 | if (!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cjbi/mybatis-ext/dba3a8a1eba8cb560da40e286ed2138f2158b66f/mybatis-ext-simple/mybatis-ext-simple-springboot/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.2.RELEASE 9 | 10 | 11 | tech.wetech.mybatis.simple 12 | mybatis-ext-simple-springboot 13 | 0.0.1 14 | mybatis-ext-simple-springboot 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | UTF-8 20 | UTF-8 21 | 22 | true 23 | true 24 | 25 | 1.8 26 | 1.8 27 | 28 | 29 | 30 | 31 | 32 | tech.wetech.mybatis 33 | mybatis-ext-spring-boot-starter 34 | 1.6.9 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-thymeleaf 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-web 44 | 45 | 46 | mysql 47 | mysql-connector-java 48 | runtime 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-compiler-plugin 66 | 67 | true 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-deploy-plugin 73 | 2.8.2 74 | 75 | 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/java/tech/wetech/mybatis/simple/MybatisExtSimpleSpringbootApplication.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | /** 8 | * @author cjbi 9 | */ 10 | @SpringBootApplication 11 | @MapperScan(basePackages = "tech.wetech.mybatis.simple.mapper") 12 | public class MybatisExtSimpleSpringbootApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(MybatisExtSimpleSpringbootApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/java/tech/wetech/mybatis/simple/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import tech.wetech.mybatis.simple.entity.User; 8 | import tech.wetech.mybatis.simple.service.UserService; 9 | 10 | @RestController 11 | public class UserController { 12 | 13 | @Autowired 14 | private UserService userService; 15 | 16 | @GetMapping("user/{userId}") 17 | private User queryUserById(@PathVariable("userId") Integer userId) { 18 | return userService.queryUserById(userId); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/java/tech/wetech/mybatis/simple/entity/User.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Id; 5 | import javax.persistence.Table; 6 | import java.util.Date; 7 | 8 | @Table(name = "weshop_user") 9 | public class User { 10 | @Id 11 | private Integer id; 12 | 13 | private String username; 14 | 15 | private String password; 16 | 17 | @Column(name = "gender") 18 | private String gender; 19 | 20 | private Date birthday; 21 | 22 | @Column(name = "register_time") 23 | private Date registerTime; 24 | 25 | @Column(name = "last_login_time") 26 | private Date lastLoginTime; 27 | 28 | @Column(name = "last_login_ip") 29 | private String lastLoginIp; 30 | 31 | @Column(name = "user_level_id") 32 | private Byte userLevelId; 33 | 34 | private String nickname; 35 | 36 | private String mobile; 37 | 38 | @Column(name = "register_ip") 39 | private String registerIp; 40 | 41 | private String avatar; 42 | 43 | @Column(name = "wechat_open_id") 44 | private String wechatOpenId; 45 | 46 | public Integer getId() { 47 | return id; 48 | } 49 | 50 | public User setId(Integer id) { 51 | this.id = id; 52 | return this; 53 | } 54 | 55 | public String getUsername() { 56 | return username; 57 | } 58 | 59 | public User setUsername(String username) { 60 | this.username = username; 61 | return this; 62 | } 63 | 64 | public String getPassword() { 65 | return password; 66 | } 67 | 68 | public User setPassword(String password) { 69 | this.password = password; 70 | return this; 71 | } 72 | 73 | public String getGender() { 74 | return gender; 75 | } 76 | 77 | public User setGender(String gender) { 78 | this.gender = gender; 79 | return this; 80 | } 81 | 82 | public Date getBirthday() { 83 | return birthday; 84 | } 85 | 86 | public User setBirthday(Date birthday) { 87 | this.birthday = birthday; 88 | return this; 89 | } 90 | 91 | public Date getRegisterTime() { 92 | return registerTime; 93 | } 94 | 95 | public User setRegisterTime(Date registerTime) { 96 | this.registerTime = registerTime; 97 | return this; 98 | } 99 | 100 | public Date getLastLoginTime() { 101 | return lastLoginTime; 102 | } 103 | 104 | public User setLastLoginTime(Date lastLoginTime) { 105 | this.lastLoginTime = lastLoginTime; 106 | return this; 107 | } 108 | 109 | public String getLastLoginIp() { 110 | return lastLoginIp; 111 | } 112 | 113 | public User setLastLoginIp(String lastLoginIp) { 114 | this.lastLoginIp = lastLoginIp; 115 | return this; 116 | } 117 | 118 | public Byte getUserLevelId() { 119 | return userLevelId; 120 | } 121 | 122 | public User setUserLevelId(Byte userLevelId) { 123 | this.userLevelId = userLevelId; 124 | return this; 125 | } 126 | 127 | public String getNickname() { 128 | return nickname; 129 | } 130 | 131 | public User setNickname(String nickname) { 132 | this.nickname = nickname; 133 | return this; 134 | } 135 | 136 | public String getMobile() { 137 | return mobile; 138 | } 139 | 140 | public User setMobile(String mobile) { 141 | this.mobile = mobile; 142 | return this; 143 | } 144 | 145 | public String getRegisterIp() { 146 | return registerIp; 147 | } 148 | 149 | public User setRegisterIp(String registerIp) { 150 | this.registerIp = registerIp; 151 | return this; 152 | } 153 | 154 | public String getAvatar() { 155 | return avatar; 156 | } 157 | 158 | public User setAvatar(String avatar) { 159 | this.avatar = avatar; 160 | return this; 161 | } 162 | 163 | public String getWechatOpenId() { 164 | return wechatOpenId; 165 | } 166 | 167 | public User setWechatOpenId(String wechatOpenId) { 168 | this.wechatOpenId = wechatOpenId; 169 | return this; 170 | } 171 | 172 | @Override 173 | public String toString() { 174 | return "User{" + 175 | "id=" + id + 176 | ", username='" + username + '\'' + 177 | ", password='" + password + '\'' + 178 | ", gender='" + gender + '\'' + 179 | ", birthday=" + birthday + 180 | ", registerTime=" + registerTime + 181 | ", lastLoginTime=" + lastLoginTime + 182 | ", lastLoginIp='" + lastLoginIp + '\'' + 183 | ", userLevelId=" + userLevelId + 184 | ", nickname='" + nickname + '\'' + 185 | ", mobile='" + mobile + '\'' + 186 | ", registerIp='" + registerIp + '\'' + 187 | ", avatar='" + avatar + '\'' + 188 | ", wechatOpenId='" + wechatOpenId + '\'' + 189 | '}'; 190 | } 191 | } -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/java/tech/wetech/mybatis/simple/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.mapper; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import org.apache.ibatis.annotations.Update; 5 | import tech.wetech.mybatis.mapper.BaseMapper; 6 | import tech.wetech.mybatis.simple.entity.User; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public interface UserMapper extends BaseMapper { 12 | 13 | // @Select("select * from weshop_user") 14 | List> selectAllUser(); 15 | 16 | @Select("select * from weshop_user") 17 | List selectAllUserWithAnnotation(); 18 | 19 | @Select("select * from weshop_user where id=#{id}") 20 | User selectById(Integer id); 21 | 22 | @Update("update weshop_user set username='dddd' where id=#{id}") 23 | int updateById(Integer id); 24 | 25 | @Select("select count(*) from weshop_user where id=#{id}") 26 | Boolean existById(Integer id); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/java/tech/wetech/mybatis/simple/service/UserService.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.service; 2 | 3 | import tech.wetech.mybatis.simple.entity.User; 4 | 5 | public interface UserService { 6 | 7 | User queryUserById(Integer userId); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/java/tech/wetech/mybatis/simple/service/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | import tech.wetech.mybatis.simple.entity.User; 6 | import tech.wetech.mybatis.simple.mapper.UserMapper; 7 | 8 | /** 9 | * @author cjbi 10 | */ 11 | @Service 12 | public class UserServiceImpl implements UserService { 13 | 14 | @Autowired 15 | private UserMapper userMapper; 16 | 17 | @Override 18 | public User queryUserById(Integer userId) { 19 | return userMapper.selectByPrimaryKeyWithOptional(userId) 20 | .orElseThrow(() -> new RuntimeException("用户不存在")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 2 | spring.datasource.url=<数据库地址> 3 | spring.datasource.username=<用户名> 4 | spring.datasource.password=<密码> 5 | mybatis.mapper-locations=classpath:mapper/*Mapper.xml 6 | logging.level.root=debug -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `weshop_user` VALUES (1, 'aaa', '2323', 2, '2018-11-23', '2018-11-17 11:54:56', '2018-11-17 11:54:56', '127.0.0.1', 1, '222', '18054071681', '127.0.0.1', '', 'dssdsdsd'); 2 | INSERT INTO `weshop_user` VALUES (2, 'bbb', '22332', 1, '1936-07-17', '2018-11-17 16:02:05', '2018-11-17 16:02:05', '', 1, 'eee', '18054071681', '123232', '1212', '32323'); -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for weshop_user 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS `weshop_user`; 5 | CREATE TABLE `weshop_user` ( 6 | `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 7 | `username` varchar(60) NOT NULL DEFAULT '', 8 | `password` varchar(32) NOT NULL DEFAULT '', 9 | `gender` tinyint(2) unsigned DEFAULT 0, 10 | `birthday` date DEFAULT NULL, 11 | `register_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 12 | `last_login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 13 | `last_login_ip` varchar(15) NOT NULL DEFAULT '', 14 | `user_level_id` tinyint(3) unsigned NOT NULL DEFAULT '0', 15 | `nickname` varchar(60) NOT NULL DEFAULT '', 16 | `mobile` varchar(20) NOT NULL, 17 | `register_ip` varchar(45) NOT NULL DEFAULT '', 18 | `avatar` varchar(255) NOT NULL DEFAULT '', 19 | `wechat_open_id` varchar(50) NOT NULL DEFAULT '', 20 | PRIMARY KEY (`id`), 21 | UNIQUE KEY `user_name` (`username`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springboot/src/test/java/tech/wetech/mybatis/simple/MybatisExtSimpleSpringbootApplicationTests.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class MybatisExtSimpleSpringbootApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/README.md: -------------------------------------------------------------------------------- 1 | 已经内置Maven Jetty插件,运行命令`mvn jetty:run` -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | war 8 | 9 | tech.wetech.mybatis.simple 10 | mybatis-ext-simple-springmvc 11 | 1.6.9 12 | 13 | 14 | 1.8 15 | UTF-8 16 | UTF-8 17 | 18 | true 19 | true 20 | 21 | 1.8 22 | 1.8 23 | 24 | 25 | 26 | 27 | 28 | tech.wetech.mybatis 29 | mybatis-ext-spring 30 | 1.6.9 31 | 32 | 33 | 34 | 35 | org.springframework 36 | spring-webmvc 37 | 5.3.18 38 | 39 | 40 | 41 | org.springframework 42 | spring-jdbc 43 | 5.2.0.RELEASE 44 | 45 | 46 | 47 | mysql 48 | mysql-connector-java 49 | 8.0.16 50 | 51 | 52 | 53 | javax.servlet 54 | servlet-api 55 | 3.0-alpha-1 56 | provided 57 | 58 | 59 | 60 | com.fasterxml.jackson.core 61 | jackson-databind 62 | 2.12.6.1 63 | 64 | 65 | 66 | 67 | org.slf4j 68 | slf4j-api 69 | 1.7.25 70 | 71 | 72 | 73 | ch.qos.logback 74 | logback-classic 75 | 1.2.3 76 | 77 | 78 | 79 | 80 | org.slf4j 81 | jcl-over-slf4j 82 | 1.7.25 83 | 84 | 85 | 86 | 87 | 88 | 89 | src/test/java 90 | 91 | **/*.xml 92 | 93 | 94 | 95 | 96 | 97 | org.eclipse.jetty 98 | jetty-maven-plugin 99 | 9.4.0.v20161208 100 | 101 | 102 | 1 103 | 104 | 105 | 8888 106 | 107 | 108 | 109 | /simple 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/java/tech/wetech/mybatis/simple/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import tech.wetech.mybatis.simple.entity.User; 8 | import tech.wetech.mybatis.simple.service.UserService; 9 | 10 | /** 11 | * @author cjbi 12 | */ 13 | @RestController 14 | public class UserController { 15 | 16 | @Autowired 17 | private UserService userService; 18 | 19 | @GetMapping("user/{userId}") 20 | private User queryUserById(@PathVariable("userId") Integer userId) { 21 | return userService.queryUserById(userId); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/java/tech/wetech/mybatis/simple/entity/User.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Id; 5 | import javax.persistence.Table; 6 | import java.util.Date; 7 | 8 | @Table(name = "weshop_user") 9 | public class User { 10 | @Id 11 | private Integer id; 12 | 13 | private String username; 14 | 15 | private String password; 16 | 17 | @Column(name = "gender") 18 | private String gender; 19 | 20 | private Date birthday; 21 | 22 | @Column(name = "register_time") 23 | private Date registerTime; 24 | 25 | @Column(name = "last_login_time") 26 | private Date lastLoginTime; 27 | 28 | @Column(name = "last_login_ip") 29 | private String lastLoginIp; 30 | 31 | @Column(name = "user_level_id") 32 | private Byte userLevelId; 33 | 34 | private String nickname; 35 | 36 | private String mobile; 37 | 38 | @Column(name = "register_ip") 39 | private String registerIp; 40 | 41 | private String avatar; 42 | 43 | @Column(name = "wechat_open_id") 44 | private String wechatOpenId; 45 | 46 | public Integer getId() { 47 | return id; 48 | } 49 | 50 | public User setId(Integer id) { 51 | this.id = id; 52 | return this; 53 | } 54 | 55 | public String getUsername() { 56 | return username; 57 | } 58 | 59 | public User setUsername(String username) { 60 | this.username = username; 61 | return this; 62 | } 63 | 64 | public String getPassword() { 65 | return password; 66 | } 67 | 68 | public User setPassword(String password) { 69 | this.password = password; 70 | return this; 71 | } 72 | 73 | public String getGender() { 74 | return gender; 75 | } 76 | 77 | public User setGender(String gender) { 78 | this.gender = gender; 79 | return this; 80 | } 81 | 82 | public Date getBirthday() { 83 | return birthday; 84 | } 85 | 86 | public User setBirthday(Date birthday) { 87 | this.birthday = birthday; 88 | return this; 89 | } 90 | 91 | public Date getRegisterTime() { 92 | return registerTime; 93 | } 94 | 95 | public User setRegisterTime(Date registerTime) { 96 | this.registerTime = registerTime; 97 | return this; 98 | } 99 | 100 | public Date getLastLoginTime() { 101 | return lastLoginTime; 102 | } 103 | 104 | public User setLastLoginTime(Date lastLoginTime) { 105 | this.lastLoginTime = lastLoginTime; 106 | return this; 107 | } 108 | 109 | public String getLastLoginIp() { 110 | return lastLoginIp; 111 | } 112 | 113 | public User setLastLoginIp(String lastLoginIp) { 114 | this.lastLoginIp = lastLoginIp; 115 | return this; 116 | } 117 | 118 | public Byte getUserLevelId() { 119 | return userLevelId; 120 | } 121 | 122 | public User setUserLevelId(Byte userLevelId) { 123 | this.userLevelId = userLevelId; 124 | return this; 125 | } 126 | 127 | public String getNickname() { 128 | return nickname; 129 | } 130 | 131 | public User setNickname(String nickname) { 132 | this.nickname = nickname; 133 | return this; 134 | } 135 | 136 | public String getMobile() { 137 | return mobile; 138 | } 139 | 140 | public User setMobile(String mobile) { 141 | this.mobile = mobile; 142 | return this; 143 | } 144 | 145 | public String getRegisterIp() { 146 | return registerIp; 147 | } 148 | 149 | public User setRegisterIp(String registerIp) { 150 | this.registerIp = registerIp; 151 | return this; 152 | } 153 | 154 | public String getAvatar() { 155 | return avatar; 156 | } 157 | 158 | public User setAvatar(String avatar) { 159 | this.avatar = avatar; 160 | return this; 161 | } 162 | 163 | public String getWechatOpenId() { 164 | return wechatOpenId; 165 | } 166 | 167 | public User setWechatOpenId(String wechatOpenId) { 168 | this.wechatOpenId = wechatOpenId; 169 | return this; 170 | } 171 | 172 | @Override 173 | public String toString() { 174 | return "User{" + 175 | "id=" + id + 176 | ", username='" + username + '\'' + 177 | ", password='" + password + '\'' + 178 | ", gender='" + gender + '\'' + 179 | ", birthday=" + birthday + 180 | ", registerTime=" + registerTime + 181 | ", lastLoginTime=" + lastLoginTime + 182 | ", lastLoginIp='" + lastLoginIp + '\'' + 183 | ", userLevelId=" + userLevelId + 184 | ", nickname='" + nickname + '\'' + 185 | ", mobile='" + mobile + '\'' + 186 | ", registerIp='" + registerIp + '\'' + 187 | ", avatar='" + avatar + '\'' + 188 | ", wechatOpenId='" + wechatOpenId + '\'' + 189 | '}'; 190 | } 191 | } -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/java/tech/wetech/mybatis/simple/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.mapper; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import org.apache.ibatis.annotations.Update; 5 | import tech.wetech.mybatis.mapper.BaseMapper; 6 | import tech.wetech.mybatis.simple.entity.User; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public interface UserMapper extends BaseMapper { 12 | 13 | // @Select("select * from weshop_user") 14 | List> selectAllUser(); 15 | 16 | @Select("select * from weshop_user") 17 | List selectAllUserWithAnnotation(); 18 | 19 | @Select("select * from weshop_user where id=#{id}") 20 | User selectById(Integer id); 21 | 22 | @Update("update weshop_user set username='dddd' where id=#{id}") 23 | int updateById(Integer id); 24 | 25 | @Select("select count(*) from weshop_user where id=#{id}") 26 | Boolean existById(Integer id); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/java/tech/wetech/mybatis/simple/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/java/tech/wetech/mybatis/simple/service/UserService.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.service; 2 | 3 | import tech.wetech.mybatis.simple.entity.User; 4 | 5 | public interface UserService { 6 | 7 | User queryUserById(Integer userId); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/java/tech/wetech/mybatis/simple/service/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.simple.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | import tech.wetech.mybatis.simple.entity.User; 6 | import tech.wetech.mybatis.simple.mapper.UserMapper; 7 | 8 | /** 9 | * @author cjbi 10 | */ 11 | @Service 12 | public class UserServiceImpl implements UserService { 13 | 14 | @Autowired 15 | private UserMapper userMapper; 16 | 17 | @Override 18 | public User queryUserById(Integer userId) { 19 | return userMapper.selectByPrimaryKeyWithOptional(userId) 20 | .orElseThrow(() -> new RuntimeException("用户不存在")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `weshop_user` VALUES (1, 'aaa', '2323', 2, '2018-11-23', '2018-11-17 11:54:56', '2018-11-17 11:54:56', '127.0.0.1', 1, '222', '18054071681', '127.0.0.1', '', 'dssdsdsd'); 2 | INSERT INTO `weshop_user` VALUES (2, 'bbb', '22332', 1, '1936-07-17', '2018-11-17 16:02:05', '2018-11-17 16:02:05', '', 1, 'eee', '18054071681', '123232', '1212', '32323'); -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for weshop_user 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS `weshop_user`; 5 | CREATE TABLE `weshop_user` ( 6 | `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 7 | `username` varchar(60) NOT NULL DEFAULT '', 8 | `password` varchar(32) NOT NULL DEFAULT '', 9 | `gender` tinyint(2) unsigned DEFAULT 0, 10 | `birthday` date DEFAULT NULL, 11 | `register_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 12 | `last_login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 13 | `last_login_ip` varchar(15) NOT NULL DEFAULT '', 14 | `user_level_id` tinyint(3) unsigned NOT NULL DEFAULT '0', 15 | `nickname` varchar(60) NOT NULL DEFAULT '', 16 | `mobile` varchar(20) NOT NULL, 17 | `register_ip` varchar(45) NOT NULL DEFAULT '', 18 | `avatar` varchar(255) NOT NULL DEFAULT '', 19 | `wechat_open_id` varchar(50) NOT NULL DEFAULT '', 20 | PRIMARY KEY (`id`), 21 | UNIQUE KEY `user_name` (`username`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/webapp/WEB-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/webapp/WEB-INF/dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/webapp/WEB-INF/jsp/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: cjbi 4 | Date: 19-9-2 5 | Time: 下午2:42 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 这是mybatis-ext的springMvc示例工程首页 12 | 13 | 14 | 这是mybatis-ext的springMvc示例工程首页 15 | 16 | 17 | -------------------------------------------------------------------------------- /mybatis-ext-simple/mybatis-ext-simple-springmvc/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | contextConfigLocation 8 | /WEB-INF/applicationContext.xml 9 | 10 | 11 | org.springframework.web.context.ContextLoaderListener 12 | 13 | 14 | dispatcher 15 | org.springframework.web.servlet.DispatcherServlet 16 | 1 17 | 18 | 19 | dispatcher 20 | / 21 | 22 | -------------------------------------------------------------------------------- /mybatis-ext-simple/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | pom 7 | 8 | 9 | mybatis-ext-simple-springboot 10 | mybatis-ext-simple-springmvc 11 | mybatis-ext-simple-java 12 | 13 | 14 | tech.wetech.mybatis.simple 15 | mybatis-ext-simple 16 | 1.6.9 17 | 18 | 19 | true 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mybatis-ext-parent 7 | tech.wetech.mybatis 8 | 1.6.9 9 | ../mybatis-ext-parent 10 | 11 | 4.0.0 12 | 13 | mybatis-ext-spring-boot-autoconfigure 14 | 1.6.9 15 | 16 | 17 | 2.2.4.RELEASE 18 | 2.0.3 19 | 1.2.0 20 | 2.1.0 21 | 1.0.1 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-autoconfigure 28 | 29 | 30 | tech.wetech.mybatis 31 | mybatis-ext-spring 32 | 1.6.9 33 | true 34 | 35 | 36 | tech.wetech.mybatis 37 | mybatis-ext-core 38 | 1.6.9 39 | 40 | 41 | 42 | org.mybatis.scripting 43 | mybatis-freemarker 44 | ${mybatis-freemarker.version} 45 | 46 | 47 | mybatis 48 | org.mybatis 49 | 50 | 51 | true 52 | 53 | 54 | org.mybatis.scripting 55 | mybatis-velocity 56 | ${mybatis-velocity.version} 57 | 58 | 59 | mybatis 60 | org.mybatis 61 | 62 | 63 | true 64 | 65 | 66 | org.mybatis.scripting 67 | mybatis-thymeleaf 68 | ${mybatis-thymeleaf.version} 69 | true 70 | 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-configuration-processor 76 | true 77 | 78 | 79 | 80 | 81 | 82 | mysql 83 | mysql-connector-java 84 | 8.0.16 85 | test 86 | 87 | 88 | 89 | org.springframework.boot 90 | spring-boot-starter-jdbc 91 | test 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-starter-test 96 | test 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | org.springframework.boot 105 | spring-boot-dependencies 106 | ${spring-boot.version} 107 | pom 108 | import 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/main/java/tech/wetech/mybatis/spring/boot/autoconfigure/ConfigurationCustomizer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2019 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package tech.wetech.mybatis.spring.boot.autoconfigure; 17 | 18 | import org.apache.ibatis.session.Configuration; 19 | 20 | /** 21 | * Callback interface that can be customized a {@link Configuration} object generated on auto-configuration. 22 | * 23 | * @author Kazuki Shimizu 24 | * @since 1.2.1 25 | */ 26 | @FunctionalInterface 27 | public interface ConfigurationCustomizer { 28 | 29 | /** 30 | * Customize the given a {@link Configuration} object. 31 | * 32 | * @param configuration 33 | * the configuration object to customize 34 | */ 35 | void customize(Configuration configuration); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/main/java/tech/wetech/mybatis/spring/boot/autoconfigure/MybatisLanguageDriverAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2019 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package tech.wetech.mybatis.spring.boot.autoconfigure; 17 | 18 | import org.apache.ibatis.scripting.LanguageDriver; 19 | import org.mybatis.scripting.freemarker.FreeMarkerLanguageDriver; 20 | import org.mybatis.scripting.freemarker.FreeMarkerLanguageDriverConfig; 21 | import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriver; 22 | import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig; 23 | import org.mybatis.scripting.velocity.VelocityLanguageDriver; 24 | import org.mybatis.scripting.velocity.VelocityLanguageDriverConfig; 25 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 27 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 28 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; 29 | import org.springframework.boot.context.properties.ConfigurationProperties; 30 | import org.springframework.context.annotation.Bean; 31 | import org.springframework.context.annotation.Configuration; 32 | 33 | /** 34 | * {@link EnableAutoConfiguration Auto-Configuration} for MyBatis's scripting language drivers. 35 | * 36 | * @author Kazuki Shimizu 37 | * @since 2.1.0 38 | */ 39 | @Configuration 40 | @ConditionalOnClass(LanguageDriver.class) 41 | public class MybatisLanguageDriverAutoConfiguration { 42 | 43 | private static final String CONFIGURATION_PROPERTY_PREFIX = "mybatis.scripting-language-driver"; 44 | 45 | /** 46 | * Configuration class for mybatis-freemarker 1.1.x or under. 47 | */ 48 | @Configuration 49 | @ConditionalOnClass(FreeMarkerLanguageDriver.class) 50 | @ConditionalOnMissingClass("org.mybatis.scripting.freemarker.FreeMarkerLanguageDriverConfig") 51 | public static class LegacyFreeMarkerConfiguration { 52 | @Bean 53 | @ConditionalOnMissingBean 54 | FreeMarkerLanguageDriver freeMarkerLanguageDriver() { 55 | return new FreeMarkerLanguageDriver(); 56 | } 57 | } 58 | 59 | /** 60 | * Configuration class for mybatis-freemarker 1.2.x or above. 61 | */ 62 | @Configuration 63 | @ConditionalOnClass({FreeMarkerLanguageDriver.class, FreeMarkerLanguageDriverConfig.class}) 64 | public static class FreeMarkerConfiguration { 65 | @Bean 66 | @ConditionalOnMissingBean 67 | FreeMarkerLanguageDriver freeMarkerLanguageDriver(FreeMarkerLanguageDriverConfig config) { 68 | return new FreeMarkerLanguageDriver(config); 69 | } 70 | 71 | @Bean 72 | @ConditionalOnMissingBean 73 | @ConfigurationProperties(CONFIGURATION_PROPERTY_PREFIX + ".freemarker") 74 | public FreeMarkerLanguageDriverConfig freeMarkerLanguageDriverConfig() { 75 | return FreeMarkerLanguageDriverConfig.newInstance(); 76 | } 77 | } 78 | 79 | /** 80 | * Configuration class for mybatis-velocity 2.0 or under. 81 | */ 82 | @Configuration 83 | @ConditionalOnClass(org.mybatis.scripting.velocity.Driver.class) 84 | @ConditionalOnMissingClass("org.mybatis.scripting.velocity.VelocityLanguageDriverConfig") 85 | @SuppressWarnings("deprecation") 86 | public static class LegacyVelocityConfiguration { 87 | @Bean 88 | @ConditionalOnMissingBean 89 | org.mybatis.scripting.velocity.Driver velocityLanguageDriver() { 90 | return new org.mybatis.scripting.velocity.Driver(); 91 | } 92 | } 93 | 94 | /** 95 | * Configuration class for mybatis-velocity 2.1.x or above. 96 | */ 97 | @Configuration 98 | @ConditionalOnClass({VelocityLanguageDriver.class, VelocityLanguageDriverConfig.class}) 99 | public static class VelocityConfiguration { 100 | @Bean 101 | @ConditionalOnMissingBean 102 | VelocityLanguageDriver velocityLanguageDriver(VelocityLanguageDriverConfig config) { 103 | return new VelocityLanguageDriver(config); 104 | } 105 | 106 | @Bean 107 | @ConditionalOnMissingBean 108 | @ConfigurationProperties(CONFIGURATION_PROPERTY_PREFIX + ".velocity") 109 | public VelocityLanguageDriverConfig velocityLanguageDriverConfig() { 110 | return VelocityLanguageDriverConfig.newInstance(); 111 | } 112 | } 113 | 114 | @Configuration 115 | @ConditionalOnClass(ThymeleafLanguageDriver.class) 116 | public static class ThymeleafConfiguration { 117 | @Bean 118 | @ConditionalOnMissingBean 119 | ThymeleafLanguageDriver thymeleafLanguageDriver(ThymeleafLanguageDriverConfig config) { 120 | return new ThymeleafLanguageDriver(config); 121 | } 122 | 123 | @Bean 124 | @ConditionalOnMissingBean 125 | @ConfigurationProperties(CONFIGURATION_PROPERTY_PREFIX + ".thymeleaf") 126 | public ThymeleafLanguageDriverConfig thymeleafLanguageDriverConfig() { 127 | return ThymeleafLanguageDriverConfig.newInstance(); 128 | } 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/main/java/tech/wetech/mybatis/spring/boot/autoconfigure/SpringBootVFS.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2019 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package tech.wetech.mybatis.spring.boot.autoconfigure; 17 | 18 | import org.apache.ibatis.io.VFS; 19 | import org.springframework.core.io.Resource; 20 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 21 | import org.springframework.core.io.support.ResourcePatternResolver; 22 | 23 | import java.io.IOException; 24 | import java.io.UncheckedIOException; 25 | import java.net.URL; 26 | import java.util.List; 27 | import java.util.stream.Collectors; 28 | import java.util.stream.Stream; 29 | 30 | /** 31 | * @author Hans Westerbeek 32 | * @author Eddú Meléndez 33 | * @author Kazuki Shimizu 34 | */ 35 | public class SpringBootVFS extends VFS { 36 | 37 | private final ResourcePatternResolver resourceResolver; 38 | 39 | public SpringBootVFS() { 40 | this.resourceResolver = new PathMatchingResourcePatternResolver(getClass().getClassLoader()); 41 | } 42 | 43 | @Override 44 | public boolean isValid() { 45 | return true; 46 | } 47 | 48 | @Override 49 | protected List list(URL url, String path) throws IOException { 50 | String urlString = url.toString(); 51 | String baseUrlString = urlString.endsWith("/") ? urlString : urlString.concat("/"); 52 | Resource[] resources = resourceResolver.getResources(baseUrlString + "**/*.class"); 53 | return Stream.of(resources).map(resource -> preserveSubpackageName(baseUrlString, resource, path)) 54 | .collect(Collectors.toList()); 55 | } 56 | 57 | private static String preserveSubpackageName(final String baseUrlString, final Resource resource, 58 | final String rootPath) { 59 | try { 60 | return rootPath + (rootPath.endsWith("/") ? "" : "/") 61 | + resource.getURL().toString().substring(baseUrlString.length()); 62 | } catch (IOException e) { 63 | throw new UncheckedIOException(e); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/main/java/tech/wetech/mybatis/spring/boot/autoconfigure/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @author Eddú Meléndez 17 | */ 18 | /** 19 | * @author Eddú Meléndez 20 | */ 21 | package tech.wetech.mybatis.spring.boot.autoconfigure; 22 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": [ 3 | { 4 | "sourceType": "org.apache.ibatis.session.Configuration", 5 | "defaultValue": "org.apache.ibatis.scripting.xmltags.XMLLanguageDriver", 6 | "name": "mybatis.configuration.default-scripting-language", 7 | "description": "A default LanguageDriver class.", 8 | "type": "java.lang.Class", 9 | "deprecation": { 10 | "reason": "Because when this configuration property is used, there is case that custom language driver cannot be registered correctly.", 11 | "replacement": "mybatis.default-scripting-language-driver" 12 | } 13 | }, 14 | { 15 | "sourceType": "org.apache.ibatis.session.Configuration", 16 | "defaultValue": "org.apache.ibatis.type.EnumTypeHandler", 17 | "name": "mybatis.configuration.default-enum-type-handler", 18 | "description": "A default TypeHandler class for Enum.", 19 | "type": "java.lang.Class" 20 | }, 21 | { 22 | "defaultValue": false, 23 | "name": "mybatis.lazy-initialization", 24 | "description": "Set whether enable lazy initialization for mapper bean.", 25 | "type": "java.lang.Boolean" 26 | }, 27 | { 28 | "name": "mybatis.scripting-language-driver.velocity.userdirective", 29 | "deprecation": { 30 | "level": "error", 31 | "reason": "The 'userdirective' is deprecated since Velocity 2.x. This property defined for keeping backward compatibility with older velocity version.", 32 | "replacement": "mybatis.scripting-language-driver.velocity.velocity-settings.runtime.custom_directives" 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | # Auto Configure 2 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 3 | tech.wetech.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\ 4 | tech.wetech.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 5 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/java/tech/wetech/mybatis/MybatisExtSpringBootApplication.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | @MapperScan(basePackages = "tech.wetech.mybatis.mapper") 8 | public class MybatisExtSpringBootApplication { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/java/tech/wetech/mybatis/MybatisExtSpringBootTests.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | import tech.wetech.mybatis.domain.Page; 11 | import tech.wetech.mybatis.entity.User; 12 | import tech.wetech.mybatis.example.Example; 13 | import tech.wetech.mybatis.mapper.UserMapper; 14 | 15 | import java.util.Arrays; 16 | import java.util.Date; 17 | import java.util.List; 18 | 19 | @RunWith(SpringRunner.class) 20 | @SpringBootTest 21 | public class MybatisExtSpringBootTests { 22 | 23 | @Autowired 24 | private UserMapper mapper; 25 | 26 | private final Logger log = LoggerFactory.getLogger(MybatisExtSpringBootTests.class); 27 | 28 | @Test 29 | public void testSelectAll() { 30 | log.info("log: {}", mapper.selectAll()); 31 | } 32 | 33 | @Test 34 | public void testSelectByPrimaryKey() { 35 | User user = mapper.selectByPrimaryKey(1); 36 | log.info("selectByPrimaryKey result: {}", user); 37 | } 38 | 39 | @Test 40 | public void testSelectById() { 41 | User user = mapper.selectById(1); 42 | log.info("selectById result: {}", user); 43 | } 44 | 45 | @Test 46 | public void testSelectByPrimaryKeyWrap() { 47 | User user = mapper.selectByPrimaryKeyWithOptional(1).orElseThrow(() -> new RuntimeException("未查到数据")); 48 | log.info("selectByPrimaryKey result: {}", user); 49 | } 50 | 51 | @Test 52 | public void testSelectByExample() { 53 | Example example = Example.of(User.class); 54 | 55 | example.createCriteria() 56 | .andEqualTo(User::getId, 1) 57 | .orEqualTo(User::getUsername, "张三") 58 | .orNotLike(User::getAvatar, "aaa") 59 | .orIsNull(User::getBirthday) 60 | .orBetween(User::getRegisterTime, new Date(), new Date()) 61 | .orIn(User::getMobile, Arrays.asList(111, "aaa", 222)) 62 | .andLike(User::getAvatar, "selectOne * from t_user"); 63 | 64 | log.info("example:{}", example); 65 | example.setDistinct(true); 66 | List users = mapper.selectByExample(example); 67 | log.info("selectByExample result: {}", users); 68 | } 69 | 70 | 71 | @Test 72 | public void testCountByExample() { 73 | Example example = Example.of(User.class); 74 | 75 | example.createCriteria() 76 | .andEqualTo(User::getId, 1) 77 | .orEqualTo(User::getUsername, "张三") 78 | .orNotLike(User::getAvatar, "aaa") 79 | .orIsNull(User::getBirthday) 80 | .orBetween(User::getRegisterTime, new Date(), new Date()) 81 | .orIn(User::getMobile, Arrays.asList(111, "aaa", 222)) 82 | .andLike(User::getAvatar, "selectOne * from t_user"); 83 | 84 | log.info("example:{}", example); 85 | Integer rows = mapper.countByExample(example); 86 | log.info("countByExample result: {}", rows); 87 | } 88 | 89 | @Test 90 | public void testCreateExample() { 91 | User user = mapper.createExample() 92 | .setDistinct(true) 93 | .setSelects(User::getId, User::getBirthday, User::getRegisterTime) 94 | .setOrderByClause("id asc,register_time desc") 95 | .createCriteria() 96 | .andEqualTo(User::getId, 1) 97 | .selectOneWithOptional() 98 | .orElseThrow(() -> new RuntimeException("数据不存在")); 99 | log.info("createExample result: {}", user); 100 | } 101 | 102 | @Test 103 | public void testSelectAllWithThreadContext() { 104 | Page users = (Page) mapper.selectAll(); 105 | log.info("testSelectAllWithThreadContext result: {}", users); 106 | } 107 | 108 | @Test 109 | public void testSelectUserWithPage() { 110 | Page page = new Page(1, 2, true); 111 | List users = mapper.selectUserWithPage(page); 112 | log.info("testSelectUserWithPage result: {}", users); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/java/tech/wetech/mybatis/entity/User.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Id; 5 | import javax.persistence.Table; 6 | import java.util.Date; 7 | 8 | @Table(name = "weshop_user") 9 | public class User { 10 | @Id 11 | private Integer id; 12 | 13 | private String username; 14 | 15 | private String password; 16 | 17 | @Column(name = "gender") 18 | private String gender; 19 | 20 | private Date birthday; 21 | 22 | @Column(name = "register_time") 23 | private Date registerTime; 24 | 25 | @Column(name = "last_login_time") 26 | private Date lastLoginTime; 27 | 28 | @Column(name = "last_login_ip") 29 | private String lastLoginIp; 30 | 31 | @Column(name = "user_level_id") 32 | private Byte userLevelId; 33 | 34 | private String nickname; 35 | 36 | private String mobile; 37 | 38 | @Column(name = "register_ip") 39 | private String registerIp; 40 | 41 | private String avatar; 42 | 43 | @Column(name = "wechat_open_id") 44 | private String wechatOpenId; 45 | 46 | public Integer getId() { 47 | return id; 48 | } 49 | 50 | public User setId(Integer id) { 51 | this.id = id; 52 | return this; 53 | } 54 | 55 | public String getUsername() { 56 | return username; 57 | } 58 | 59 | public User setUsername(String username) { 60 | this.username = username; 61 | return this; 62 | } 63 | 64 | public String getPassword() { 65 | return password; 66 | } 67 | 68 | public User setPassword(String password) { 69 | this.password = password; 70 | return this; 71 | } 72 | 73 | public String getGender() { 74 | return gender; 75 | } 76 | 77 | public User setGender(String gender) { 78 | this.gender = gender; 79 | return this; 80 | } 81 | 82 | public Date getBirthday() { 83 | return birthday; 84 | } 85 | 86 | public User setBirthday(Date birthday) { 87 | this.birthday = birthday; 88 | return this; 89 | } 90 | 91 | public Date getRegisterTime() { 92 | return registerTime; 93 | } 94 | 95 | public User setRegisterTime(Date registerTime) { 96 | this.registerTime = registerTime; 97 | return this; 98 | } 99 | 100 | public Date getLastLoginTime() { 101 | return lastLoginTime; 102 | } 103 | 104 | public User setLastLoginTime(Date lastLoginTime) { 105 | this.lastLoginTime = lastLoginTime; 106 | return this; 107 | } 108 | 109 | public String getLastLoginIp() { 110 | return lastLoginIp; 111 | } 112 | 113 | public User setLastLoginIp(String lastLoginIp) { 114 | this.lastLoginIp = lastLoginIp; 115 | return this; 116 | } 117 | 118 | public Byte getUserLevelId() { 119 | return userLevelId; 120 | } 121 | 122 | public User setUserLevelId(Byte userLevelId) { 123 | this.userLevelId = userLevelId; 124 | return this; 125 | } 126 | 127 | public String getNickname() { 128 | return nickname; 129 | } 130 | 131 | public User setNickname(String nickname) { 132 | this.nickname = nickname; 133 | return this; 134 | } 135 | 136 | public String getMobile() { 137 | return mobile; 138 | } 139 | 140 | public User setMobile(String mobile) { 141 | this.mobile = mobile; 142 | return this; 143 | } 144 | 145 | public String getRegisterIp() { 146 | return registerIp; 147 | } 148 | 149 | public User setRegisterIp(String registerIp) { 150 | this.registerIp = registerIp; 151 | return this; 152 | } 153 | 154 | public String getAvatar() { 155 | return avatar; 156 | } 157 | 158 | public User setAvatar(String avatar) { 159 | this.avatar = avatar; 160 | return this; 161 | } 162 | 163 | public String getWechatOpenId() { 164 | return wechatOpenId; 165 | } 166 | 167 | public User setWechatOpenId(String wechatOpenId) { 168 | this.wechatOpenId = wechatOpenId; 169 | return this; 170 | } 171 | 172 | @Override 173 | public String toString() { 174 | return "User{" + 175 | "id=" + id + 176 | ", username='" + username + '\'' + 177 | ", password='" + password + '\'' + 178 | ", gender='" + gender + '\'' + 179 | ", birthday=" + birthday + 180 | ", registerTime=" + registerTime + 181 | ", lastLoginTime=" + lastLoginTime + 182 | ", lastLoginIp='" + lastLoginIp + '\'' + 183 | ", userLevelId=" + userLevelId + 184 | ", nickname='" + nickname + '\'' + 185 | ", mobile='" + mobile + '\'' + 186 | ", registerIp='" + registerIp + '\'' + 187 | ", avatar='" + avatar + '\'' + 188 | ", wechatOpenId='" + wechatOpenId + '\'' + 189 | '}'; 190 | } 191 | } -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/java/tech/wetech/mybatis/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.mapper; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import org.apache.ibatis.annotations.Update; 5 | import tech.wetech.mybatis.domain.Page; 6 | import tech.wetech.mybatis.entity.User; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public interface UserMapper extends BaseMapper { 12 | 13 | // @Select("select * from weshop_user") 14 | List> selectAllUser(); 15 | 16 | @Select("select * from weshop_user") 17 | List selectAllUserWithAnnotation(); 18 | 19 | @Select("select * from weshop_user where id=#{id}") 20 | User selectById(Integer id); 21 | 22 | @Update("update weshop_user set username='dddd' where id=#{id}") 23 | int updateById(Integer id); 24 | 25 | @Select("select count(*) from weshop_user where id=#{id}") 26 | Boolean existById(Integer id); 27 | 28 | @Select("select * from weshop_user") 29 | List selectUserWithPage(Page page); 30 | } 31 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/java/tech/wetech/mybatis/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=${driver} 2 | spring.datasource.url=${url} 3 | spring.datasource.username=${username} 4 | spring.datasource.password=${password} 5 | mybatis.mapper-locations=classpath:tech.wetech.mybatis.mapper/*Mapper.xml -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `weshop_user` VALUES (1, 'aaa', '2323', 2, '2018-11-23', '2018-11-17 11:54:56', '2018-11-17 11:54:56', '127.0.0.1', 1, '222', '18054071681', '127.0.0.1', '', 'dssdsdsd'); 2 | INSERT INTO `weshop_user` VALUES (2, 'bbb', '22332', 1, '1936-07-17', '2018-11-17 16:02:05', '2018-11-17 16:02:05', '', 1, 'eee', '18054071681', '123232', '1212', '32323'); -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-autoconfigure/src/test/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for weshop_user 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS `weshop_user`; 5 | CREATE TABLE `weshop_user` ( 6 | `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 7 | `username` varchar(60) NOT NULL DEFAULT '', 8 | `password` varchar(32) NOT NULL DEFAULT '', 9 | `gender` tinyint(2) unsigned DEFAULT 0, 10 | `birthday` date DEFAULT NULL, 11 | `register_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 12 | `last_login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 13 | `last_login_ip` varchar(15) NOT NULL DEFAULT '', 14 | `user_level_id` tinyint(3) unsigned NOT NULL DEFAULT '0', 15 | `nickname` varchar(60) NOT NULL DEFAULT '', 16 | `mobile` varchar(20) NOT NULL, 17 | `register_ip` varchar(45) NOT NULL DEFAULT '', 18 | `avatar` varchar(255) NOT NULL DEFAULT '', 19 | `wechat_open_id` varchar(50) NOT NULL DEFAULT '', 20 | PRIMARY KEY (`id`), 21 | UNIQUE KEY `user_name` (`username`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -------------------------------------------------------------------------------- /mybatis-ext-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mybatis-ext-parent 7 | tech.wetech.mybatis 8 | 1.6.9 9 | ../mybatis-ext-parent 10 | 11 | 4.0.0 12 | 13 | mybatis-ext-spring-boot-starter 14 | 1.6.9 15 | 16 | 17 | 2.3.2.RELEASE 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-jdbc 28 | 29 | 30 | tech.wetech.mybatis 31 | mybatis-ext-spring 32 | 1.6.9 33 | 34 | 35 | tech.wetech.mybatis 36 | mybatis-ext-core 37 | 1.6.9 38 | 39 | 40 | tech.wetech.mybatis 41 | mybatis-ext-spring-boot-autoconfigure 42 | 1.6.9 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-dependencies 52 | ${spring-boot.version} 53 | pom 54 | import 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /mybatis-ext-spring/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mybatis-ext-parent 7 | tech.wetech.mybatis 8 | 1.6.9 9 | ../mybatis-ext-parent 10 | 11 | 4.0.0 12 | 13 | mybatis-ext-spring 14 | 1.6.9 15 | 16 | 17 | 5.1.8.RELEASE 18 | 2.0.3 19 | 20 | 21 | 22 | 23 | tech.wetech.mybatis 24 | mybatis-ext-core 25 | 1.6.9 26 | 27 | 28 | org.mybatis 29 | mybatis-spring 30 | ${mybatis-spring.version} 31 | 32 | 33 | org.springframework 34 | spring-context 35 | ${spring.version} 36 | provided 37 | 38 | 39 | org.springframework 40 | spring-jdbc 41 | ${spring.version} 42 | provided 43 | 44 | 45 | 46 | org.springframework 47 | spring-test 48 | ${spring.version} 49 | test 50 | 51 | 52 | org.slf4j 53 | slf4j-simple 54 | 1.6.1 55 | test 56 | 57 | 58 | org.slf4j 59 | slf4j-log4j12 60 | 1.6.1 61 | test 62 | 63 | 64 | mysql 65 | mysql-connector-java 66 | 8.0.16 67 | test 68 | 69 | 70 | junit 71 | junit 72 | 4.13.1 73 | test 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/MybatisExtSpringTests.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.spring; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | import tech.wetech.mybatis.domain.Page; 11 | import tech.wetech.mybatis.example.Example; 12 | import tech.wetech.mybatis.spring.entity.User; 13 | import tech.wetech.mybatis.spring.mapper.UserMapper; 14 | 15 | import java.util.Arrays; 16 | import java.util.Date; 17 | import java.util.List; 18 | 19 | @RunWith(SpringJUnit4ClassRunner.class) 20 | @ContextConfiguration("/beans2.xml") 21 | public class MybatisExtSpringTests { 22 | 23 | private final Logger log = LoggerFactory.getLogger(MybatisSpringTests.class); 24 | 25 | @Autowired 26 | private UserMapper mapper; 27 | 28 | @Test 29 | public void testSelectAll() { 30 | log.info("log: {}", mapper.selectAll()); 31 | } 32 | 33 | @Test 34 | public void testSelectByPrimaryKey() { 35 | User user = mapper.selectByPrimaryKey(1); 36 | log.info("selectByPrimaryKey result: {}", user); 37 | } 38 | 39 | @Test 40 | public void testSelectById() { 41 | User user = mapper.selectById(1); 42 | log.info("selectById result: {}", user); 43 | } 44 | 45 | @Test 46 | public void testSelectByPrimaryKeyWrap() { 47 | User user = mapper.selectByPrimaryKeyWithOptional(1).orElseThrow(() -> new RuntimeException("未查到数据")); 48 | log.info("selectByPrimaryKey result: {}", user); 49 | } 50 | 51 | @Test 52 | public void testSelectByExample() { 53 | Example example = Example.of(User.class); 54 | 55 | example.createCriteria() 56 | .andEqualTo(User::getId, 1) 57 | .orEqualTo(User::getUsername, "张三") 58 | .orNotLike(User::getAvatar, "aaa") 59 | .orIsNull(User::getBirthday) 60 | .orBetween(User::getRegisterTime, new Date(), new Date()) 61 | .orIn(User::getMobile, Arrays.asList(111, "aaa", 222)) 62 | .andLike(User::getAvatar, "select * from t_user"); 63 | 64 | log.info("example:{}", example); 65 | example.setDistinct(true); 66 | List users = mapper.selectByExample(example); 67 | log.info("selectByExample result: {}", users); 68 | } 69 | 70 | 71 | @Test 72 | public void testCountByExample() { 73 | Example example = Example.of(User.class); 74 | 75 | example.createCriteria() 76 | .andEqualTo(User::getId, 1) 77 | .orEqualTo(User::getUsername, "张三") 78 | .orNotLike(User::getAvatar, "aaa") 79 | .orIsNull(User::getBirthday) 80 | .orBetween(User::getRegisterTime, new Date(), new Date()) 81 | .orIn(User::getMobile, Arrays.asList(111, "aaa", 222)) 82 | .andLike(User::getAvatar, "select * from t_user"); 83 | 84 | log.info("example:{}", example); 85 | Integer rows = mapper.countByExample(example); 86 | log.info("countByExample result: {}", rows); 87 | } 88 | 89 | @Test 90 | public void testCreateExample() { 91 | User user = mapper.createExample() 92 | .setDistinct(true) 93 | .setSelects(User::getId, User::getBirthday, User::getRegisterTime) 94 | .setOrderByClause("id asc,register_time desc") 95 | .createCriteria() 96 | .andEqualTo(User::getId, 1) 97 | .selectOneWithOptional() 98 | .orElseThrow(() -> new RuntimeException("数据不存在")); 99 | log.info("createExample result: {}", user); 100 | } 101 | 102 | @Test 103 | public void testCustomMapper() { 104 | List users = mapper.selectByUsername("张三"); 105 | log.info("customMapper result: {}", users); 106 | } 107 | 108 | @Test 109 | public void testSelectAllWithThreadContext() { 110 | Page users = (Page) mapper.selectAll(); 111 | log.info("testSelectAllWithThreadContext result: {}", users); 112 | } 113 | 114 | @Test 115 | public void testSelectUserWithPage() { 116 | Page page = new Page(1, 2, true); 117 | List users = mapper.selectUserWithPage(page); 118 | log.info("testSelectUserWithPage result: {}", users); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/MybatisSpringTests.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.spring; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | import tech.wetech.mybatis.spring.mapper.UserMapper; 11 | 12 | @RunWith(SpringJUnit4ClassRunner.class) 13 | @ContextConfiguration("/beans.xml") 14 | public class MybatisSpringTests { 15 | 16 | private final Logger log = LoggerFactory.getLogger(MybatisSpringTests.class); 17 | 18 | @Autowired 19 | private UserMapper mapper; 20 | 21 | @Test 22 | public void testSimple() { 23 | log.info("log: {}", mapper.selectAllUser()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/custom/CustomMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.spring.custom; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import tech.wetech.mybatis.mapper.BaseMapper; 5 | 6 | import java.util.List; 7 | 8 | public interface CustomMapper extends BaseMapper { 9 | @Select("select * from weshop_user where username=#{username}") 10 | List selectByUsername(String username); 11 | } 12 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/custom/SelectUserByUserNameMethod.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.spring.custom; 2 | 3 | import org.apache.ibatis.mapping.SqlCommandType; 4 | import tech.wetech.mybatis.ExtConfiguration; 5 | import tech.wetech.mybatis.builder.EntityMapping; 6 | 7 | public class SelectUserByUserNameMethod { 8 | 9 | public String script(ExtConfiguration extConfiguration, EntityMapping entityMapping) { 10 | StringBuilder builder = new StringBuilder(); 11 | builder.append(""); 14 | return builder.toString(); 15 | } 16 | 17 | public String methodName() { 18 | return null; 19 | } 20 | 21 | public SqlCommandType sqlCommandType() { 22 | return null; 23 | } 24 | 25 | public Class resultType() { 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/entity/User.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.spring.entity; 2 | 3 | import javax.persistence.*; 4 | import java.util.Date; 5 | 6 | @Table(name = "weshop_user") 7 | public class User { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | private Integer id; 11 | 12 | private String username; 13 | 14 | private String password; 15 | 16 | @Column(name = "gender") 17 | private String gender; 18 | 19 | private Date birthday; 20 | 21 | @Column(name = "register_time") 22 | private Date registerTime; 23 | 24 | @Column(name = "last_login_time") 25 | private Date lastLoginTime; 26 | 27 | @Column(name = "last_login_ip") 28 | private String lastLoginIp; 29 | 30 | @Column(name = "user_level_id") 31 | private Byte userLevelId; 32 | 33 | private String nickname; 34 | 35 | private String mobile; 36 | 37 | @Column(name = "register_ip") 38 | private String registerIp; 39 | 40 | private String avatar; 41 | 42 | @Column(name = "wechat_open_id") 43 | private String wechatOpenId; 44 | 45 | public Integer getId() { 46 | return id; 47 | } 48 | 49 | public User setId(Integer id) { 50 | this.id = id; 51 | return this; 52 | } 53 | 54 | public String getUsername() { 55 | return username; 56 | } 57 | 58 | public User setUsername(String username) { 59 | this.username = username; 60 | return this; 61 | } 62 | 63 | public String getPassword() { 64 | return password; 65 | } 66 | 67 | public User setPassword(String password) { 68 | this.password = password; 69 | return this; 70 | } 71 | 72 | public String getGender() { 73 | return gender; 74 | } 75 | 76 | public User setGender(String gender) { 77 | this.gender = gender; 78 | return this; 79 | } 80 | 81 | public Date getBirthday() { 82 | return birthday; 83 | } 84 | 85 | public User setBirthday(Date birthday) { 86 | this.birthday = birthday; 87 | return this; 88 | } 89 | 90 | public Date getRegisterTime() { 91 | return registerTime; 92 | } 93 | 94 | public User setRegisterTime(Date registerTime) { 95 | this.registerTime = registerTime; 96 | return this; 97 | } 98 | 99 | public Date getLastLoginTime() { 100 | return lastLoginTime; 101 | } 102 | 103 | public User setLastLoginTime(Date lastLoginTime) { 104 | this.lastLoginTime = lastLoginTime; 105 | return this; 106 | } 107 | 108 | public String getLastLoginIp() { 109 | return lastLoginIp; 110 | } 111 | 112 | public User setLastLoginIp(String lastLoginIp) { 113 | this.lastLoginIp = lastLoginIp; 114 | return this; 115 | } 116 | 117 | public Byte getUserLevelId() { 118 | return userLevelId; 119 | } 120 | 121 | public User setUserLevelId(Byte userLevelId) { 122 | this.userLevelId = userLevelId; 123 | return this; 124 | } 125 | 126 | public String getNickname() { 127 | return nickname; 128 | } 129 | 130 | public User setNickname(String nickname) { 131 | this.nickname = nickname; 132 | return this; 133 | } 134 | 135 | public String getMobile() { 136 | return mobile; 137 | } 138 | 139 | public User setMobile(String mobile) { 140 | this.mobile = mobile; 141 | return this; 142 | } 143 | 144 | public String getRegisterIp() { 145 | return registerIp; 146 | } 147 | 148 | public User setRegisterIp(String registerIp) { 149 | this.registerIp = registerIp; 150 | return this; 151 | } 152 | 153 | public String getAvatar() { 154 | return avatar; 155 | } 156 | 157 | public User setAvatar(String avatar) { 158 | this.avatar = avatar; 159 | return this; 160 | } 161 | 162 | public String getWechatOpenId() { 163 | return wechatOpenId; 164 | } 165 | 166 | public User setWechatOpenId(String wechatOpenId) { 167 | this.wechatOpenId = wechatOpenId; 168 | return this; 169 | } 170 | 171 | @Override 172 | public String toString() { 173 | return "User{" + 174 | "id=" + id + 175 | ", username='" + username + '\'' + 176 | ", password='" + password + '\'' + 177 | ", gender='" + gender + '\'' + 178 | ", birthday=" + birthday + 179 | ", registerTime=" + registerTime + 180 | ", lastLoginTime=" + lastLoginTime + 181 | ", lastLoginIp='" + lastLoginIp + '\'' + 182 | ", userLevelId=" + userLevelId + 183 | ", nickname='" + nickname + '\'' + 184 | ", mobile='" + mobile + '\'' + 185 | ", registerIp='" + registerIp + '\'' + 186 | ", avatar='" + avatar + '\'' + 187 | ", wechatOpenId='" + wechatOpenId + '\'' + 188 | '}'; 189 | } 190 | } -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package tech.wetech.mybatis.spring.mapper; 2 | 3 | import org.apache.ibatis.annotations.Select; 4 | import org.apache.ibatis.annotations.Update; 5 | import org.springframework.stereotype.Component; 6 | import tech.wetech.mybatis.domain.Page; 7 | import tech.wetech.mybatis.spring.custom.CustomMapper; 8 | import tech.wetech.mybatis.spring.entity.User; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | @Component 14 | public interface UserMapper extends CustomMapper { 15 | 16 | // @Select("select * from weshop_user") 17 | List> selectAllUser(); 18 | 19 | @Select("select * from weshop_user") 20 | List selectAllUserWithAnnotation(); 21 | 22 | @Select("select * from weshop_user where id=#{id}") 23 | User selectById(Integer id); 24 | 25 | @Update("update weshop_user set username='dddd' where id=#{id}") 26 | int updateById(Integer id); 27 | 28 | @Select("select count(*) from weshop_user where id=#{id}") 29 | Boolean existById(Integer id); 30 | 31 | @Select("select * from weshop_user") 32 | List selectUserWithPage(Page page); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/java/tech/wetech/mybatis/spring/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/resources/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/resources/beans2.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `weshop_user` VALUES (1, 'aaa', '2323', 2, '2018-11-23', '2018-11-17 11:54:56', '2018-11-17 11:54:56', '127.0.0.1', 1, '222', '18054071681', '127.0.0.1', '', 'dssdsdsd'); 2 | INSERT INTO `weshop_user` VALUES (2, 'bbb', '22332', 1, '1936-07-17', '2018-11-17 16:02:05', '2018-11-17 16:02:05', '', 1, 'eee', '18054071681', '123232', '1212', '32323'); -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Global logging configuration 2 | log4j.rootLogger=DEBUG, stdout 3 | # MyBatis logging configuration... 4 | #log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 | # Console output... 6 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=[%5p] %d{yyyy-MM-dd HH:mm:ss} [%F:%L] %m %n -------------------------------------------------------------------------------- /mybatis-ext-spring/src/test/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for weshop_user 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS `weshop_user`; 5 | CREATE TABLE `weshop_user` ( 6 | `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 7 | `username` varchar(60) NOT NULL DEFAULT '', 8 | `password` varchar(32) NOT NULL DEFAULT '', 9 | `gender` tinyint(2) unsigned DEFAULT 0, 10 | `birthday` date DEFAULT NULL, 11 | `register_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 12 | `last_login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 13 | `last_login_ip` varchar(15) NOT NULL DEFAULT '', 14 | `user_level_id` tinyint(3) unsigned NOT NULL DEFAULT '0', 15 | `nickname` varchar(60) NOT NULL DEFAULT '', 16 | `mobile` varchar(20) NOT NULL, 17 | `register_ip` varchar(45) NOT NULL DEFAULT '', 18 | `avatar` varchar(255) NOT NULL DEFAULT '', 19 | `wechat_open_id` varchar(50) NOT NULL DEFAULT '', 20 | PRIMARY KEY (`id`), 21 | UNIQUE KEY `user_name` (`username`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | tech.wetech.mybatis 8 | mybatis-ext 9 | 1.6.9 10 | mybatis-ext 11 | Mybatis Extensions. 12 | https://github.com/cjbi/mybatis-ext 13 | 14 | mybatis-ext-parent 15 | mybatis-ext-core 16 | mybatis-ext-spring 17 | mybatis-ext-spring-boot-autoconfigure 18 | mybatis-ext-spring-boot-starter 19 | mybatis-ext-simple 20 | 21 | pom 22 | 23 | true 24 | 25 | 26 | 27 | --------------------------------------------------------------------------------