├── LICENSE
├── README.md
├── lit-code
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── github
│ │ └── lit
│ │ └── code
│ │ ├── CodeGeneration.java
│ │ ├── config
│ │ ├── Configuration.java
│ │ ├── ConfigurationBuilder.java
│ │ └── JdbcConfig.java
│ │ ├── context
│ │ ├── Column.java
│ │ ├── ConfigConst.java
│ │ ├── GenerationException.java
│ │ ├── Table.java
│ │ └── Task.java
│ │ ├── datebase
│ │ ├── DataBaseProvider.java
│ │ ├── DateBaseProviderFactory.java
│ │ └── MySqlProvider.java
│ │ ├── executor
│ │ └── GenerationExecutor.java
│ │ ├── parser
│ │ ├── ConfigParser.java
│ │ ├── ConstantParser.java
│ │ ├── ConverterParser.java
│ │ ├── JdbcParser.java
│ │ ├── TableParser.java
│ │ └── TasksParser.java
│ │ ├── plugin
│ │ ├── PluginExecutor.java
│ │ └── SerialVersionUIDPlugin.java
│ │ └── util
│ │ ├── DBUtils.java
│ │ └── FileUtils.java
│ └── test
│ ├── java
│ └── com
│ │ └── github
│ │ └── lit
│ │ └── code
│ │ └── Generation.java
│ └── resources
│ ├── code.json
│ └── templates
│ ├── client.vm
│ ├── mapper.vm
│ ├── model.vm
│ ├── qo.vm
│ ├── rest.vm
│ ├── service.vm
│ ├── serviceImpl.vm
│ └── xmlMapper.vm
├── lit-starters
├── lit-starter-jdbc
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── lit
│ │ │ └── starter
│ │ │ └── jdbc
│ │ │ └── JdbcSupportAutoConfiguration.java
│ │ └── resources
│ │ └── META-INF
│ │ └── spring.factories
└── pom.xml
├── lit-support
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── github
│ │ └── lit
│ │ └── support
│ │ ├── data
│ │ ├── AbstractSQL.java
│ │ ├── Condition.java
│ │ ├── Logic.java
│ │ ├── SQL.java
│ │ ├── SQLUtils.java
│ │ ├── domain
│ │ │ ├── Page.java
│ │ │ ├── PageInfo.java
│ │ │ ├── PageRequest.java
│ │ │ ├── PageUtils.java
│ │ │ ├── Pageable.java
│ │ │ ├── Sort.java
│ │ │ └── TableMetaDate.java
│ │ ├── jdbc
│ │ │ ├── AnnotationRowMapper.java
│ │ │ ├── EnableJdbcSupport.java
│ │ │ ├── JdbcRepository.java
│ │ │ ├── JdbcRepositoryImpl.java
│ │ │ └── JdbcSupportConfigure.java
│ │ └── mybatis
│ │ │ ├── BaseMapper.java
│ │ │ ├── BaseSqlProvider.java
│ │ │ ├── EnambeMybatisSupport.java
│ │ │ ├── MyBatisSupportConfigure.java
│ │ │ └── ResultMapInterceptor.java
│ │ ├── exception
│ │ ├── BizException.java
│ │ ├── ExceptionDefinition.java
│ │ ├── LitException.java
│ │ └── SysException.java
│ │ └── util
│ │ ├── ClassUtils.java
│ │ ├── DateTimeUtils.java
│ │ ├── NameUtils.java
│ │ ├── PropertyUtils.java
│ │ ├── RandomUtils.java
│ │ ├── SpelUtils.java
│ │ ├── SpringContextUtils.java
│ │ ├── TokenUtils.java
│ │ ├── UUIDUtils.java
│ │ ├── bean
│ │ ├── BeanUtils.java
│ │ └── IntrospectionCache.java
│ │ ├── lamabda
│ │ ├── SerializedFunction.java
│ │ └── SerializedLambdaUtils.java
│ │ └── secret
│ │ ├── BCrypt.java
│ │ └── EncryptUtils.java
│ └── test
│ ├── java
│ └── com
│ │ └── github
│ │ └── lit
│ │ └── support
│ │ ├── configure
│ │ └── SpringTestConfigure.java
│ │ ├── jdbc
│ │ └── JdbcRepositoryTest.java
│ │ ├── model
│ │ ├── Goods.java
│ │ ├── GoodsCondition.java
│ │ ├── ProductCondition.java
│ │ └── SignProduct.java
│ │ └── mybatis
│ │ ├── GoodsMapper.java
│ │ ├── MapperTest.java
│ │ └── MybatisConfig.java
│ └── resources
│ └── sql
│ └── init_schema.sql
└── pom.xml
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # lit 工具集合
2 |
3 | > 此工具集是工作中对一些框架的封装, 简便使用
4 |
5 | ### 内容
6 |
7 | - lit-jdbc: 对spring jdbc 的封装, 自动完成常用增删改查操作, 简便sql拼写
8 | - lit-mybatis: 对mybatis封装了BaseMapper, 方便操作
9 |
10 | ### 如何使用
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lit-code/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | lit
7 | com.github.liulus
8 | 2.5.0
9 |
10 | 4.0.0
11 |
12 | lit-code
13 |
14 |
15 |
16 | com.github.liulus
17 | lit-support
18 | ${project.version}
19 |
20 |
21 |
22 | com.google.code.gson
23 | gson
24 | 2.8.5
25 |
26 |
27 |
28 | org.apache.velocity
29 | velocity
30 | 1.7
31 |
32 |
33 |
34 | mysql
35 | mysql-connector-java
36 | test
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/CodeGeneration.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.config.ConfigurationBuilder;
5 | import com.github.lit.code.context.GenerationException;
6 | import com.github.lit.code.datebase.DataBaseProvider;
7 | import com.github.lit.code.datebase.DateBaseProviderFactory;
8 | import com.github.lit.code.executor.GenerationExecutor;
9 | import com.github.lit.code.parser.ConfigParser;
10 |
11 | import java.util.logging.Logger;
12 |
13 | /**
14 | * User : liulu
15 | * Date : 2018/2/6 15:03
16 | * version $Id: CodeGeneration.java, v 0.1 Exp $
17 | */
18 | public class CodeGeneration {
19 |
20 | private static final Logger LOGGER = Logger.getLogger(CodeGeneration.class.getName());
21 |
22 | public static void run() {
23 | run("code.json");
24 | }
25 |
26 | public static void run(String configFile) {
27 | if (configFile == null || configFile.length() == 0) {
28 | throw new GenerationException("配置文件名称不能为空");
29 | }
30 | Configuration configuration = ConfigurationBuilder.build(configFile);
31 | GenerationExecutor.execute(configuration);
32 | }
33 |
34 | public static void registerParser(ConfigParser configParser) {
35 | ConfigurationBuilder.registerParser(configParser);
36 | }
37 |
38 | public static void registerProvider(DataBaseProvider dataBaseProvider) {
39 | DateBaseProviderFactory.registerProvider(dataBaseProvider);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/config/Configuration.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.config;
2 |
3 | import com.github.lit.code.context.Table;
4 | import com.github.lit.code.context.Task;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 | import lombok.ToString;
8 |
9 | import java.math.BigDecimal;
10 | import java.sql.JDBCType;
11 | import java.util.Date;
12 | import java.util.HashMap;
13 | import java.util.Map;
14 | import java.util.concurrent.ConcurrentHashMap;
15 |
16 | /**
17 | * User : liulu
18 | * Date : 2018/2/6 16:26
19 | * version $Id: Configuration.java, v 0.1 Exp $
20 | */
21 | @Getter
22 | @Setter
23 | @ToString
24 | public class Configuration {
25 |
26 | /**
27 | * 默认的转换映射 map
28 | */
29 | private static final Map DEFAULT_CONVERT_MAP = new ConcurrentHashMap<>();
30 |
31 | /**
32 | * 常量Map
33 | */
34 | private Map constantMap = new HashMap<>();
35 |
36 | /**
37 | * jdbcType 和 javaType 转换映射 Map
38 | */
39 | private Map converterMap = new HashMap<>();
40 |
41 | /**
42 | * 任务Map
43 | */
44 | private Map taskMap = new HashMap<>();
45 |
46 | /**
47 | * jdbc连接
48 | */
49 | private JdbcConfig jdbcConfig;
50 |
51 | /**
52 | * 表配置
53 | */
54 | private Table table;
55 |
56 |
57 | static {
58 | DEFAULT_CONVERT_MAP.put(JDBCType.REAL.getName(), Float.class.getName());
59 | DEFAULT_CONVERT_MAP.put(JDBCType.DECIMAL.getName(), BigDecimal.class.getName());
60 | DEFAULT_CONVERT_MAP.put(JDBCType.NUMERIC.getName(), BigDecimal.class.getName());
61 | DEFAULT_CONVERT_MAP.put(JDBCType.CHAR.getName(), String.class.getName());
62 | DEFAULT_CONVERT_MAP.put(JDBCType.LONGVARCHAR.getName(), String.class.getName());
63 | DEFAULT_CONVERT_MAP.put(JDBCType.CLOB.getName(), String.class.getName());
64 | DEFAULT_CONVERT_MAP.put(JDBCType.BINARY.getName(), Byte.class.getName() + "[]");
65 | DEFAULT_CONVERT_MAP.put(JDBCType.VARBINARY.getName(), Byte.class.getName() + "[]");
66 | DEFAULT_CONVERT_MAP.put(JDBCType.LONGVARBINARY.getName(), Byte.class.getName() + "[]");
67 | DEFAULT_CONVERT_MAP.put(JDBCType.BLOB.getName(), Byte.class.getName() + "[]");
68 | DEFAULT_CONVERT_MAP.put(JDBCType.DATE.getName(), Date.class.getName());
69 | DEFAULT_CONVERT_MAP.put(JDBCType.TIME.getName(), Date.class.getName());
70 | DEFAULT_CONVERT_MAP.put(JDBCType.TIMESTAMP.getName(), Date.class.getName());
71 |
72 | // mySql
73 | DEFAULT_CONVERT_MAP.put("TINYTEXT", String.class.getName());
74 | DEFAULT_CONVERT_MAP.put("TEXT", String.class.getName());
75 | DEFAULT_CONVERT_MAP.put("LONGTEXT", String.class.getName());
76 | }
77 |
78 |
79 | public void addConstant(String key, String value) {
80 | constantMap.put(key, value);
81 | }
82 |
83 | public String getConstant(String key) {
84 | return constantMap.get(key);
85 | }
86 |
87 | public String getConstant(String key, String defaultValue) {
88 | String value = constantMap.get(key);
89 | if (value == null || value.length() == 0) {
90 | value = defaultValue;
91 | }
92 | return value;
93 | }
94 |
95 | public Boolean getBooleanConstant(String key) {
96 | String value = constantMap.get(key);
97 | if (value == null || value.length() == 0) {
98 | return false;
99 | }
100 | return Boolean.valueOf(value);
101 | }
102 |
103 | public Boolean getBooleanConstant(String key, Boolean defaultValue) {
104 | String value = constantMap.get(key);
105 | if (value == null || value.length() == 0) {
106 | return defaultValue;
107 | }
108 | return Boolean.valueOf(value);
109 | }
110 |
111 | public void addTask(Task task) {
112 | if (task == null) {
113 | return;
114 | }
115 | taskMap.put(task.getName(), task);
116 | }
117 |
118 | public Task getTask(String key) {
119 | return taskMap.get(key);
120 | }
121 |
122 | public void addConverter(String key, String value) {
123 | converterMap.put(key, value);
124 | }
125 |
126 | public String getConverter(String key) {
127 | String value = converterMap.get(key);
128 | if (value == null || value.isEmpty()) {
129 | value = DEFAULT_CONVERT_MAP.get(key);
130 | }
131 | return value;
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/config/ConfigurationBuilder.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.config;
2 |
3 | import com.github.lit.code.context.ConfigConst;
4 | import com.github.lit.code.context.GenerationException;
5 | import com.github.lit.code.parser.*;
6 | import com.github.lit.support.util.ClassUtils;
7 | import com.github.lit.support.util.TokenUtils;
8 | import com.google.gson.JsonElement;
9 | import com.google.gson.JsonObject;
10 | import com.google.gson.JsonParser;
11 |
12 | import java.io.InputStream;
13 | import java.io.InputStreamReader;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.logging.Logger;
18 |
19 | /**
20 | * User : liulu
21 | * Date : 2018/2/7 14:49
22 | * version $Id: ConfigurationBuilder.java, v 0.1 Exp $
23 | */
24 | public class ConfigurationBuilder {
25 |
26 | private static final Logger LOGGER = Logger.getLogger(ConfigurationBuilder.class.getName());
27 |
28 | private static final List CONFIG_PARSERS = new ArrayList<>();
29 |
30 | static {
31 | // CONFIG_PARSERS.add(new ConstantParser());
32 | CONFIG_PARSERS.add(new JdbcParser());
33 | CONFIG_PARSERS.add(new ConverterParser());
34 | CONFIG_PARSERS.add(new TableParser());
35 | CONFIG_PARSERS.add(new TasksParser());
36 | }
37 |
38 | public static Configuration build(String configFile) {
39 | if (configFile.startsWith("/")) {
40 | configFile = configFile.substring(1);
41 | }
42 | InputStream inputStream = ClassUtils.getDefaultClassLoader().getResourceAsStream(configFile);
43 | if (inputStream == null) {
44 | throw new GenerationException(String.format("未能找到配置文件 %s, 请确认该文件放在 classpath 路径下", configFile));
45 | }
46 |
47 | Configuration configuration = new Configuration();
48 | JsonElement rootElement = new JsonParser().parse(new InputStreamReader(inputStream));
49 | if (rootElement.isJsonArray()) {
50 | throw new GenerationException("配置文件不能是数组");
51 | }
52 |
53 | // 提前解析出所有的常量
54 | JsonObject constant = rootElement.getAsJsonObject().getAsJsonObject().getAsJsonObject(ConfigConst.CONSTANT);
55 | for (Map.Entry entry : constant.entrySet()) {
56 | configuration.addConstant(entry.getKey(), entry.getValue().getAsString());
57 | }
58 |
59 | // 替换 json 配置中的 ${} 占位符
60 | String rootConfigJson = TokenUtils.parseToken(configuration.getConstantMap(), rootElement.toString());
61 | JsonObject rootObject = new JsonParser().parse(rootConfigJson).getAsJsonObject();
62 |
63 | LOGGER.info("开始解析配置文件: " + configFile);
64 | for (ConfigParser configParser : CONFIG_PARSERS) {
65 | JsonElement jsonElement = rootObject.get(configParser.getConfigKey());
66 | if (jsonElement != null) {
67 | configParser.parser(configuration, jsonElement);
68 | }
69 | }
70 | LOGGER.info("完成配置文件: " + configFile + " 的解析!");
71 | return configuration;
72 | }
73 |
74 |
75 | public static void registerParser(ConfigParser configParser) {
76 | CONFIG_PARSERS.add(configParser);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/config/JdbcConfig.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.config;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import lombok.ToString;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * User : liulu
11 | * Date : 2018/2/6 16:28
12 | * version $Id: JdbcConfig.java, v 0.1 Exp $
13 | */
14 | @Getter
15 | @Setter
16 | @ToString
17 | public class JdbcConfig implements Serializable{
18 |
19 | private static final long serialVersionUID = -488479893077026027L;
20 |
21 | private String dbName;
22 |
23 | private String driverClass;
24 |
25 | private String url;
26 |
27 | private String user;
28 |
29 | private String password;
30 | }
31 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/context/Column.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.context;
2 |
3 | import com.github.lit.support.util.NameUtils;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * User : liulu
12 | * Date : 2018/2/8 11:34
13 | * version $Id: Column.java, v 0.1 Exp $
14 | */
15 | @Getter
16 | @Setter
17 | @ToString
18 | public class Column implements Serializable {
19 |
20 | private static final long serialVersionUID = 4076352228046456676L;
21 |
22 | private String name;
23 |
24 | private Integer displaySize;
25 |
26 | private Integer scale;
27 |
28 | private String comment;
29 |
30 | private Boolean primaryKey;
31 |
32 | private Boolean autoIncrement;
33 |
34 | private String jdbcType;
35 |
36 | private String javaType;
37 |
38 | private String javaClass;
39 |
40 | public String getCamelName() {
41 | return NameUtils.getCamelName(name);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/context/ConfigConst.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.context;
2 |
3 | /**
4 | * User : liulu
5 | * Date : 2018/3/6 16:36
6 | * version $Id: ConfigConst.java, v 0.1 Exp $
7 | */
8 | public interface ConfigConst {
9 |
10 | String CONSTANT = "constant";
11 |
12 | String JDBC = "jdbc";
13 |
14 | String CONVERTER = "converter";
15 |
16 | String TABLE = "table";
17 |
18 | String TASKS = "tasks";
19 |
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/context/GenerationException.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.context;
2 |
3 | /**
4 | * User : liulu
5 | * Date : 2018/2/7 14:36
6 | * version $Id: GenerationException.java, v 0.1 Exp $
7 | */
8 | public class GenerationException extends RuntimeException{
9 |
10 | private static final long serialVersionUID = 6061456844067018240L;
11 |
12 | public GenerationException() {
13 | super();
14 | }
15 |
16 | public GenerationException(String message) {
17 | super(message);
18 | }
19 |
20 | public GenerationException(String message, Throwable cause) {
21 | super(message, cause);
22 | }
23 |
24 | public GenerationException(Throwable cause) {
25 | super(cause);
26 | }
27 |
28 | protected GenerationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
29 | super(message, cause, enableSuppression, writableStackTrace);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/context/Table.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.context;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import lombok.ToString;
6 |
7 | import java.io.Serializable;
8 | import java.util.HashSet;
9 | import java.util.List;
10 | import java.util.Set;
11 |
12 | /**
13 | * User : liulu
14 | * Date : 2018/2/7 18:51
15 | * version $Id: Table.java, v 0.1 Exp $
16 | */
17 | @Getter
18 | @Setter
19 | @ToString
20 | public class Table implements Serializable {
21 |
22 | private static final long serialVersionUID = -3416826548050707151L;
23 |
24 | private String catalog;
25 |
26 | private String schema;
27 |
28 | private String quoteString;
29 |
30 | private String name;
31 |
32 | private String primaryKey;
33 |
34 | private String desc;
35 |
36 | private List columns;
37 |
38 | private List tasks;
39 |
40 |
41 | public String getFullTableName() {
42 | String result = " ";
43 | if (catalog != null && !catalog.isEmpty()) {
44 | result += catalog + ".";
45 | }
46 |
47 | if (schema != null && !schema.isEmpty()) {
48 | result += schema + ".";
49 | }
50 |
51 | return result + quoteString + name + quoteString + " ";
52 |
53 |
54 | }
55 |
56 | public Set getImportClasses() {
57 |
58 | Set importClasses = new HashSet<>();
59 |
60 | for (Column column : columns) {
61 | if (!column.getJavaClass().startsWith("java.lang")) {
62 | importClasses.add(column.getJavaClass());
63 | }
64 | }
65 |
66 | return importClasses;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/context/Task.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.context;
2 |
3 | import com.github.lit.support.util.NameUtils;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import java.io.File;
9 | import java.io.Serializable;
10 | import java.util.List;
11 | import java.util.logging.Logger;
12 |
13 | /**
14 | * User : liulu
15 | * Date : 2018/2/7 17:02
16 | * version $Id: Task.java, v 0.1 Exp $
17 | */
18 | @Getter
19 | @Setter
20 | @ToString
21 | public class Task implements Serializable {
22 |
23 | private static final Logger LOGGER = Logger.getLogger(Task.class.getName());
24 |
25 | private static final long serialVersionUID = 5454351511354251547L;
26 |
27 | private String name;
28 |
29 | private String tableName;
30 |
31 | private String generateClass;
32 |
33 | private String template;
34 |
35 | private String prefixRemove = "";
36 |
37 | private String suffixRemove = "";
38 |
39 | private String delimiter = "_";
40 |
41 | private String prefixAdd = "";
42 |
43 | private String suffixAdd = "";
44 |
45 | private String fileType = ".java";
46 |
47 | private Boolean upperCase = false;
48 |
49 | private Boolean lowerCase = false;
50 |
51 | private Boolean camel = false;
52 |
53 | private String fileSeparator = "";
54 |
55 | private String module = "";
56 |
57 | private String srcDir = "src/main/java";
58 |
59 | private String _package = "";
60 |
61 | private List plugins;
62 |
63 |
64 | public String getShortClassName() {
65 | String resultName = NameUtils.getFirstUpperName(NameUtils.getCamelName(tableName, delimiter));
66 | return prefixAdd + resultName + suffixAdd;
67 | }
68 |
69 | public String getLongClassName() {
70 | return _package + "." + getShortClassName();
71 | }
72 |
73 | public String getFirstLowerClassName() {
74 | if (prefixAdd == null || prefixAdd.isEmpty()) {
75 | return NameUtils.getCamelName(tableName) + suffixAdd;
76 | }
77 | return NameUtils.getFirstLowerName(getShortClassName());
78 | }
79 |
80 | public String getUnderLineSplitName() {
81 | return NameUtils.getLowerDelimiterName(getShortClassName(), "_");
82 | }
83 |
84 | public String getMiddleLineSplitName() {
85 | return NameUtils.getLowerDelimiterName(getShortClassName(), "-");
86 | }
87 |
88 | public String getPathSplitName() {
89 | return NameUtils.getLowerDelimiterName(getShortClassName(), "/");
90 | }
91 |
92 | public String getUpperName() {
93 | return getShortClassName().toUpperCase();
94 | }
95 |
96 | public String getLowerName() {
97 | return getShortClassName().toLowerCase();
98 | }
99 |
100 |
101 | public String processTableName(String tableName) {
102 | if (prefixRemove != null && !prefixRemove.isEmpty()) {
103 | if (tableName.startsWith(prefixRemove)) {
104 | tableName = tableName.substring(prefixRemove.length());
105 | } else {
106 | LOGGER.warning(String.format("table %s 设置移除的前缀 %s 无效!", tableName, prefixRemove));
107 | }
108 | }
109 | if (suffixRemove != null && !suffixRemove.isEmpty()) {
110 | if (tableName.endsWith(suffixRemove)) {
111 | tableName = tableName.substring(0, tableName.length() - suffixRemove.length());
112 | }
113 | }
114 | if (tableName.startsWith(delimiter)) {
115 | tableName = tableName.substring(delimiter.length());
116 | }
117 | if (tableName.endsWith(delimiter)) {
118 | tableName = tableName.substring(0, tableName.length() - delimiter.length());
119 | }
120 | return tableName;
121 | }
122 |
123 |
124 | public String getFileName() {
125 |
126 | String resultName = null;
127 |
128 | if (camel) {
129 | resultName = getShortClassName();
130 | } else if (upperCase) {
131 | resultName = prefixAdd + (tableName.replace(delimiter, fileSeparator)).toUpperCase() + suffixAdd;
132 | } else if (lowerCase) {
133 | resultName = prefixAdd + (tableName.replace(delimiter, fileSeparator)).toLowerCase() + suffixAdd;
134 | }
135 |
136 | // 默认设置为首字母大写驼峰
137 | if (resultName == null) {
138 | resultName = getShortClassName();
139 | }
140 |
141 | String longName = (get_package() + "." + resultName).replace(".", File.separator);
142 | if (!srcDir.startsWith(File.separator)) {
143 | srcDir = File.separator + srcDir;
144 | }
145 | if (!srcDir.endsWith(File.separator)) {
146 | srcDir = srcDir + File.separator;
147 | }
148 | if (!fileType.startsWith(".")) {
149 | fileType = "." + fileType;
150 | }
151 | return srcDir + longName + fileType;
152 | }
153 |
154 | public String getPackageName() {
155 | return _package;
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/datebase/DataBaseProvider.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.datebase;
2 |
3 | import com.github.lit.code.context.Table;
4 |
5 | import java.sql.Connection;
6 | import java.sql.SQLException;
7 | import java.util.Map;
8 |
9 | /**
10 | * User : liulu
11 | * Date : 2018/2/10 15:48
12 | * version $Id: DataBaseProvider.java, v 0.1 Exp $
13 | */
14 | public interface DataBaseProvider {
15 |
16 | String getDbName();
17 |
18 | Map getColumnComment(Connection connection, Table table) throws SQLException;
19 | }
20 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/datebase/DateBaseProviderFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.datebase;
2 |
3 | import java.util.Map;
4 | import java.util.concurrent.ConcurrentHashMap;
5 |
6 | /**
7 | * User : liulu
8 | * Date : 2018/2/10 16:06
9 | * version $Id: DateBaseProviderFactory.java, v 0.1 Exp $
10 | */
11 | public class DateBaseProviderFactory {
12 |
13 | private static final Map PROVIDER_MAP = new ConcurrentHashMap<>();
14 |
15 | static {
16 | registerProvider(new MySqlProvider());
17 | }
18 |
19 | public static void registerProvider(DataBaseProvider dataBaseProvider) {
20 | PROVIDER_MAP.put(dataBaseProvider.getDbName().toUpperCase(), dataBaseProvider);
21 | }
22 |
23 |
24 | public static DataBaseProvider getDataBaseProvider(String dbName) {
25 | return PROVIDER_MAP.get(dbName.toUpperCase());
26 | }
27 |
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/datebase/MySqlProvider.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.datebase;
2 |
3 | import com.github.lit.code.context.Table;
4 |
5 | import java.sql.Connection;
6 | import java.sql.PreparedStatement;
7 | import java.sql.ResultSet;
8 | import java.sql.SQLException;
9 | import java.util.Map;
10 | import java.util.concurrent.ConcurrentHashMap;
11 |
12 | /**
13 | * User : liulu
14 | * Date : 2018/2/10 15:50
15 | * version $Id: MySqlProvider.java, v 0.1 Exp $
16 | */
17 | public class MySqlProvider implements DataBaseProvider {
18 | @Override
19 | public String getDbName() {
20 | return "MYSQL";
21 | }
22 |
23 | @Override
24 | public Map getColumnComment(Connection connection, Table table) throws SQLException {
25 |
26 | String sql = "select column_name, column_comment from information_schema.columns where table_schema = ? and table_name = ?";
27 | PreparedStatement ps = connection.prepareStatement(sql);
28 | ps.setString(1, table.getCatalog());
29 | ps.setString(2, table.getName());
30 | ResultSet resultSet = ps.executeQuery();
31 |
32 | Map result = new ConcurrentHashMap<>();
33 |
34 | while (resultSet.next()) {
35 | result.put(resultSet.getString("column_name").toLowerCase(), resultSet.getString("column_comment"));
36 | }
37 |
38 | return result;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/executor/GenerationExecutor.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.executor;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.context.Table;
5 | import com.github.lit.code.context.Task;
6 | import com.github.lit.code.plugin.PluginExecutor;
7 | import com.github.lit.code.util.FileUtils;
8 | import com.github.lit.support.util.ClassUtils;
9 | import org.apache.velocity.VelocityContext;
10 | import org.apache.velocity.app.Velocity;
11 | import org.apache.velocity.context.Context;
12 |
13 | import java.io.File;
14 | import java.io.StringWriter;
15 | import java.util.List;
16 | import java.util.logging.Logger;
17 |
18 | /**
19 | * User : liulu
20 | * Date : 2018/2/7 15:00
21 | * version $Id: GenerationExecutor.java, v 0.1 Exp $
22 | */
23 | public class GenerationExecutor {
24 |
25 | private static final Logger LOGGER = Logger.getLogger(GenerationExecutor.class.getName());
26 |
27 | public static void execute(Configuration configuration) {
28 |
29 | Table table = configuration.getTable();
30 | Boolean overwrite = configuration.getBooleanConstant("overwrite", true);
31 | Boolean onChildModule = configuration.getBooleanConstant("onChildModule");
32 | String rootDir = configuration.getConstant("rootDir", System.getProperty("user.dir"));
33 | if (onChildModule) {
34 | rootDir = rootDir.substring(0, rootDir.lastIndexOf(File.separator));
35 | }
36 |
37 | VelocityContext context = new VelocityContext();
38 | context.put("table", table);
39 | context.put("constant", configuration.getConstantMap());
40 |
41 | List tableTasks = table.getTasks();
42 | for (String tableTask : tableTasks) {
43 | Task task = configuration.getTask(tableTask);
44 | if (task == null) {
45 | continue;
46 | }
47 | task.setTableName(task.processTableName(table.getName()));
48 | context.put(task.getName(), task);
49 |
50 | executePlugin(configuration, context, task);
51 |
52 | String targetDir = rootDir + File.separator + task.getModule();
53 | String filePath = targetDir + task.getFileName();
54 |
55 | String templateText = FileUtils.readToString(task.getTemplate());
56 |
57 | StringWriter stringWriter = new StringWriter();
58 | Velocity.evaluate(context, stringWriter, "lit-code", templateText);
59 | String resultText = stringWriter.toString();
60 | FileUtils.writeToFile(resultText, filePath, overwrite);
61 | }
62 | }
63 |
64 |
65 | private static void executePlugin(Configuration configuration, Context context, Task task) {
66 |
67 | List plugins = task.getPlugins();
68 | if (plugins == null || plugins.isEmpty()) {
69 | return;
70 | }
71 |
72 | for (String plugin : plugins) {
73 | PluginExecutor pluginExecutor = (PluginExecutor) ClassUtils.newInstance(plugin);
74 | pluginExecutor.execute(configuration, context, task);
75 | }
76 | }
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/parser/ConfigParser.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.parser;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.google.gson.JsonElement;
5 |
6 | /**
7 | * User : liulu
8 | * Date : 2018/2/6 16:31
9 | * version $Id: ConfigParser.java, v 0.1 Exp $
10 | */
11 | public interface ConfigParser {
12 |
13 | String getConfigKey();
14 |
15 | void parser(Configuration configuration, JsonElement jsonElement);
16 | }
17 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/parser/ConstantParser.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.parser;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.context.ConfigConst;
5 | import com.google.gson.JsonElement;
6 |
7 | import java.util.Map;
8 |
9 | /**
10 | * User : liulu
11 | * Date : 2018/2/7 15:13
12 | * version $Id: ConstantParser.java, v 0.1 Exp $
13 | */
14 | public class ConstantParser implements ConfigParser {
15 |
16 | @Override
17 | public String getConfigKey() {
18 | return ConfigConst.CONSTANT;
19 | }
20 |
21 | @Override
22 | public void parser(Configuration configuration, JsonElement jsonElement) {
23 | if (jsonElement.isJsonArray()) {
24 | return;
25 | }
26 | for (Map.Entry entry : jsonElement.getAsJsonObject().entrySet()) {
27 | String value = entry.getValue().getAsString();
28 | if (value == null || value.length() == 0 || "null".equals(value)) {
29 | continue;
30 | }
31 | configuration.addConstant(entry.getKey(), value);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/parser/ConverterParser.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.parser;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.context.ConfigConst;
5 | import com.github.lit.code.context.GenerationException;
6 | import com.google.gson.JsonElement;
7 |
8 | import java.util.Map;
9 |
10 | /**
11 | * User : liulu
12 | * Date : 2018/2/9 15:12
13 | * version $Id: ConverterParser.java, v 0.1 Exp $
14 | */
15 | public class ConverterParser implements ConfigParser {
16 |
17 | @Override
18 | public String getConfigKey() {
19 | return ConfigConst.CONVERTER;
20 | }
21 |
22 | @Override
23 | public void parser(Configuration configuration, JsonElement jsonElement) {
24 | if (jsonElement.isJsonArray()) {
25 | throw new GenerationException("列转换 配置项不能是数组!");
26 | }
27 | for (Map.Entry entry : jsonElement.getAsJsonObject().entrySet()) {
28 | if (entry.getValue() == null) {
29 | continue;
30 | }
31 | configuration.addConverter(entry.getKey().toUpperCase(), entry.getValue().getAsString());
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/parser/JdbcParser.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.parser;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.config.JdbcConfig;
5 | import com.github.lit.code.context.ConfigConst;
6 | import com.github.lit.code.context.GenerationException;
7 | import com.google.gson.Gson;
8 | import com.google.gson.JsonElement;
9 |
10 | /**
11 | * User : liulu
12 | * Date : 2018/2/6 15:10
13 | * version $Id: JdbcParser.java, v 0.1 Exp $
14 | */
15 | public class JdbcParser implements ConfigParser {
16 |
17 | @Override
18 | public String getConfigKey() {
19 | return ConfigConst.JDBC;
20 | }
21 |
22 | @Override
23 | public void parser(Configuration configuration, JsonElement jsonElement) {
24 | if (jsonElement.isJsonArray()) {
25 | throw new GenerationException("table 配置项不能是数组!");
26 | }
27 |
28 | JdbcConfig jdbcConfig = new Gson().fromJson(jsonElement.toString(), JdbcConfig.class);
29 | if (jdbcConfig.getDbName() != null && !jdbcConfig.getDbName().isEmpty()) {
30 | jdbcConfig.setDbName(jdbcConfig.getDbName().toUpperCase());
31 | }
32 | configuration.setJdbcConfig(jdbcConfig);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/parser/TableParser.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.parser;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.config.JdbcConfig;
5 | import com.github.lit.code.context.Column;
6 | import com.github.lit.code.context.ConfigConst;
7 | import com.github.lit.code.context.GenerationException;
8 | import com.github.lit.code.context.Table;
9 | import com.github.lit.code.datebase.DataBaseProvider;
10 | import com.github.lit.code.datebase.DateBaseProviderFactory;
11 | import com.github.lit.code.util.DBUtils;
12 | import com.google.gson.Gson;
13 | import com.google.gson.JsonElement;
14 |
15 | import java.sql.Connection;
16 | import java.sql.PreparedStatement;
17 | import java.sql.ResultSet;
18 | import java.sql.ResultSetMetaData;
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.Map;
22 | import java.util.Objects;
23 | import java.util.logging.Logger;
24 |
25 | /**
26 | * User : liulu
27 | * Date : 2018/2/7 18:58
28 | * version $Id: TableParser.java, v 0.1 Exp $
29 | */
30 | public class TableParser implements ConfigParser {
31 |
32 | private static final Logger LOGGER = Logger.getLogger(TableParser.class.getName());
33 |
34 | @Override
35 | public String getConfigKey() {
36 | return ConfigConst.TABLE;
37 | }
38 |
39 | @Override
40 | public void parser(Configuration configuration, JsonElement jsonElement) {
41 |
42 | JdbcConfig jdbcConfig = configuration.getJdbcConfig();
43 | if (jdbcConfig == null) {
44 | throw new GenerationException("未找到数据库连接配置, 不能解析表信息! 如果不需要解析表信息, 请将配置文件中的 table 配置删除!");
45 | }
46 | if (jsonElement.isJsonArray()) {
47 | throw new GenerationException("table 配置项不能是数组!");
48 | }
49 |
50 | Table table = new Gson().fromJson(jsonElement.toString(), Table.class);
51 | configuration.setTable(table);
52 |
53 | // 初始化数据连接
54 | DBUtils.createConnection(configuration.getJdbcConfig());
55 | initTableMetaData(table);
56 |
57 | // 转换自定义 jdbcType 和 javaType 的映射
58 | for (Column column : table.getColumns()) {
59 | String javaClass = configuration.getConverter(column.getJdbcType());
60 | if (javaClass != null && !javaClass.isEmpty()) {
61 | column.setJavaClass(javaClass);
62 | }
63 | column.setJavaType(column.getJavaClass().substring(column.getJavaClass().lastIndexOf(".") + 1));
64 | }
65 | }
66 |
67 | /**
68 | * @param table
69 | */
70 | private void initTableMetaData(Table table) {
71 |
72 | Connection connection = DBUtils.getConnection();
73 | try {
74 | if (table.getCatalog() == null || table.getCatalog().isEmpty()) {
75 | table.setCatalog(connection.getCatalog());
76 | }
77 | if (table.getSchema() == null || table.getSchema().isEmpty()) {
78 | table.setSchema(connection.getSchema());
79 | }
80 | if (table.getQuoteString() == null || table.getQuoteString().isEmpty()) {
81 | table.setQuoteString(connection.getMetaData().getIdentifierQuoteString());
82 | }
83 | String dbName = connection.getMetaData().getDatabaseProductName();
84 | DataBaseProvider provider = DateBaseProviderFactory.getDataBaseProvider(dbName);
85 | Map columnCommentMap = null;
86 | if (provider != null) {
87 | columnCommentMap = provider.getColumnComment(connection, table);
88 | } else {
89 | LOGGER.warning("未能找到 " + dbName + " 数据库查询列备注信息的provider!");
90 | }
91 |
92 | ResultSet primaryKeys = connection.getMetaData().getPrimaryKeys(table.getCatalog(), table.getSchema(), table.getName());
93 | while (primaryKeys.next()) {
94 | table.setPrimaryKey(primaryKeys.getString("COLUMN_NAME").toLowerCase());
95 | }
96 |
97 | String querySql = "select * from" + table.getFullTableName() + "where 1=2";
98 | LOGGER.info("查询表元数据, 执行sql: " + querySql);
99 | PreparedStatement ps = connection.prepareStatement(querySql);
100 | ResultSetMetaData tableMetaData = ps.executeQuery().getMetaData();
101 |
102 | List columns = new ArrayList<>(tableMetaData.getColumnCount());
103 | for (int i = 0; i < tableMetaData.getColumnCount(); i++) {
104 | Column column = new Column();
105 | column.setName(tableMetaData.getColumnName(i + 1).toLowerCase()); // 列名 - 小写
106 | column.setJdbcType(tableMetaData.getColumnTypeName(i + 1)); // jdbcType eg: VARCHAR
107 | column.setJavaClass(tableMetaData.getColumnClassName(i + 1)); // jdbcType 对应的 javaClass eg: java.lang.String
108 | column.setDisplaySize(tableMetaData.getColumnDisplaySize(i + 1));
109 | column.setScale(tableMetaData.getScale(i + 1));
110 | column.setAutoIncrement(tableMetaData.isAutoIncrement(i + 1)); //是否是自增列
111 | // 列备注
112 | if (columnCommentMap != null) {
113 | String comment = columnCommentMap.get(column.getName());
114 | if (comment != null && !comment.isEmpty()) {
115 | column.setComment(comment);
116 | }
117 | }
118 | // 列是否主键
119 | if (table.getPrimaryKey() == null || table.getPrimaryKey().isEmpty()) {
120 | column.setPrimaryKey(false);
121 | } else {
122 | column.setPrimaryKey(Objects.equals(column.getName(), table.getPrimaryKey()));
123 | }
124 |
125 | columns.add(column);
126 | }
127 | table.setColumns(columns);
128 | } catch (Exception e) {
129 | throw new GenerationException("初始化表元数据信息异常", e);
130 | } finally {
131 | DBUtils.closeConnection();
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/parser/TasksParser.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.parser;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.context.ConfigConst;
5 | import com.github.lit.code.context.GenerationException;
6 | import com.github.lit.code.context.Task;
7 | import com.google.gson.Gson;
8 | import com.google.gson.JsonElement;
9 |
10 | /**
11 | * User : liulu
12 | * Date : 2018/2/7 16:41
13 | * version $Id: TasksParser.java, v 0.1 Exp $
14 | */
15 | public class TasksParser implements ConfigParser {
16 |
17 | @Override
18 | public String getConfigKey() {
19 | return ConfigConst.TASKS;
20 | }
21 |
22 | @Override
23 | public void parser(Configuration configuration, JsonElement jsonElement) {
24 | if (jsonElement.isJsonObject()) {
25 | throw new GenerationException("tasks 配置项必须是数组");
26 | }
27 |
28 | Gson gson = new Gson();
29 | for (JsonElement subElement : jsonElement.getAsJsonArray()) {
30 | if (subElement.isJsonArray()) {
31 | throw new GenerationException("tasks子项不能为数组!");
32 | }
33 | Task task = gson.fromJson(subElement.toString(), Task.class);
34 | String _Package = subElement.getAsJsonObject().get("package").getAsString();
35 | task.set_package(_Package);
36 | configuration.addTask(task);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/plugin/PluginExecutor.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.plugin;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.context.Task;
5 | import org.apache.velocity.context.Context;
6 |
7 | /**
8 | * User : liulu
9 | * Date : 2018/3/16 13:29
10 | * version $Id: PluginExecutor.java, v 0.1 Exp $
11 | */
12 | public interface PluginExecutor {
13 |
14 | void execute(Configuration configuration, Context context, Task task);
15 |
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/plugin/SerialVersionUIDPlugin.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.plugin;
2 |
3 | import com.github.lit.code.config.Configuration;
4 | import com.github.lit.code.context.Task;
5 | import org.apache.velocity.context.Context;
6 |
7 | import java.util.UUID;
8 |
9 | /**
10 | * User : liulu
11 | * Date : 2018/3/16 13:37
12 | * version $Id: SerialVersionUIDPlugin.java, v 0.1 Exp $
13 | */
14 | public class SerialVersionUIDPlugin implements PluginExecutor {
15 |
16 | @Override
17 | public void execute(Configuration configuration, Context context, Task task) {
18 | long serialVersionUID = Math.abs(UUID.randomUUID().getLeastSignificantBits());
19 | context.put("serialVersionUID", -serialVersionUID);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/util/DBUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.util;
2 |
3 | import com.github.lit.code.config.JdbcConfig;
4 | import com.github.lit.code.context.GenerationException;
5 |
6 | import java.sql.Connection;
7 | import java.sql.DriverManager;
8 | import java.sql.SQLException;
9 |
10 | /**
11 | * User : liulu
12 | * Date : 2018/2/9 15:20
13 | * version $Id: DBUtils.java, v 0.1 Exp $
14 | */
15 | public class DBUtils {
16 |
17 | private static Connection connection;
18 |
19 | private static String getDriverClass(String dbName) {
20 | if (dbName == null || dbName.isEmpty()) {
21 | return dbName;
22 | }
23 | switch (dbName.toUpperCase()) {
24 | case "MYSQL":
25 | return "com.mysql.jdbc.Driver";
26 | case "ORACLE":
27 | return "oracle.jdbc.driver.OracleDriver";
28 | default:
29 | return "";
30 | }
31 | }
32 |
33 |
34 | public synchronized static void createConnection(JdbcConfig jdbcConfig) {
35 |
36 | try {
37 | if (jdbcConfig.getDriverClass() == null && jdbcConfig.getDbName() != null) {
38 | jdbcConfig.setDriverClass(getDriverClass(jdbcConfig.getDbName()));
39 | Class.forName(jdbcConfig.getDriverClass());
40 | }
41 | connection = DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUser(), jdbcConfig.getPassword());
42 | if (jdbcConfig.getDbName() == null || jdbcConfig.getDbName().isEmpty()) {
43 | jdbcConfig.setDbName(connection.getMetaData().getDatabaseProductName().toUpperCase());
44 | }
45 | } catch (Exception e) {
46 | throw new GenerationException("创建数据库连接失败! 检查连接信息是否正确!", e);
47 | }
48 | }
49 |
50 | public static Connection getConnection() {
51 | try {
52 | if (connection == null || connection.isClosed()) {
53 | throw new GenerationException("数据库连接已失效, 请重新创建!");
54 | }
55 | return connection;
56 | } catch (SQLException e) {
57 | throw new GenerationException("数据库连接异常!", e);
58 | }
59 | }
60 |
61 | public static void closeConnection() {
62 | try {
63 | connection.close();
64 | } catch (SQLException e) {
65 | //
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lit-code/src/main/java/com/github/lit/code/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code.util;
2 |
3 | import java.io.*;
4 | import java.util.logging.Logger;
5 |
6 | /**
7 | * User : liulu
8 | * Date : 2018/2/6 15:39
9 | * version $Id: ResourceUtils.java, v 0.1 Exp $
10 | */
11 | public class FileUtils {
12 |
13 | private static final Logger LOGGER = Logger.getLogger(FileUtils.class.getName());
14 |
15 | public static String readToString (String filePath) {
16 | if (!filePath.startsWith(File.separator)) {
17 | filePath = File.separator + filePath;
18 | }
19 | InputStream inputStream = FileUtils.class.getResourceAsStream(filePath);
20 | if (inputStream == null) {
21 | return "";
22 | }
23 | return readToString(inputStream);
24 | }
25 |
26 | public static String readToString(InputStream inputStream) {
27 |
28 | byte[] b = new byte[1024 * 4];
29 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
30 | try {
31 | for (int len; ; ) {
32 | len = inputStream.read(b, 0, b.length);
33 | if (len == -1) {
34 | break;
35 | }
36 | outputStream.write(b, 0, len);
37 | }
38 | return outputStream.toString("UTF-8");
39 | } catch (IOException e) {
40 | //
41 | } finally {
42 | try {
43 | inputStream.close();
44 | outputStream.close();
45 | } catch (IOException e) {
46 | //
47 | }
48 | }
49 | return "";
50 | }
51 |
52 | public static void writeToFile (String text, String filePath, boolean overwrite) {
53 |
54 | try {
55 | File file = new File(filePath);
56 | if (file.exists() && !overwrite) {
57 | LOGGER.info(String.format("file %s is exist, do nothing", filePath));
58 | return;
59 | }
60 | if (!file.getParentFile().exists()) {
61 | file.getParentFile().mkdirs();
62 | }
63 |
64 | FileWriter fileWriter = new FileWriter(file);
65 | fileWriter.write(text);
66 | fileWriter.flush();
67 | fileWriter.close();
68 | LOGGER.info(String.format("generate file: %s ", filePath));
69 | } catch (IOException e) {
70 | //
71 | }
72 |
73 | }
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/lit-code/src/test/java/com/github/lit/code/Generation.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.code;
2 |
3 | /**
4 | * User : liulu
5 | * Date : 2018/3/16 11:45
6 | * version $Id: Generation.java, v 0.1 Exp $
7 | */
8 | public class Generation {
9 |
10 |
11 | public static void main(String[] args) {
12 | CodeGeneration.run();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lit-code/src/test/resources/code.json:
--------------------------------------------------------------------------------
1 | {
2 | "constant": {
3 | "overwrite": true,
4 | "onChildModule": false,
5 | "rootDir": "/Users/liulu/Documents/project/git/qianniu",
6 | "baseModule": "qn-common",
7 | "basePackage": "com.ipampas.qianniu",
8 | "modelPackage": "product"
9 | },
10 | "jdbc": {
11 | "url": "jdbc:mysql://10.10.100.56:3306/qianniu_dev?useSSL=false&useUnicode=true&characterEncoding=UTF-8",
12 | "user": "root",
13 | "password": "123456"
14 | },
15 | "table": {
16 | "name": "sign_product",
17 | "desc": "3.0产品",
18 | "tasks": [
19 | "model",
20 | "qo",
21 | "mapper",
22 | "xmlMapper",
23 | "service",
24 | "serviceImpl"
25 | ]
26 | },
27 | "tasks": [
28 | {
29 | "name": "model",
30 | "plugins": [
31 | "com.github.lit.code.plugin.SerialVersionUIDPlugin"
32 | ],
33 | "template": "/templates/model.vm",
34 | "module": "${baseModule}",
35 | "package": "${basePackage}.model.${modelPackage}"
36 | },
37 | {
38 | "name": "qo",
39 | "plugins": [
40 | "com.github.lit.code.plugin.SerialVersionUIDPlugin"
41 | ],
42 | "template": "/templates/qo.vm",
43 | "suffixAdd": "Qo",
44 | "module": "${baseModule}",
45 | "package": "${basePackage}.model.${modelPackage}"
46 | },
47 | {
48 | "name": "mapper",
49 | "template": "/templates/mapper.vm",
50 | "suffixAdd": "Mapper",
51 | "module": "${baseModule}",
52 | "package": "${basePackage}.mapper.${modelPackage}"
53 | },
54 | {
55 | "name": "xmlMapper",
56 | "template": "/templates/xmlMapper.vm",
57 | "suffixAdd": "Mapper",
58 | "fileType": ".xml",
59 | "module": "${baseModule}",
60 | "srcDir": "src/main/resources",
61 | "package": "${basePackage}.mapper.${modelPackage}"
62 | },
63 | {
64 | "name": "service",
65 | "template": "/templates/service.vm",
66 | "suffixAdd": "Service",
67 | "module": "${baseModule}",
68 | "package": "${basePackage}.service.${modelPackage}"
69 | },
70 | {
71 | "name": "serviceImpl",
72 | "suffixAdd": "ServiceImpl",
73 | "template": "/templates/serviceImpl.vm",
74 | "module": "${baseModule}",
75 | "package": "${basePackage}.service.${modelPackage}.impl"
76 | }
77 | ]
78 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/client.vm:
--------------------------------------------------------------------------------
1 | package ${packageName};
2 |
3 | import com.ipampas.framework.model.Page;
4 | import ${model.longClassName};
5 | import ${qo.longClassName};
6 | import org.springframework.cloud.netflix.feign.FeignClient;
7 | import org.springframework.web.bind.annotation.*;
8 |
9 | /**
10 | * ${table.desc} 接口客户端
11 | *
12 | * Author: Created by code generator
13 | * Date: ${date}
14 | */
15 | @FeignClient("panshi-server")
16 | public interface ${client.shortClassName} {
17 |
18 |
19 | @PostMapping("/${model.pathThroughClassName}/list")
20 | Page<${model.shortClassName}> findPageList(@RequestBody ${qo.shortClassName} ${qo.firstLowerClassName});
21 |
22 |
23 | @GetMapping("/${model.pathThroughClassName}/{id}")
24 | ${model.shortClassName} get(@PathVariable("id") Long id);
25 |
26 |
27 | @PostMapping("/${model.pathThroughClassName}")
28 | Long insert(@RequestBody ${model.shortClassName} ${model.firstLowerClassName});
29 |
30 |
31 | @PutMapping("/${model.pathThroughClassName}")
32 | Integer update(@RequestBody ${model.shortClassName} ${model.firstLowerClassName});
33 |
34 |
35 | @DeleteMapping("/${model.pathThroughClassName}/{id}")
36 | Integer deleteById(@PathVariable("id") Long id);
37 |
38 |
39 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/mapper.vm:
--------------------------------------------------------------------------------
1 | package ${mapper.packageName};
2 |
3 | import ${model.longClassName};
4 | import ${qo.longClassName};
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * ${table.desc} mapper 接口
10 | *
11 | * @author generator
12 | * @version 1.0.0
13 | */
14 | public interface ${mapper.shortClassName} {
15 |
16 | /**
17 | * 新增${table.desc}
18 | *
19 | * @param ${model.firstLowerClassName}
20 | * @return
21 | */
22 | int insert(${model.shortClassName} ${model.firstLowerClassName});
23 |
24 | /**
25 | * 删除${table.desc}
26 | *
27 | * @param id
28 | * @return
29 | */
30 | int deleteById(Long id);
31 |
32 | /**
33 | * 修改${table.desc}, 忽略null值
34 | *
35 | * @param ${model.firstLowerClassName}
36 | * @return
37 | */
38 | int updateById(${model.shortClassName} ${model.firstLowerClassName});
39 |
40 | /**
41 | * 查询${table.desc}
42 | *
43 | * @param id
44 | * @return ${table.desc}
45 | */
46 | ${model.shortClassName} findById(Long id);
47 |
48 | /**
49 | * 分页查询${table.desc}列表
50 | *
51 | * @param ${qo.firstLowerClassName} 查询对象
52 | * @return ${table.desc}列表
53 | */
54 | List<${model.shortClassName}> findList(${qo.shortClassName} ${qo.firstLowerClassName});
55 |
56 |
57 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/model.vm:
--------------------------------------------------------------------------------
1 | package ${model.packageName};
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 | #foreach($im in ${table.importClasses})
7 | import ${im};
8 | #end
9 |
10 | /**
11 | * ${table.desc}
12 | *
13 | * @author generator
14 | * @version 1.0.0
15 | */
16 | @Data
17 | public class ${model.shortClassName} implements Serializable{
18 |
19 | /** serialVersionUID */
20 | private static final long serialVersionUID = ${serialVersionUID}L;
21 |
22 | #foreach($column in ${table.columns})
23 | #if(${column.comment} && $column.name != 'tenant_id')
24 | /** ${column.comment} */
25 | #end
26 | #if($column.name != 'tenant_id')
27 | private ${column.javaType} ${column.camelName};
28 |
29 | #end
30 | #end
31 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/qo.vm:
--------------------------------------------------------------------------------
1 | package ${qo.packageName};
2 |
3 | import com.ipampas.framework.model.Page;
4 | import lombok.Data;
5 |
6 | /**
7 | * ${table.desc}
8 | *
9 | * @author generator
10 | * @version 1.0.0
11 | */
12 | @Data
13 | public class ${qo.shortClassName} extends Page {
14 |
15 | /** serialVersionUID */
16 | private static final long serialVersionUID = ${serialVersionUID}L;
17 |
18 |
19 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/rest.vm:
--------------------------------------------------------------------------------
1 | package ${packageName};
2 |
3 | import com.github.pagehelper.Page;
4 | import ${model.longClassName};
5 | import ${qo.longClassName};
6 | import ${service.longClassName};
7 | import org.springframework.web.bind.annotation.*;
8 |
9 | import javax.annotation.Resource;
10 |
11 | /**
12 | * ${table.desc} rest 接口
13 | *
14 | * Author: Created by code generator
15 | * Date: ${date}
16 | */
17 | @RestController
18 | @RequestMapping("/${model.pathThroughClassName}")
19 | public class ${rest.shortClassName} {
20 |
21 | @Resource
22 | private ${service.shortClassName} ${service.firstLowerClassName};
23 |
24 |
25 | @PostMapping("/list")
26 | public com.ipampas.framework.model.Page<${model.shortClassName}> list(@RequestBody ${qo.shortClassName} ${qo.firstLowerClassName}) {
27 | Page<${model.shortClassName}> list = (Page<${model.shortClassName}>) ${service.firstLowerClassName}.findPageList(${qo.firstLowerClassName});
28 |
29 | // myBatis 分页对象转为 pps 统一分页对象
30 | com.ipampas.framework.model.Page<${model.shortClassName}> result = new com.ipampas.framework.model.Page<>();
31 | result.setPageNo(list.getPageNum());
32 | result.setPageRecords(list);
33 | result.setPageSize(list.getPageSize());
34 | result.setTotalRecords(list.getTotal());
35 |
36 | return result;
37 | }
38 |
39 | @GetMapping("/{id}")
40 | public ${model.shortClassName} detail(@PathVariable Long id) {
41 | return ${service.firstLowerClassName}.findById(id);
42 | }
43 |
44 | @PostMapping
45 | public Long add(@RequestBody ${model.shortClassName} ${model.firstLowerClassName}) {
46 | return ${service.firstLowerClassName}.insert(${model.firstLowerClassName});
47 | }
48 |
49 | @PutMapping
50 | public Integer update(@RequestBody ${model.shortClassName} ${model.firstLowerClassName}) {
51 | return ${service.firstLowerClassName}.updateById(${model.firstLowerClassName});
52 | }
53 |
54 | @DeleteMapping("{id}")
55 | public Integer deleteById(@PathVariable Long id) {
56 | return ${service.firstLowerClassName}.deleteById(id);
57 | }
58 |
59 |
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/service.vm:
--------------------------------------------------------------------------------
1 | package ${service.packageName};
2 |
3 | import com.ipampas.framework.model.Page;
4 | import ${model.longClassName};
5 | import ${qo.longClassName};
6 |
7 |
8 | /**
9 | * ${table.desc} service 接口
10 | *
11 | * @author generator
12 | * @version 1.0.0
13 | */
14 | public interface ${service.shortClassName} {
15 |
16 | /**
17 | * 新增${table.desc}
18 | *
19 | * @param ${model.firstLowerClassName}
20 | * @return 新记录的Id
21 | */
22 | Long create(${model.shortClassName} ${model.firstLowerClassName});
23 |
24 | /**
25 | * 删除${table.desc}
26 | *
27 | * @param id
28 | * @return
29 | */
30 | int removeById(Long id);
31 |
32 | /**
33 | * 修改${table.desc}, 忽略null值
34 | *
35 | * @param ${model.firstLowerClassName}
36 | * @return
37 | */
38 | int modify(${model.shortClassName} ${model.firstLowerClassName});
39 |
40 | /**
41 | * 查询${table.desc}
42 | *
43 | * @param id
44 | * @return ${table.desc}
45 | */
46 | ${model.shortClassName} findById(Long id);
47 |
48 | /**
49 | * 分页查询${table.desc}列表
50 | *
51 | * @param ${qo.firstLowerClassName} 查询对象
52 | * @return ${table.desc}列表
53 | */
54 | Page<${model.shortClassName}> findPageList(${qo.shortClassName} ${qo.firstLowerClassName});
55 |
56 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/serviceImpl.vm:
--------------------------------------------------------------------------------
1 | package ${serviceImpl.packageName};
2 |
3 | import com.github.pagehelper.PageHelper;
4 | import com.ipampas.framework.model.Page;
5 | import com.ipampas.qianniu.util.PageUtils;
6 | import ${model.longClassName};
7 | import ${qo.longClassName};
8 | import ${mapper.longClassName};
9 | import ${service.longClassName};
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.transaction.annotation.Transactional;
13 |
14 | import javax.annotation.Resource;
15 | import java.util.List;
16 |
17 | /**
18 | * ${table.desc} service 接口实现
19 | *
20 | * @author generator
21 | * @version 1.0.0
22 | */
23 | @Service
24 | @Slf4j
25 | @Transactional
26 | public class ${serviceImpl.shortClassName} implements ${service.shortClassName} {
27 |
28 | @Resource
29 | private ${mapper.shortClassName} ${mapper.firstLowerClassName};
30 |
31 |
32 | @Override
33 | public Long create(${model.shortClassName} ${model.firstLowerClassName}) {
34 | ${mapper.firstLowerClassName}.insert(${model.firstLowerClassName});
35 | return ${model.firstLowerClassName}.getId();
36 | }
37 |
38 | @Override
39 | public int removeById(Long id) {
40 | return ${mapper.firstLowerClassName}.deleteById(id);
41 | }
42 |
43 | @Override
44 | public int modify(${model.shortClassName} ${model.firstLowerClassName}) {
45 | return ${mapper.firstLowerClassName}.updateById(${model.firstLowerClassName});
46 | }
47 |
48 | @Override
49 | public ${model.shortClassName} findById(Long id) {
50 | return ${mapper.firstLowerClassName}.findById(id);
51 | }
52 |
53 | @Override
54 | public Page<${model.shortClassName}> findPageList(${qo.shortClassName} ${qo.firstLowerClassName}) {
55 | PageHelper.startPage(${qo.firstLowerClassName}.getPageNo(), ${qo.firstLowerClassName}.getPageSize());
56 | List<${model.shortClassName}> pageList = ${mapper.firstLowerClassName}.findList(${qo.firstLowerClassName});
57 | return PageUtils.transToPage(pageList);
58 | }
59 |
60 |
61 | }
--------------------------------------------------------------------------------
/lit-code/src/test/resources/templates/xmlMapper.vm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #foreach($column in ${table.columns})
7 | #if(${column.primaryKey})
8 | #set($primaryKey = $column)
9 |
10 | #elseif($column.name != 'tenant_id')
11 |
12 | #end
13 | #end
14 |
15 |
16 |
17 | #set($columnSize = ${table.columns.size()})
18 | #foreach($column in ${table.columns})
19 | #if($column.name != 'tenant_id')${column.name}#end#if($velocityCount < $columnSize && $column.name != 'tenant_id'), #end
20 | #end
21 |
22 |
23 |
24 |
30 |
31 |
36 |
37 |
38 | insert into ${table.name}
39 |
40 | #foreach($column in ${table.columns})
41 | #if($column.name != 'tenant_id')
42 |
43 | ${column.name},
44 |
45 | #else
46 | tenant_id,
47 | #end
48 | #end
49 |
50 |
51 | #foreach($column in ${table.columns})
52 | #if(${column.name} == 'tenant_id')
53 | #{tenantId},
54 | #else
55 |
56 | #{${column.camelName}},
57 |
58 | #end
59 | #end
60 |
61 |
62 |
63 |
64 | update ${table.name}
65 |
66 | #foreach($column in ${table.columns})
67 | #if(!${column.isPrimaryKey})
68 | #if($column.name != 'tenant_id')
69 |
70 | ${column.name} = #{${column.camelName}},
71 |
72 | #end
73 | #end
74 | #end
75 |
76 | where ${primaryKey.name} = #{${primaryKey.camelName}} and tenant_id = #{tenantId}
77 |
78 |
79 |
80 | delete from ${table.name} where ${primaryKey.name} = #{id} and tenant_id = #{tenantId}
81 |
82 |
83 |
--------------------------------------------------------------------------------
/lit-starters/lit-starter-jdbc/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | lit-starters
7 | com.github.liulus
8 | 2.5.0
9 |
10 | 4.0.0
11 |
12 | lit-starter-jdbc
13 |
14 |
15 |
16 | com.github.liulus
17 | lit-support
18 | ${project.version}
19 |
20 |
21 |
22 | javax.persistence
23 | persistence-api
24 | 1.0
25 |
26 |
27 |
28 | org.springframework
29 | spring-jdbc
30 | ${spring.version}
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-autoconfigure
35 | ${spring.boot.version}
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/lit-starters/lit-starter-jdbc/src/main/java/com/github/lit/starter/jdbc/JdbcSupportAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.starter.jdbc;
2 |
3 | import com.github.lit.support.data.jdbc.EnableJdbcSupport;
4 | import org.springframework.boot.autoconfigure.AutoConfigureOrder;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.core.Ordered;
7 |
8 | /**
9 | * @author liulu
10 | * @version v1.0
11 | * date 2018-12-22 19:27
12 | */
13 | @Configuration
14 | @EnableJdbcSupport
15 | @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
16 | public class JdbcSupportAutoConfiguration {
17 |
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/lit-starters/lit-starter-jdbc/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.github.lit.starter.jdbc.JdbcSupportAutoConfiguration
--------------------------------------------------------------------------------
/lit-starters/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | lit
7 | com.github.liulus
8 | 2.5.0
9 |
10 | pom
11 | 4.0.0
12 |
13 | lit-starters
14 |
15 |
16 | lit-starter-jdbc
17 |
18 |
19 |
--------------------------------------------------------------------------------
/lit-support/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | lit
7 | com.github.liulus
8 | 2.5.0
9 |
10 | 4.0.0
11 |
12 | lit-support
13 |
14 |
15 |
16 | javax.persistence
17 | persistence-api
18 | 1.0
19 | true
20 |
21 |
22 | javax.servlet
23 | javax.servlet-api
24 | 3.1.0
25 | true
26 |
27 |
28 | org.slf4j
29 | slf4j-api
30 | true
31 |
32 |
33 | com.fasterxml.jackson.core
34 | jackson-databind
35 | ${jackson.version}
36 | true
37 |
38 |
39 | org.springframework
40 | spring-jdbc
41 | ${spring.version}
42 | true
43 |
44 |
45 | org.springframework
46 | spring-webmvc
47 | ${spring.version}
48 | true
49 |
50 |
51 | org.springframework
52 | spring-aspects
53 | ${spring.version}
54 | true
55 |
56 |
57 | com.google.guava
58 | guava
59 | 22.0
60 | true
61 |
62 |
63 | org.mybatis
64 | mybatis
65 | ${mybatis.version}
66 | true
67 |
68 |
69 |
70 |
71 | org.springframework
72 | spring-test
73 | ${spring.version}
74 | test
75 |
76 |
77 | ch.qos.logback
78 | logback-classic
79 | ${logback.version}
80 | test
81 |
82 |
83 | org.slf4j
84 | jcl-over-slf4j
85 | ${slf4j.version}
86 | test
87 |
88 |
89 | ch.vorburger.mariaDB4j
90 | mariaDB4j
91 | 2.2.3
92 | test
93 |
94 |
95 | mysql
96 | mysql-connector-java
97 | test
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/AbstractSQL.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data;
2 |
3 | import java.io.IOException;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 | import java.util.Collections;
7 | import java.util.List;
8 |
9 | /**
10 | * 引用 org.apache.ibatis.jdbc.AbstractSQL
11 | *
12 | * @author mybatis
13 | * @version v1.0
14 | * @see org.apache.ibatis.jdbc.AbstractSQL
15 | * date 2018-12-10 14:12
16 | */
17 | public abstract class AbstractSQL {
18 |
19 | private static final String AND = ") AND (";
20 | private static final String OR = ") OR (";
21 |
22 | private final SQLStatement sql = new SQLStatement();
23 |
24 | public abstract T getSelf();
25 |
26 | public T UPDATE(String table) {
27 | sql().statementType = SQLStatement.StatementType.UPDATE;
28 | sql().tables.add(table);
29 | return getSelf();
30 | }
31 |
32 | public T SET(String sets) {
33 | sql().sets.add(sets);
34 | return getSelf();
35 | }
36 |
37 | /**
38 | * @since 3.4.2
39 | */
40 | public T SET(String... sets) {
41 | sql().sets.addAll(Arrays.asList(sets));
42 | return getSelf();
43 | }
44 |
45 | public T INSERT_INTO(String tableName) {
46 | sql().statementType = SQLStatement.StatementType.INSERT;
47 | sql().tables.add(tableName);
48 | return getSelf();
49 | }
50 |
51 | public T VALUES(String columns, String values) {
52 | sql().columns.add(columns);
53 | sql().values.add(values);
54 | return getSelf();
55 | }
56 |
57 | /**
58 | * @since 3.4.2
59 | */
60 | public T INTO_COLUMNS(String... columns) {
61 | sql().columns.addAll(Arrays.asList(columns));
62 | return getSelf();
63 | }
64 |
65 | /**
66 | * @since 3.4.2
67 | */
68 | public T INTO_VALUES(String... values) {
69 | sql().values.addAll(Arrays.asList(values));
70 | return getSelf();
71 | }
72 |
73 | public T SELECT(String columns) {
74 | sql().statementType = SQLStatement.StatementType.SELECT;
75 | sql().select.add(columns);
76 | return getSelf();
77 | }
78 |
79 | /**
80 | * @since 3.4.2
81 | */
82 | public T SELECT(String... columns) {
83 | sql().statementType = SQLStatement.StatementType.SELECT;
84 | sql().select.addAll(Arrays.asList(columns));
85 | return getSelf();
86 | }
87 |
88 | public T SELECT_DISTINCT(String columns) {
89 | sql().distinct = true;
90 | SELECT(columns);
91 | return getSelf();
92 | }
93 |
94 | /**
95 | * @since 3.4.2
96 | */
97 | public T SELECT_DISTINCT(String... columns) {
98 | sql().distinct = true;
99 | SELECT(columns);
100 | return getSelf();
101 | }
102 |
103 | public T DELETE_FROM(String table) {
104 | sql().statementType = SQLStatement.StatementType.DELETE;
105 | sql().tables.add(table);
106 | return getSelf();
107 | }
108 |
109 | public T FROM(String table) {
110 | sql().tables.add(table);
111 | return getSelf();
112 | }
113 |
114 | /**
115 | * @since 3.4.2
116 | */
117 | public T FROM(String... tables) {
118 | sql().tables.addAll(Arrays.asList(tables));
119 | return getSelf();
120 | }
121 |
122 | public T JOIN(String join) {
123 | sql().join.add(join);
124 | return getSelf();
125 | }
126 |
127 | /**
128 | * @since 3.4.2
129 | */
130 | public T JOIN(String... joins) {
131 | sql().join.addAll(Arrays.asList(joins));
132 | return getSelf();
133 | }
134 |
135 | public T INNER_JOIN(String join) {
136 | sql().innerJoin.add(join);
137 | return getSelf();
138 | }
139 |
140 | /**
141 | * @since 3.4.2
142 | */
143 | public T INNER_JOIN(String... joins) {
144 | sql().innerJoin.addAll(Arrays.asList(joins));
145 | return getSelf();
146 | }
147 |
148 | public T LEFT_OUTER_JOIN(String join) {
149 | sql().leftOuterJoin.add(join);
150 | return getSelf();
151 | }
152 |
153 | /**
154 | * @since 3.4.2
155 | */
156 | public T LEFT_OUTER_JOIN(String... joins) {
157 | sql().leftOuterJoin.addAll(Arrays.asList(joins));
158 | return getSelf();
159 | }
160 |
161 | public T RIGHT_OUTER_JOIN(String join) {
162 | sql().rightOuterJoin.add(join);
163 | return getSelf();
164 | }
165 |
166 | /**
167 | * @since 3.4.2
168 | */
169 | public T RIGHT_OUTER_JOIN(String... joins) {
170 | sql().rightOuterJoin.addAll(Arrays.asList(joins));
171 | return getSelf();
172 | }
173 |
174 | public T OUTER_JOIN(String join) {
175 | sql().outerJoin.add(join);
176 | return getSelf();
177 | }
178 |
179 | /**
180 | * @since 3.4.2
181 | */
182 | public T OUTER_JOIN(String... joins) {
183 | sql().outerJoin.addAll(Arrays.asList(joins));
184 | return getSelf();
185 | }
186 |
187 | public T WHERE(String conditions) {
188 | sql().where.add(conditions);
189 | sql().lastList = sql().where;
190 | return getSelf();
191 | }
192 |
193 | /**
194 | * @since 3.4.2
195 | */
196 | public T WHERE(String... conditions) {
197 | sql().where.addAll(Arrays.asList(conditions));
198 | sql().lastList = sql().where;
199 | return getSelf();
200 | }
201 |
202 | public T OR() {
203 | sql().lastList.add(OR);
204 | return getSelf();
205 | }
206 |
207 | public T AND() {
208 | sql().lastList.add(AND);
209 | return getSelf();
210 | }
211 |
212 | public T GROUP_BY(String columns) {
213 | sql().groupBy.add(columns);
214 | return getSelf();
215 | }
216 |
217 | /**
218 | * @since 3.4.2
219 | */
220 | public T GROUP_BY(String... columns) {
221 | sql().groupBy.addAll(Arrays.asList(columns));
222 | return getSelf();
223 | }
224 |
225 | public T HAVING(String conditions) {
226 | sql().having.add(conditions);
227 | sql().lastList = sql().having;
228 | return getSelf();
229 | }
230 |
231 | /**
232 | * @since 3.4.2
233 | */
234 | public T HAVING(String... conditions) {
235 | sql().having.addAll(Arrays.asList(conditions));
236 | sql().lastList = sql().having;
237 | return getSelf();
238 | }
239 |
240 | public T ORDER_BY(String columns) {
241 | sql().orderBy.add(columns);
242 | return getSelf();
243 | }
244 |
245 | /**
246 | * @since 3.4.2
247 | */
248 | public T ORDER_BY(String... columns) {
249 | sql().orderBy.addAll(Arrays.asList(columns));
250 | return getSelf();
251 | }
252 |
253 | private SQLStatement sql() {
254 | return sql;
255 | }
256 |
257 | public A usingAppender(A a) {
258 | if (sql().statementType == SQLStatement.StatementType.COUNT) {
259 | sql().statementType = SQLStatement.StatementType.SELECT;
260 | }
261 | sql().sql(a);
262 | return a;
263 | }
264 |
265 | @Override
266 | public String toString() {
267 | if (sql().statementType == SQLStatement.StatementType.COUNT) {
268 | sql().statementType = SQLStatement.StatementType.SELECT;
269 | }
270 | StringBuilder sb = new StringBuilder();
271 | sql().sql(sb);
272 |
273 | return sb.toString();
274 | }
275 |
276 | public String countSql() {
277 | if (sql().statementType == SQLStatement.StatementType.SELECT) {
278 | sql().statementType = SQLStatement.StatementType.COUNT;
279 | }
280 | StringBuilder sb = new StringBuilder();
281 | sql().sql(sb);
282 |
283 | return sb.toString();
284 | }
285 |
286 | private static class SafeAppendable {
287 | private final Appendable a;
288 | private boolean empty = true;
289 |
290 | public SafeAppendable(Appendable a) {
291 | super();
292 | this.a = a;
293 | }
294 |
295 | public SafeAppendable append(CharSequence s) {
296 | try {
297 | if (empty && s.length() > 0) {
298 | empty = false;
299 | }
300 | a.append(s);
301 | } catch (IOException e) {
302 | throw new RuntimeException(e);
303 | }
304 | return this;
305 | }
306 |
307 | public boolean isEmpty() {
308 | return empty;
309 | }
310 |
311 | }
312 |
313 | private static class SQLStatement {
314 |
315 | public enum StatementType {
316 | DELETE, INSERT, SELECT, UPDATE, COUNT
317 | }
318 |
319 | SQLStatement.StatementType statementType;
320 | List sets = new ArrayList<>();
321 | List select = new ArrayList<>();
322 | List count = Collections.singletonList("count(*)");
323 | List tables = new ArrayList<>();
324 | List join = new ArrayList<>();
325 | List innerJoin = new ArrayList<>();
326 | List outerJoin = new ArrayList<>();
327 | List leftOuterJoin = new ArrayList<>();
328 | List rightOuterJoin = new ArrayList<>();
329 | List where = new ArrayList<>();
330 | List having = new ArrayList<>();
331 | List groupBy = new ArrayList<>();
332 | List orderBy = new ArrayList<>();
333 | List lastList = new ArrayList<>();
334 | List columns = new ArrayList<>();
335 | List values = new ArrayList<>();
336 | boolean distinct;
337 |
338 | public SQLStatement() {
339 | // Prevent Synthetic Access
340 | }
341 |
342 | private void sqlClause(SafeAppendable builder, String keyword, List parts, String open, String close,
343 | String conjunction) {
344 | if (!parts.isEmpty()) {
345 | if (!builder.isEmpty()) {
346 | builder.append(" ");
347 | }
348 | builder.append(keyword);
349 | builder.append(" ");
350 | builder.append(open);
351 | String last = "________";
352 | for (int i = 0, n = parts.size(); i < n; i++) {
353 | String part = parts.get(i);
354 | if (i > 0 && !part.equals(AND) && !part.equals(OR) && !last.equals(AND) && !last.equals(OR)) {
355 | builder.append(conjunction);
356 | }
357 | builder.append(part);
358 | last = part;
359 | }
360 | builder.append(close);
361 | }
362 | }
363 |
364 | private String selectSQL(SafeAppendable builder) {
365 | if (distinct) {
366 | sqlClause(builder, "SELECT DISTINCT", select, "", "", ", ");
367 | } else {
368 | sqlClause(builder, "SELECT", select, "", "", ", ");
369 | }
370 |
371 | sqlClause(builder, "FROM", tables, "", "", ", ");
372 | joins(builder);
373 | sqlClause(builder, "WHERE", where, "(", ")", " AND ");
374 | sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");
375 | sqlClause(builder, "HAVING", having, "(", ")", " AND ");
376 | sqlClause(builder, "ORDER BY", orderBy, "", "", ", ");
377 | return builder.toString();
378 | }
379 |
380 | private String countSQL(SafeAppendable builder) {
381 | sqlClause(builder, "SELECT", count, "", "", ", ");
382 | sqlClause(builder, "FROM", tables, "", "", ", ");
383 | joins(builder);
384 | sqlClause(builder, "WHERE", where, "(", ")", " AND ");
385 | sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");
386 | sqlClause(builder, "HAVING", having, "(", ")", " AND ");
387 | return builder.toString();
388 | }
389 |
390 | private void joins(SafeAppendable builder) {
391 | sqlClause(builder, "JOIN", join, "", "", " JOIN ");
392 | sqlClause(builder, "INNER JOIN", innerJoin, "", "", " INNER JOIN ");
393 | sqlClause(builder, "OUTER JOIN", outerJoin, "", "", " OUTER JOIN ");
394 | sqlClause(builder, "LEFT OUTER JOIN", leftOuterJoin, "", "", " LEFT OUTER JOIN ");
395 | sqlClause(builder, "RIGHT OUTER JOIN", rightOuterJoin, "", "", " RIGHT OUTER JOIN ");
396 | }
397 |
398 | private String insertSQL(SafeAppendable builder) {
399 | sqlClause(builder, "INSERT INTO", tables, "", "", "");
400 | sqlClause(builder, "", columns, "(", ")", ", ");
401 | sqlClause(builder, "VALUES", values, "(", ")", ", ");
402 | return builder.toString();
403 | }
404 |
405 | private String deleteSQL(SafeAppendable builder) {
406 | sqlClause(builder, "DELETE FROM", tables, "", "", "");
407 | sqlClause(builder, "WHERE", where, "(", ")", " AND ");
408 | return builder.toString();
409 | }
410 |
411 | private String updateSQL(SafeAppendable builder) {
412 | sqlClause(builder, "UPDATE", tables, "", "", "");
413 | joins(builder);
414 | sqlClause(builder, "SET", sets, "", "", ", ");
415 | sqlClause(builder, "WHERE", where, "(", ")", " AND ");
416 | return builder.toString();
417 | }
418 |
419 | public String sql(Appendable a) {
420 | SafeAppendable builder = new SafeAppendable(a);
421 | if (statementType == null) {
422 | return null;
423 | }
424 |
425 | String answer;
426 |
427 | switch (statementType) {
428 | case DELETE:
429 | answer = deleteSQL(builder);
430 | break;
431 |
432 | case INSERT:
433 | answer = insertSQL(builder);
434 | break;
435 |
436 | case SELECT:
437 | answer = selectSQL(builder);
438 | break;
439 |
440 | case UPDATE:
441 | answer = updateSQL(builder);
442 | break;
443 |
444 | case COUNT:
445 | answer = countSQL(builder);
446 | break;
447 |
448 | default:
449 | answer = null;
450 | }
451 |
452 | return answer;
453 | }
454 | }
455 | }
456 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/Condition.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data;
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 | * User : liulu
12 | * Date : 2018/7/11 18:18
13 | * version $Id: LogicCondition.java, v 0.1 Exp $
14 | */
15 | @Target({METHOD, FIELD})
16 | @Retention(RUNTIME)
17 | public @interface Condition {
18 |
19 | String property() default "";
20 |
21 | Logic logic() default Logic.EQ;
22 |
23 | boolean ignoreEmpty() default true;
24 |
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/Logic.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | /**
7 | * User : liulu
8 | * Date : 2017/3/18 13:19
9 | * version $Id: Logic.java, v 0.1 Exp $
10 | */
11 | @Getter
12 | @AllArgsConstructor
13 | public enum Logic {
14 |
15 | EQ(" = ", "equal"),
16 |
17 | NOT_EQ(" != ", "not equal"),
18 |
19 | LT(" < ", "less than"),
20 |
21 | GT(" > ", "grater than"),
22 |
23 | LTEQ(" <= ", "less than or equal"),
24 |
25 | GTEQ(" >= ", "grater than or equal"),
26 |
27 | LIKE(" like ", "like"),
28 |
29 | NOT_LIKE(" not like ", "not like"),
30 |
31 | IN(" in ", "in"),
32 |
33 | NOT_IN(" not in ", "not in"),
34 |
35 | NULL(" is null ", "is null"),
36 |
37 | NOT_NULL(" is not null ", "is not null"),;
38 |
39 |
40 | private String code;
41 |
42 | private String desc;
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/SQL.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data;
2 |
3 | import com.github.lit.support.data.domain.TableMetaDate;
4 |
5 | /**
6 | * @author mybaitis
7 | * @version v1.0
8 | * @see org.apache.ibatis.jdbc.SQL
9 | * date 2018-12-10 14:20
10 | */
11 | public class SQL extends AbstractSQL {
12 |
13 | public enum Type {
14 | JDBC,
15 | MYBATIS,
16 | ;
17 | }
18 |
19 |
20 | @Override
21 | public SQL getSelf() {
22 | return this;
23 | }
24 |
25 | public static SQL init() {
26 | return new SQL();
27 | }
28 |
29 | public static SQL baseSelect(Class> cls) {
30 | TableMetaDate metaDate = TableMetaDate.forClass(cls);
31 | return SQL.init().SELECT(metaDate.getBaseColumns()).FROM(metaDate.getTableName());
32 | }
33 |
34 | public static SQL count(Class> cls) {
35 | TableMetaDate metaDate = TableMetaDate.forClass(cls);
36 | return SQL.init().SELECT("count(*)").FROM(metaDate.getTableName());
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/SQLUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data;
2 |
3 | import com.github.lit.support.data.domain.Sort;
4 | import com.github.lit.support.data.domain.TableMetaDate;
5 | import com.github.lit.support.util.bean.BeanUtils;
6 | import org.springframework.util.ReflectionUtils;
7 | import org.springframework.util.StringUtils;
8 |
9 | import java.beans.PropertyDescriptor;
10 | import java.text.MessageFormat;
11 | import java.util.Collection;
12 | import java.util.Map;
13 | import java.util.Objects;
14 | import java.util.Optional;
15 |
16 | /**
17 | * @author liulu
18 | * @version v1.0
19 | * date 2018-12-21 19:57
20 | */
21 | public abstract class SQLUtils {
22 |
23 | /**
24 | * MySQL 分页,参数1 :第几条开始( offset ); 参数2:查询多少条(pageSize)
25 | */
26 | private static final String MYSQL_PAGE_SQL = "%s limit %d, %d ";
27 |
28 | /**
29 | * DB2 分页,参数1 :第几条开始( offset ); 参数2:第几条为止(maxResult)
30 | */
31 | private static final String DB2_PAGE_SQL = "select * from ( select t.*, rownumber() over() rowid from ( %s ) t ) where rowid > %d ) and rowid <= %d ";
32 |
33 | /**
34 | * Oracle 分页,参数1:第几条为止(maxResult); 参数2 :第几条开始( offset )
35 | */
36 | private static final String ORACLE_PAGE_SQL = "select * from (select t.*, rownum rowno from ( %s ) t where rownum <= %d ) where rowno > %d ";
37 |
38 | private SQLUtils() {
39 | }
40 |
41 | public static SQL insertSQL(Object entity, SQL.Type sqlType) {
42 | Objects.requireNonNull(entity, "insert with entity can not be null");
43 | Class> eClass = entity.getClass();
44 | TableMetaDate mataDate = TableMetaDate.forClass(eClass);
45 | Map fieldColumnMap = mataDate.getFieldColumnMap();
46 | SQL sql = SQL.init().INSERT_INTO(mataDate.getTableName());
47 | for (Map.Entry entry : fieldColumnMap.entrySet()) {
48 | // 忽略主键
49 | PropertyDescriptor ps = BeanUtils.getPropertyDescriptor(eClass, entry.getKey());
50 | if (Objects.equals(entry.getKey(), mataDate.getKeyProperty())
51 | || ps == null || ps.getReadMethod() == null) {
52 | continue;
53 | }
54 | Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity);
55 | if (value != null) {
56 | sql.VALUES(entry.getValue(), getTokenParam(entry.getKey(), sqlType));
57 | }
58 | }
59 | return sql;
60 | }
61 |
62 | public static SQL updateSQL(Object entity, Boolean ignoreNull, SQL.Type sqlType) {
63 | Objects.requireNonNull(entity, "update with entity can not be null");
64 | Class> entityClass = entity.getClass();
65 | TableMetaDate mataDate = TableMetaDate.forClass(entityClass);
66 | Map fieldColumnMap = mataDate.getFieldColumnMap();
67 |
68 | SQL sql = SQL.init().UPDATE(mataDate.getTableName());
69 | for (Map.Entry entry : fieldColumnMap.entrySet()) {
70 | // 忽略主键
71 | PropertyDescriptor ps = BeanUtils.getPropertyDescriptor(entityClass, entry.getKey());
72 | if (Objects.equals(entry.getKey(), mataDate.getKeyProperty())
73 | || ps == null || ps.getReadMethod() == null) {
74 | continue;
75 | }
76 | if (ignoreNull) {
77 | Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity);
78 | if (value != null) {
79 | sql.SET(getEq(entry.getValue(), entry.getKey(), sqlType));
80 | }
81 | } else {
82 | sql.SET(getEq(entry.getValue(), entry.getKey(), sqlType));
83 | }
84 | }
85 | sql.WHERE(getEq(mataDate.getKeyColumn(), mataDate.getKeyProperty(), sqlType));
86 | return sql;
87 | }
88 |
89 | public static SQL deleteSQL(Class> eClass, SQL.Type sqlType) {
90 | TableMetaDate mataDate = TableMetaDate.forClass(eClass);
91 | return SQL.init().DELETE_FROM(mataDate.getTableName())
92 | .WHERE(getEq(mataDate.getKeyColumn(), mataDate.getKeyProperty(), sqlType));
93 | }
94 |
95 |
96 | public static SQL selectSQL(Class> eClass, Object condition, Sort sort, SQL.Type sqlType) {
97 |
98 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
99 |
100 | SQL sql = SQL.init().SELECT(metaDate.getBaseColumns()).FROM(metaDate.getTableName());
101 | ReflectionUtils.doWithFields(condition.getClass(), field -> {
102 | Condition logicCondition = field.getAnnotation(Condition.class);
103 | String property = Optional.ofNullable(logicCondition)
104 | .map(Condition::property)
105 | .filter(s -> !s.isEmpty())
106 | .orElse(field.getName());
107 | String mappedColumn = metaDate.getColumn(property);
108 |
109 | if (!metaDate.containsColumn(mappedColumn)) {
110 | return;
111 | }
112 | PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(condition.getClass(), field.getName());
113 | if (pd == null || pd.getReadMethod() == null) {
114 | return;
115 | }
116 | Object value = ReflectionUtils.invokeMethod(pd.getReadMethod(), condition);
117 | String sqlCondition = getCondition(field.getName(), logicCondition, value, sqlType);
118 | if (StringUtils.hasText(sqlCondition)) {
119 | sql.WHERE(mappedColumn + sqlCondition);
120 | }
121 | });
122 | if (sort != null) {
123 | for (Map.Entry entry : sort.getOrderByMap().entrySet()) {
124 | String column = metaDate.getColumn(entry.getKey());
125 | sql.ORDER_BY(column + entry.getValue());
126 | }
127 | }
128 | return sql;
129 | }
130 |
131 | private static String getCondition(String fieldName, Condition logicCondition, Object value, SQL.Type sqlType) {
132 | Logic logic = Optional.ofNullable(logicCondition).map(Condition::logic).orElse(Logic.EQ);
133 | boolean ignoreEmpty = Optional.ofNullable(logicCondition).map(Condition::ignoreEmpty).orElse(true);
134 | if (logic == Logic.NULL || logic == Logic.NOT_NULL) {
135 | return logic.getCode();
136 | }
137 | if (value == null || ("".equals(value) && ignoreEmpty)) {
138 | return "";
139 | }
140 | if (value.getClass().isArray()) {
141 | throw new UnsupportedOperationException("unsupported operation for array params:" + fieldName);
142 | }
143 | if (value instanceof Collection && (logic == Logic.IN || logic == Logic.NOT_IN)) {
144 | int size = ((Collection) value).size();
145 | return logic.getCode() + getIn(fieldName, size, sqlType);
146 | }
147 | return logic.getCode() + getTokenParam(fieldName, sqlType);
148 | }
149 |
150 |
151 | private static String getEq(String column, String param, SQL.Type sqlType) {
152 | return column + Logic.EQ.getCode() + getTokenParam(param, sqlType);
153 | }
154 |
155 | private static String getIn(String property, int size, SQL.Type sqlType) {
156 | if (sqlType == SQL.Type.JDBC) {
157 | return "( :" + property + ")";
158 | }
159 | if (sqlType == SQL.Type.MYBATIS) {
160 | MessageFormat messageFormat = new MessageFormat("#'{'" + property + "[{0}]}");
161 | StringBuilder sb = new StringBuilder(" (");
162 | for (int i = 0; i < size; i++) {
163 | sb.append(messageFormat.format(new Object[]{i}));
164 | if (i != size - 1) {
165 | sb.append(", ");
166 | }
167 | }
168 | return sb.append(")").toString();
169 | }
170 | throw new UnsupportedOperationException("unsupported operation build in with null SQL.Type");
171 | }
172 |
173 |
174 | private static String getTokenParam(String param, SQL.Type sqlType) {
175 | switch (sqlType) {
176 | case JDBC:
177 | return ":" + param;
178 | case MYBATIS:
179 | return "#{" + param + "}";
180 | default:
181 | throw new UnsupportedOperationException("unsupported operation build token param with null SQL.Type");
182 | }
183 | }
184 |
185 | public static String getPageSql(String dbName, String sql, int pageSize, int pageNum) {
186 | if (StringUtils.isEmpty(dbName)) {
187 | throw new UnsupportedOperationException("unsupported operation build page sql unknow database");
188 | }
189 | dbName = dbName.toUpperCase();
190 | switch (dbName) {
191 | case "DB2":
192 | return String.format(DB2_PAGE_SQL, sql, pageSize * (pageNum - 1), pageSize * pageNum);
193 | case "MYSQL":
194 | return String.format(MYSQL_PAGE_SQL, sql, pageSize * (pageNum - 1), pageSize);
195 | case "ORACLE":
196 | return String.format(ORACLE_PAGE_SQL, sql, pageSize * pageNum, pageSize * (pageNum - 1));
197 | default:
198 | throw new UnsupportedOperationException("unsupported operation build page sql for database: " + dbName);
199 | }
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/Page.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import java.util.Collections;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * @author liulu
15 | * @version v1.0
16 | * date 2018-12-15 13:41
17 | */
18 | @ToString
19 | @NoArgsConstructor
20 | public class Page {
21 |
22 | @Getter
23 | @Setter
24 | private List data;
25 |
26 | @Getter
27 | @Setter
28 | private PageInfo pageInfo;
29 |
30 | private Map additional;
31 |
32 | public Page(List data, PageInfo pageInfo) {
33 | this.data = data;
34 | this.pageInfo = pageInfo;
35 | }
36 |
37 | public static Page emptyPage() {
38 | return new Page<>(Collections.emptyList() , PageInfo.EMPTY);
39 | }
40 |
41 |
42 | public void add(String key, Object value) {
43 | if (additional == null) {
44 | additional = new HashMap<>();
45 | }
46 | additional.put(key, value);
47 | }
48 |
49 | public void addAll(Map map) {
50 | if (map == null) {
51 | return;
52 | }
53 | if (additional == null) {
54 | additional = new HashMap<>();
55 | }
56 | additional.putAll(map);
57 | }
58 |
59 | public Map getAdditional() {
60 | if (additional == null) {
61 | return null;
62 | }
63 | return Collections.unmodifiableMap(additional);
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/PageInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | import lombok.Data;
4 | import lombok.NoArgsConstructor;
5 |
6 | import java.io.Serializable;
7 | import java.util.Objects;
8 |
9 | /**
10 | * User : liulu
11 | * Date : 2017/3/20 19:30
12 | * version $Id: PageInfo.java, v 0.1 Exp $
13 | */
14 | @Data
15 | @NoArgsConstructor
16 | public class PageInfo implements Serializable {
17 |
18 | private static final long serialVersionUID = -1073813980324211986L;
19 |
20 | private static final int PAGER_LENGTH = 3;
21 |
22 | public static final PageInfo EMPTY = new PageInfo();
23 |
24 | /**
25 | * 每页记录数
26 | */
27 | private int pageSize;
28 |
29 | /**
30 | * 当前页
31 | */
32 | private int pageNum;
33 |
34 | /**
35 | * 总记录数
36 | */
37 | private int total;
38 |
39 | public PageInfo(int pageSize, int pageNum) {
40 | this.pageSize = pageSize;
41 | this.pageNum = pageNum;
42 | }
43 |
44 | public PageInfo(int pageSize, int pageNum, int total) {
45 | this.pageSize = pageSize;
46 | this.pageNum = pageNum;
47 | this.total = total;
48 | }
49 |
50 | public int getPageNum() {
51 | return Math.min(Math.max(1, pageNum), getTotalPage());
52 | }
53 |
54 | /**
55 | * @return 总页数
56 | */
57 | public int getTotalPage() {
58 | return (total - 1) / pageSize + 1;
59 | }
60 |
61 | /**
62 | * @return 分页条起始页码
63 | */
64 | public int getStart() {
65 | return Math.max(1, Math.min(getPageNum(), getTotalPage() - PAGER_LENGTH) - PAGER_LENGTH);
66 | }
67 |
68 | /**
69 | * @return 分页条结束页码
70 | */
71 | public int getEnd() {
72 | return Math.min(getTotalPage(), Math.max(getPageNum(), PAGER_LENGTH + 1) + PAGER_LENGTH);
73 | }
74 |
75 | public boolean isFirstPage() {
76 | return getPageNum() == 1;
77 | }
78 |
79 | public boolean isLastPage() {
80 | return Objects.equals(getTotalPage(), getPageNum());
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/PageRequest.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | import lombok.NoArgsConstructor;
4 | import lombok.Setter;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * User : liulu
10 | * Date : 2016-10-5 11:03
11 | */
12 | @Setter
13 | @NoArgsConstructor
14 | public class PageRequest implements Pageable, Serializable {
15 |
16 | private static final long serialVersionUID = -2502137541842239335L;
17 |
18 | private static final int MAX_PAGE_SIZE = 200;
19 |
20 | private transient Sort sort;
21 |
22 | /**
23 | * 每页记录数
24 | */
25 | protected int pageSize = 20;
26 |
27 | /**
28 | * 当前页
29 | */
30 | protected int pageNum = 1;
31 |
32 | /**
33 | * 是否查询总记录数
34 | */
35 | protected boolean count = true;
36 |
37 |
38 | public PageRequest(int pageSize, int pageNum) {
39 | this.pageSize = pageSize;
40 | this.pageNum = pageNum;
41 | }
42 |
43 | public PageRequest(int pageSize, int pageNum, boolean count) {
44 | this.pageSize = pageSize;
45 | this.pageNum = pageNum;
46 | this.count = count;
47 | }
48 |
49 | @Override
50 | public int getOffset() {
51 | return getPageSize() * (getPageNum() - 1);
52 | }
53 |
54 | @Override
55 | public int getPageSize() {
56 | return Math.min(MAX_PAGE_SIZE, Math.max(1, pageSize));
57 | }
58 |
59 | @Override
60 | public int getPageNum() {
61 | return Math.max(1, pageNum);
62 | }
63 |
64 | @Override
65 | public boolean isCount() {
66 | return count;
67 | }
68 |
69 | @Override
70 | public Sort getSort() {
71 | return sort;
72 | }
73 |
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/PageUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | import com.github.lit.support.util.bean.BeanUtils;
4 |
5 | import java.util.List;
6 | import java.util.function.BiConsumer;
7 |
8 | /**
9 | * @author liulu
10 | * @version v1.0
11 | * date 2018-12-22 12:53
12 | */
13 | public abstract class PageUtils {
14 |
15 |
16 | public static Page convert(Page sPage, Class tClass) {
17 | return convert(sPage, tClass, null);
18 | }
19 |
20 | public static Page convert(Page sPage, Class tClass, BiConsumer consumer) {
21 | Page result = new Page<>();
22 | result.setPageInfo(sPage.getPageInfo());
23 | result.addAll(sPage.getAdditional());
24 |
25 | List tList = BeanUtils.convertList(tClass, sPage.getData(), consumer);
26 | result.setData(tList);
27 |
28 | return result;
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/Pageable.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | /**
4 | * @author liulu
5 | * @version v1.0
6 | * date 2018-12-21 18:58
7 | */
8 | public interface Pageable {
9 |
10 |
11 | int getPageNum();
12 |
13 | int getPageSize();
14 |
15 | int getOffset();
16 |
17 | Sort getSort();
18 |
19 | default boolean isCount() {
20 | return true;
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/Sort.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | import com.github.lit.support.util.lamabda.SerializedFunction;
4 | import com.github.lit.support.util.lamabda.SerializedLambdaUtils;
5 |
6 | import java.util.Collections;
7 | import java.util.LinkedHashMap;
8 | import java.util.Map;
9 | import java.util.Objects;
10 |
11 | /**
12 | * not thread safe
13 | *
14 | * @author liulu
15 | * @version v1.0
16 | * date 2019-07-26
17 | */
18 | public class Sort {
19 |
20 | private static final String ORDER_ASC = " ASC";
21 | private static final String ORDER_DESC = " DESC";
22 |
23 | private static final String DEFAULT_MESSAGE = "sort properties must not null!";
24 |
25 | private Map orderByMap = new LinkedHashMap<>();
26 |
27 | public static Sort init() {
28 | return new Sort();
29 | }
30 |
31 | public Sort asc(String... properties) {
32 | Objects.requireNonNull(properties, DEFAULT_MESSAGE);
33 | for (String property : properties) {
34 | orderByMap.put(property, ORDER_ASC);
35 | }
36 | return this;
37 | }
38 |
39 | public Sort desc(String... properties) {
40 | Objects.requireNonNull(properties, DEFAULT_MESSAGE);
41 | for (String property : properties) {
42 | orderByMap.put(property, ORDER_DESC);
43 | }
44 | return this;
45 | }
46 |
47 | @SafeVarargs
48 | public final Sort asc(SerializedFunction... serializedFunctions) {
49 | return addSort(ORDER_ASC, serializedFunctions);
50 | }
51 |
52 | @SafeVarargs
53 | public final Sort desc(SerializedFunction... serializedFunctions) {
54 | return addSort(ORDER_DESC, serializedFunctions);
55 | }
56 |
57 | @SafeVarargs
58 | private final Sort addSort(String direction, SerializedFunction... serializedFunctions) {
59 | Objects.requireNonNull(serializedFunctions, DEFAULT_MESSAGE);
60 | for (SerializedFunction serializedFunction : serializedFunctions) {
61 | String property = SerializedLambdaUtils.getProperty(serializedFunction);
62 | orderByMap.put(property, direction);
63 | }
64 | return this;
65 | }
66 |
67 | public Map getOrderByMap() {
68 | return Collections.unmodifiableMap(orderByMap);
69 | }
70 |
71 | @Override
72 | public String toString() {
73 | StringBuilder sb = new StringBuilder();
74 | for (Map.Entry entry : orderByMap.entrySet()) {
75 | if (sb.length() > 0) {
76 | sb.append(", ");
77 | }
78 | sb.append(entry.getKey()).append(entry.getValue());
79 | }
80 | return sb.toString();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/domain/TableMetaDate.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.domain;
2 |
3 | import com.github.lit.support.util.ClassUtils;
4 | import com.github.lit.support.util.NameUtils;
5 | import com.github.lit.support.util.bean.BeanUtils;
6 | import com.github.lit.support.util.lamabda.SerializedFunction;
7 | import com.github.lit.support.util.lamabda.SerializedLambdaUtils;
8 | import lombok.Getter;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Id;
12 | import javax.persistence.Table;
13 | import javax.persistence.Transient;
14 | import java.beans.PropertyDescriptor;
15 | import java.io.Serializable;
16 | import java.lang.reflect.Field;
17 | import java.lang.reflect.Modifier;
18 | import java.util.*;
19 |
20 | /**
21 | * @author liulu
22 | * @version : v1.0
23 | * date : 7/24/18 11:31
24 | */
25 | @Getter
26 | public class TableMetaDate implements Serializable {
27 |
28 | private static final long serialVersionUID = 7433386817779746930L;
29 |
30 | private static final int DEFAULT_CACHE_LIMIT = 128;
31 |
32 | @SuppressWarnings("serial")
33 | private static final Map, TableMetaDate> TABLE_CACHE =
34 | new LinkedHashMap, TableMetaDate>(DEFAULT_CACHE_LIMIT, 0.75f, true) {
35 | @Override
36 | protected boolean removeEldestEntry(Map.Entry, TableMetaDate> eldest) {
37 | return size() > DEFAULT_CACHE_LIMIT;
38 | }
39 | };
40 |
41 | private Class> entityClass;
42 |
43 | /**
44 | * 表名
45 | */
46 | private String tableName;
47 |
48 | /**
49 | * 主键属性名
50 | */
51 | private String keyProperty;
52 |
53 | /**
54 | * 主键对应的列名
55 | */
56 | private String keyColumn;
57 |
58 | /**
59 | * 属性名和字段名映射关系的 map
60 | */
61 | private Map fieldColumnMap;
62 |
63 | /**
64 | * 字段类型
65 | */
66 | private Map> fieldTypeMap;
67 |
68 | private TableMetaDate(Class> clazz) {
69 | fieldColumnMap = new HashMap<>();
70 | fieldTypeMap = new HashMap<>();
71 | initTableInfo(clazz);
72 | }
73 |
74 |
75 | public static TableMetaDate forClass(Class> entityClass) {
76 | synchronized (TABLE_CACHE) {
77 | return TABLE_CACHE.computeIfAbsent(entityClass, TableMetaDate::new);
78 | }
79 | }
80 |
81 | public String getBaseColumns() {
82 | Collection columns = fieldColumnMap.values();
83 | if (columns.isEmpty()) {
84 | return "";
85 | }
86 | Iterator iterator = columns.iterator();
87 | StringBuilder sb = new StringBuilder();
88 | while (iterator.hasNext()) {
89 | String next = iterator.next();
90 | sb.append(tableName).append(".").append(next);
91 | if (iterator.hasNext()) {
92 | sb.append(", ");
93 | }
94 | }
95 | return sb.toString();
96 | }
97 |
98 | /**
99 | * 根据注解初始化表信息,
100 | *
101 | * @param eClass 实体类的 class
102 | */
103 | private void initTableInfo(Class> eClass) {
104 | entityClass = eClass;
105 | Table tableAnnotation = eClass.getAnnotation(Table.class);
106 | tableName = tableAnnotation != null ? tableAnnotation.name() : NameUtils.getUnderLineName(eClass.getSimpleName());
107 |
108 | Field[] fields = eClass.getDeclaredFields();
109 | for (Field field : fields) {
110 |
111 | // 过滤静态字段和有 @Transient 注解的字段
112 | if (Modifier.isStatic(field.getModifiers()) ||
113 | field.isAnnotationPresent(Transient.class) ||
114 | !ClassUtils.isSimpleProperty(field.getType())) {
115 | continue;
116 | }
117 |
118 | String property = field.getName();
119 | Column column = field.getAnnotation(Column.class);
120 | String columnName = column != null ? column.name() : NameUtils.getUnderLineName(property);
121 |
122 | // 主键信息 : 有 @Id 注解的字段,没有默认是 类名+Id
123 | if (field.isAnnotationPresent(Id.class) || (property.equalsIgnoreCase("id") && keyProperty == null)) {
124 | this.keyProperty = property;
125 | this.keyColumn = columnName;
126 | }
127 | // 将字段对应的列放到 map 中
128 | PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(eClass, property);
129 | if (descriptor != null && descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) {
130 | fieldColumnMap.put(property, columnName);
131 | fieldTypeMap.put(property, field.getType());
132 | }
133 | }
134 | fieldColumnMap = Collections.unmodifiableMap(fieldColumnMap);
135 | fieldTypeMap = Collections.unmodifiableMap(fieldTypeMap);
136 | }
137 |
138 |
139 | public String getColumn(SerializedFunction function) {
140 | Class lambdaClass = SerializedLambdaUtils.getLambdaClass(function);
141 | // 如果不是实体class的父类
142 | if (!lambdaClass.isAssignableFrom(entityClass)) {
143 | throw new IllegalArgumentException("illegal argument");
144 | }
145 | String property = SerializedLambdaUtils.getProperty(function);
146 | return fieldColumnMap.get(property);
147 | }
148 |
149 | public String getColumn(String field) {
150 | String column = fieldColumnMap.get(field);
151 | return column == null || column.isEmpty() ? field : column;
152 | }
153 |
154 | public Boolean containsField(String field) {
155 | return fieldColumnMap.containsKey(field);
156 | }
157 |
158 | public Boolean containsColumn(String column) {
159 | return fieldColumnMap.containsValue(column);
160 | }
161 |
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/jdbc/AnnotationRowMapper.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.jdbc;
2 |
3 | import com.github.lit.support.util.NameUtils;
4 | import org.springframework.beans.BeanUtils;
5 | import org.springframework.core.annotation.AnnotationUtils;
6 | import org.springframework.jdbc.core.BeanPropertyRowMapper;
7 | import org.springframework.util.ReflectionUtils;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Transient;
11 | import java.beans.PropertyDescriptor;
12 | import java.lang.reflect.Field;
13 | import java.lang.reflect.Modifier;
14 | import java.util.Map;
15 | import java.util.Set;
16 |
17 | /**
18 | * @author liulu
19 | * @version v1.0
20 | * date 2018-12-15 21:42
21 | */
22 | public class AnnotationRowMapper extends BeanPropertyRowMapper {
23 |
24 | public AnnotationRowMapper() {
25 | }
26 |
27 | public AnnotationRowMapper(Class mappedClass) {
28 | initialize(mappedClass);
29 | }
30 |
31 | @SuppressWarnings({"ConstantConditions", "unchecked"})
32 | @Override
33 | protected void initialize(Class mappedClass) {
34 | super.initialize(mappedClass);
35 |
36 | Field mappedFields = ReflectionUtils.findField(this.getClass(), "mappedFields");
37 | ReflectionUtils.makeAccessible(mappedFields);
38 | Field mappedProperties = ReflectionUtils.findField(this.getClass(), "mappedProperties");
39 | ReflectionUtils.makeAccessible(mappedProperties);
40 |
41 | Map mappedFieldsMap = (Map) ReflectionUtils.getField(mappedFields, this);
42 | Set mappedPropertiesSet = (Set) ReflectionUtils.getField(mappedProperties, this);
43 |
44 | ReflectionUtils.doWithFields(mappedClass, field -> {
45 | if (Modifier.isStatic(field.getModifiers()) ||
46 | field.isAnnotationPresent(Transient.class) ||
47 | !BeanUtils.isSimpleValueType(field.getType())) {
48 | return;
49 | }
50 | PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(mappedClass, field.getName());
51 | if (pd != null && pd.getWriteMethod() != null) {
52 | Column column = AnnotationUtils.findAnnotation(field, Column.class);
53 | String columnName = column != null ? column.name().toLowerCase()
54 | : NameUtils.getUnderLineName(field.getName());
55 | mappedFieldsMap.putIfAbsent(columnName, pd);
56 | String lowerPdName = pd.getName().toLowerCase();
57 | if (!lowerPdName.equals(columnName)) {
58 | mappedFieldsMap.putIfAbsent(lowerPdName, pd);
59 | }
60 | mappedPropertiesSet.add(pd.getName());
61 | }
62 | });
63 | }
64 |
65 |
66 | /**
67 | * Static factory method to create a new {@code AnnotationRowMapper}
68 | * (with the mapped class specified only once).
69 | *
70 | * @param mappedClass the class that each row should be mapped to
71 | */
72 | public static AnnotationRowMapper newInstance(Class mappedClass) {
73 | return new AnnotationRowMapper<>(mappedClass);
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/jdbc/EnableJdbcSupport.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.jdbc;
2 |
3 | import org.springframework.context.annotation.Import;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * @author liulu
12 | * @version v1.0
13 | * date 2018-12-22 13:18
14 | */
15 | @Target({ElementType.TYPE})
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Import({JdbcSupportConfigure.class})
18 | public @interface EnableJdbcSupport {
19 | }
20 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/jdbc/JdbcRepository.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.jdbc;
2 |
3 | import com.github.lit.support.data.SQL;
4 | import com.github.lit.support.data.domain.Page;
5 | import com.github.lit.support.data.domain.Pageable;
6 | import com.github.lit.support.data.domain.Sort;
7 | import com.github.lit.support.util.lamabda.SerializedFunction;
8 | import org.springframework.stereotype.Repository;
9 |
10 | import java.util.Collection;
11 | import java.util.List;
12 |
13 | /**
14 | * @author liulu
15 | * @version v1.0
16 | * date 2018-12-09 23:03
17 | */
18 | @Repository
19 | public interface JdbcRepository {
20 |
21 | int insert(E entity);
22 |
23 | int batchInsert(Collection eList);
24 |
25 | int update(E entity);
26 |
27 | int updateSelective(E entity);
28 |
29 | int delete(E entity);
30 |
31 | int deleteById(Class eClass, Long id);
32 |
33 | int deleteByIds(Class eClass, Collection ids);
34 |
35 | E selectById(Class eClass, Long id);
36 |
37 | List selectByIds(Class eClass, Collection ids);
38 |
39 | List selectAll(Class eClass);
40 |
41 | E selectByProperty(SerializedFunction serializedFunction, Object value);
42 |
43 | List selectListByProperty(SerializedFunction serializedFunction, Object value);
44 |
45 | List selectList(Class eClass, C condition);
46 |
47 | List selectListWithOrder(Class eClass, C condition, Sort sort);
48 |
49 | Page selectPageList(Class eClass, C condition);
50 |
51 | E selectForObject(SQL sql, Object args, Class requiredType);
52 |
53 | List selectForList(SQL sql, Object args, Class requiredType);
54 |
55 | Page selectForPageList(SQL sql, Pageable args, Class requiredType);
56 |
57 | int count(Class eClass);
58 |
59 | int countByProperty(SerializedFunction serializedFunction, Object value);
60 |
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/jdbc/JdbcRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.jdbc;
2 |
3 | import com.github.lit.support.data.SQL;
4 | import com.github.lit.support.data.SQLUtils;
5 | import com.github.lit.support.data.domain.*;
6 | import com.github.lit.support.util.ClassUtils;
7 | import com.github.lit.support.util.bean.BeanUtils;
8 | import com.github.lit.support.util.lamabda.SerializedFunction;
9 | import com.github.lit.support.util.lamabda.SerializedLambdaUtils;
10 | import lombok.Getter;
11 | import lombok.NoArgsConstructor;
12 | import lombok.Setter;
13 | import lombok.extern.slf4j.Slf4j;
14 | import org.springframework.dao.IncorrectResultSizeDataAccessException;
15 | import org.springframework.jdbc.core.ConnectionCallback;
16 | import org.springframework.jdbc.core.namedparam.EmptySqlParameterSource;
17 | import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
18 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
19 | import org.springframework.jdbc.core.namedparam.SqlParameterSource;
20 | import org.springframework.jdbc.support.GeneratedKeyHolder;
21 | import org.springframework.jdbc.support.KeyHolder;
22 | import org.springframework.util.Assert;
23 | import org.springframework.util.CollectionUtils;
24 | import org.springframework.util.ReflectionUtils;
25 | import org.springframework.util.StringUtils;
26 |
27 | import java.beans.PropertyDescriptor;
28 | import java.util.*;
29 |
30 | /**
31 | * @author liulu
32 | * @version v1.0
33 | * date 2018-12-10 14:28
34 | */
35 | @Slf4j
36 | @NoArgsConstructor
37 | public class JdbcRepositoryImpl implements JdbcRepository {
38 |
39 | private static final String PARAM = "param";
40 |
41 | private static final String PARAM_EQ = " = :param";
42 |
43 | private static final String PARAM_IN = " in (:param)";
44 |
45 | @Setter
46 | private String dbName;
47 |
48 | @Getter
49 | @Setter
50 | private NamedParameterJdbcOperations jdbcOperations;
51 |
52 |
53 | private String getDbName() {
54 | if (StringUtils.isEmpty(dbName)) {
55 | dbName = jdbcOperations.getJdbcOperations()
56 | .execute((ConnectionCallback) con -> con.getMetaData().getDatabaseProductName());
57 | }
58 | return dbName;
59 | }
60 |
61 | public JdbcRepositoryImpl(NamedParameterJdbcOperations jdbcOperations) {
62 | this.jdbcOperations = jdbcOperations;
63 | }
64 |
65 | @Override
66 | public int insert(E entity) {
67 | Objects.requireNonNull(entity, "insert with entity can not be null");
68 | Class> entityClass = entity.getClass();
69 | TableMetaDate metaDate = TableMetaDate.forClass(entityClass);
70 | String sql = SQLUtils.insertSQL(entity, SQL.Type.JDBC).toString();
71 | KeyHolder keyHolder = new GeneratedKeyHolder();
72 | SqlParameterSource sqlParameterSource = getSqlParameterSource(entity);
73 | logSqlAndParams(sql, sqlParameterSource);
74 | int insert = jdbcOperations.update(sql, sqlParameterSource, keyHolder);
75 | PropertyDescriptor keyPs = BeanUtils.getPropertyDescriptor(entityClass, metaDate.getKeyProperty());
76 | // set key property
77 | if (keyPs != null) {
78 | ReflectionUtils.invokeMethod(keyPs.getWriteMethod(), entity,
79 | Objects.requireNonNull(keyHolder.getKey()).longValue());
80 | }
81 | return insert;
82 | }
83 |
84 | @Override
85 | public int batchInsert(Collection eList) {
86 | if (CollectionUtils.isEmpty(eList)) {
87 | return 0;
88 | }
89 | E entity = eList.iterator().next();
90 | SQL sql = SQLUtils.insertSQL(entity, SQL.Type.JDBC);
91 |
92 | SqlParameterSource[] parameterSources = eList.stream()
93 | .map(this::getSqlParameterSource).toArray(SqlParameterSource[]::new);
94 | int[] updateResult = jdbcOperations.batchUpdate(sql.toString(), parameterSources);
95 |
96 | int row = 0;
97 | for (int res : updateResult) {
98 | row += res;
99 | }
100 | return row;
101 | }
102 |
103 |
104 | @Override
105 | public int update(E entity) {
106 | SQL sql = SQLUtils.updateSQL(entity, false, SQL.Type.JDBC);
107 | return jdbcOperations.update(sql.toString(), getSqlParameterSource(entity));
108 | }
109 |
110 | @Override
111 | public int updateSelective(E entity) {
112 | String sql = SQLUtils.updateSQL(entity, true, SQL.Type.JDBC).toString();
113 | SqlParameterSource sqlParameterSource = getSqlParameterSource(entity);
114 | logSqlAndParams(sql, sqlParameterSource);
115 | return jdbcOperations.update(sql, sqlParameterSource);
116 | }
117 |
118 | @Override
119 | public int delete(E entity) {
120 | Assert.notNull(entity, "deleteById with entity can not be null");
121 | TableMetaDate metaDate = TableMetaDate.forClass(entity.getClass());
122 | PropertyDescriptor keyPs = BeanUtils.getPropertyDescriptor(entity.getClass(), metaDate.getKeyProperty());
123 | Assert.notNull(keyPs, "can not find key property from " + entity.getClass().getName());
124 | Object keyValue = ReflectionUtils.invokeMethod(keyPs.getReadMethod(), entity);
125 | Assert.notNull(keyValue, "key value can not be null");
126 |
127 | String sql = SQLUtils.deleteSQL(entity.getClass(), SQL.Type.JDBC).toString();
128 | SqlParameterSource sqlParam = getSqlParameterSource(Collections.singletonMap(metaDate.getKeyProperty(), keyValue));
129 | logSqlAndParams(sql, sqlParam);
130 | return jdbcOperations.update(sql, sqlParam);
131 | }
132 |
133 | @Override
134 | public int deleteById(Class eClass, Long id) {
135 | Assert.notNull(id, "id can not be null");
136 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
137 | String sql = SQLUtils.deleteSQL(eClass, SQL.Type.JDBC).toString();
138 | SqlParameterSource sqlParam = getSqlParameterSource(Collections.singletonMap(metaDate.getKeyProperty(), id));
139 | logSqlAndParams(sql, sqlParam);
140 | return jdbcOperations.update(sql, sqlParam);
141 | }
142 |
143 | @Override
144 | public int deleteByIds(Class eClass, Collection ids) {
145 | if (CollectionUtils.isEmpty(ids)) {
146 | return 0;
147 | }
148 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
149 | String sql = SQL.init().DELETE_FROM(metaDate.getTableName())
150 | .WHERE(metaDate.getKeyColumn() + PARAM_IN)
151 | .toString();
152 | SqlParameterSource sqlParam = getSqlParameterSource(Collections.singletonMap(PARAM, ids));
153 | logSqlAndParams(sql, sqlParam);
154 | return jdbcOperations.update(sql, sqlParam);
155 | }
156 |
157 | @Override
158 | public E selectById(Class eClass, Long id) {
159 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
160 |
161 | SQL sql = SQL.init().SELECT(metaDate.getBaseColumns())
162 | .FROM(metaDate.getTableName())
163 | .WHERE(metaDate.getKeyColumn() + PARAM_EQ);
164 |
165 | return selectForObject(sql, Collections.singletonMap(PARAM, id), eClass);
166 | }
167 |
168 | @Override
169 | public List selectByIds(Class eClass, Collection ids) {
170 | if (CollectionUtils.isEmpty(ids)) {
171 | return Collections.emptyList();
172 | }
173 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
174 |
175 | SQL sql = SQL.init().SELECT(metaDate.getBaseColumns())
176 | .FROM(metaDate.getTableName())
177 | .WHERE(metaDate.getKeyColumn() + PARAM_IN);
178 |
179 | return selectForList(sql, Collections.singletonMap(PARAM, ids), eClass);
180 | }
181 |
182 | @Override
183 | public List selectAll(Class eClass) {
184 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
185 | String sql = SQL.init().SELECT(metaDate.getBaseColumns())
186 | .FROM(metaDate.getTableName())
187 | .toString();
188 | logSqlAndParams(sql, null);
189 | return jdbcOperations.query(sql, Collections.emptyMap(), AnnotationRowMapper.newInstance(eClass));
190 | }
191 |
192 | @Override
193 | public E selectByProperty(SerializedFunction serializedFunction, Object value) {
194 | Class eClass = SerializedLambdaUtils.getLambdaClass(serializedFunction);
195 | SQL sql = getSelectByPropertySql(serializedFunction, eClass);
196 | return selectForObject(sql, Collections.singletonMap(PARAM, value), eClass);
197 | }
198 |
199 | @Override
200 | public List selectListByProperty(SerializedFunction serializedFunction, Object value) {
201 | Class eClass = SerializedLambdaUtils.getLambdaClass(serializedFunction);
202 | String sql = getSelectByPropertySql(serializedFunction, eClass).toString();
203 | SqlParameterSource sqlParams = getSqlParameterSource(Collections.singletonMap(PARAM, value));
204 | logSqlAndParams(sql, sqlParams);
205 | return jdbcOperations.query(sql, sqlParams, AnnotationRowMapper.newInstance(eClass));
206 | }
207 |
208 | private SQL getSelectByPropertySql(SerializedFunction serializedFunction, Class eClass) {
209 | String property = SerializedLambdaUtils.getProperty(serializedFunction);
210 |
211 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
212 | String column = metaDate.getFieldColumnMap().get(property);
213 |
214 | return SQL.init().SELECT(metaDate.getBaseColumns())
215 | .FROM(metaDate.getTableName())
216 | .WHERE(column + PARAM_EQ);
217 | }
218 |
219 | @Override
220 | public List selectList(Class eClass, C condition) {
221 | return selectListWithOrder(eClass, condition, null);
222 | }
223 |
224 | @Override
225 | public List selectListWithOrder(Class eClass, C condition, Sort sort) {
226 | String sql = SQLUtils.selectSQL(eClass, condition, sort, SQL.Type.JDBC).toString();
227 | SqlParameterSource sqlParams = getSqlParameterSource(condition);
228 | logSqlAndParams(sql, sqlParams);
229 | return jdbcOperations.query(sql, sqlParams, AnnotationRowMapper.newInstance(eClass));
230 | }
231 |
232 | @Override
233 | public Page selectPageList(Class eClass, C condition) {
234 |
235 | SQL sql = SQLUtils.selectSQL(eClass, condition, condition.getSort(), SQL.Type.JDBC);
236 | return selectForPageList(sql, condition, eClass);
237 | }
238 |
239 | @Override
240 | public E selectForObject(SQL sql, Object args, Class requiredType) {
241 | List rs = selectForList(sql, args, requiredType);
242 | if (CollectionUtils.isEmpty(rs)) {
243 | return null;
244 | }
245 | if (rs.size() > 1) {
246 | throw new IncorrectResultSizeDataAccessException(1, rs.size());
247 | }
248 | return rs.iterator().next();
249 | }
250 |
251 | @Override
252 | public List selectForList(SQL sql, Object args, Class requiredType) {
253 | if (args == null) {
254 | args = Collections.emptyMap();
255 | }
256 | String sqlStr = sql.toString();
257 | SqlParameterSource parameterSource = getSqlParameterSource(args);
258 | logSqlAndParams(sqlStr, parameterSource);
259 | if (ClassUtils.isSimpleValueType(requiredType)) {
260 | return jdbcOperations.queryForList(sqlStr, parameterSource, requiredType);
261 | }
262 | return jdbcOperations.query(sqlStr, parameterSource, AnnotationRowMapper.newInstance(requiredType));
263 | }
264 |
265 | @Override
266 | public Page selectForPageList(SQL sql, Pageable args, Class requiredType) {
267 | Integer count = 0;
268 | SqlParameterSource sqlParameterSource = getSqlParameterSource(args);
269 | if (args.isCount()) {
270 | String countSql = sql.countSql();
271 | logSqlAndParams(countSql, sqlParameterSource);
272 | count = jdbcOperations.queryForObject(countSql, sqlParameterSource, int.class);
273 | if (count == null || count <= 0) {
274 | return Page.emptyPage();
275 | }
276 | }
277 | String pageSql = SQLUtils.getPageSql(getDbName(), sql.toString(), args.getPageSize(), args.getPageNum());
278 | logSqlAndParams(pageSql, sqlParameterSource);
279 | List rs = jdbcOperations.query(pageSql, sqlParameterSource, AnnotationRowMapper.newInstance(requiredType));
280 |
281 | PageInfo pageInfo = new PageInfo(args.getPageSize(), args.getPageNum(), count);
282 | return new Page<>(rs, pageInfo);
283 | }
284 |
285 | @Override
286 | public int count(Class eClass) {
287 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
288 | SQL sql = SQL.init().SELECT("count(*)")
289 | .FROM(metaDate.getTableName());
290 | return selectForObject(sql, Collections.emptyMap(), int.class);
291 | }
292 |
293 | @Override
294 | public int countByProperty(SerializedFunction serializedFunction, Object value) {
295 | Class eClass = SerializedLambdaUtils.getLambdaClass(serializedFunction);
296 | String property = SerializedLambdaUtils.getProperty(serializedFunction);
297 |
298 | TableMetaDate metaDate = TableMetaDate.forClass(eClass);
299 |
300 | SQL sql = SQL.init().SELECT("count(*)")
301 | .FROM(metaDate.getTableName())
302 | .WHERE(metaDate.getColumn(property) + PARAM_EQ);
303 |
304 | return selectForObject(sql, Collections.singletonMap(PARAM, value), int.class);
305 | }
306 |
307 |
308 | private void logSqlAndParams(String sql, SqlParameterSource params) {
309 | if (params == null || params.getParameterNames() == null) {
310 | log.info("\n sql: {} \n params: ", sql);
311 | return;
312 | }
313 | StringBuilder paramLog = new StringBuilder();
314 | for (String parameterName : params.getParameterNames()) {
315 | Object value = params.getValue(parameterName);
316 | if (!StringUtils.isEmpty(value)) {
317 | paramLog.append(parameterName).append("=").append(value).append(", ");
318 | }
319 | }
320 | log.info("\n sql: {} \n params: {}", sql, paramLog);
321 | }
322 |
323 | private SqlParameterSource getSqlParameterSource(E params) {
324 | if (params == null) {
325 | return new EmptySqlParameterSource();
326 | }
327 | Map paramMap = params instanceof Map ? (Map) params : BeanUtils.beanToMap(params);
328 | return new MapSqlParameterSource(paramMap);
329 | }
330 |
331 | }
332 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/jdbc/JdbcSupportConfigure.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.jdbc;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.ApplicationContext;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.core.annotation.Order;
7 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
8 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
9 | import org.springframework.util.StringUtils;
10 |
11 | import javax.sql.DataSource;
12 | import java.util.Map;
13 |
14 | /**
15 | * @author liulu
16 | * @version v1.0
17 | * date 2018-12-22 13:02
18 | */
19 | @Order
20 | public class JdbcSupportConfigure {
21 |
22 | @Value("${lit.support.jdbc.database:}")
23 | private String database;
24 |
25 | @Value("${lit.support.jdbc.dataSource:}")
26 | private String dataSourceName;
27 |
28 | @Value("${lit.support.jdbc.template:}")
29 | private String templateName;
30 |
31 | @Bean
32 | public JdbcRepository jdbcRepository(ApplicationContext context) {
33 | JdbcRepositoryImpl jdbcRepository = new JdbcRepositoryImpl();
34 | if (StringUtils.hasText(database)) {
35 | jdbcRepository.setDbName(database.toUpperCase());
36 | }
37 |
38 | Map jdbcOperationsBeans
39 | = context.getBeansOfType(NamedParameterJdbcOperations.class);
40 | if (jdbcOperationsBeans == null || jdbcOperationsBeans.isEmpty()) {
41 | Map dataSourceBeans = context.getBeansOfType(DataSource.class);
42 | if (dataSourceBeans == null || dataSourceBeans.isEmpty()) {
43 | throw new IllegalArgumentException("to enable jdbcRepository, need config DataSource or JdbcOperations bean");
44 | }
45 | if (StringUtils.isEmpty(dataSourceName)) {
46 | DataSource dataSource = dataSourceBeans.values().iterator().next();
47 | jdbcRepository.setJdbcOperations(new NamedParameterJdbcTemplate(dataSource));
48 | return jdbcRepository;
49 | }
50 | DataSource dataSource = dataSourceBeans.get(dataSourceName);
51 | if (dataSource == null) {
52 | throw new IllegalArgumentException("no DataSource bean named: " + dataSourceName);
53 | }
54 | jdbcRepository.setJdbcOperations(new NamedParameterJdbcTemplate(dataSource));
55 | return jdbcRepository;
56 | }
57 |
58 | if (StringUtils.isEmpty(templateName)) {
59 | jdbcRepository.setJdbcOperations(jdbcOperationsBeans.values().iterator().next());
60 | return jdbcRepository;
61 | }
62 | NamedParameterJdbcOperations jdbcOperations = jdbcOperationsBeans.get(templateName);
63 | if (jdbcOperations == null) {
64 | throw new IllegalArgumentException("no NamedParameterJdbcOperations bean named: " + templateName);
65 | }
66 | jdbcRepository.setJdbcOperations(jdbcOperations);
67 |
68 | return jdbcRepository;
69 | }
70 |
71 |
72 |
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/mybatis/BaseMapper.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.mybatis;
2 |
3 | import com.github.lit.support.util.lamabda.SerializedFunction;
4 | import org.apache.ibatis.annotations.DeleteProvider;
5 | import org.apache.ibatis.annotations.InsertProvider;
6 | import org.apache.ibatis.annotations.Options;
7 | import org.apache.ibatis.annotations.Param;
8 | import org.apache.ibatis.annotations.SelectProvider;
9 | import org.apache.ibatis.annotations.UpdateProvider;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * @author liulu
15 | * @version : v1.0
16 | * date : 7/24/18 09:54
17 | */
18 | public interface BaseMapper {
19 |
20 | /**
21 | * 新增一条记录
22 | *
23 | * @param entity 实体
24 | * @return 受影响记录
25 | */
26 | @InsertProvider(type = BaseSqlProvider.class, method = "insert")
27 | @Options(useGeneratedKeys = true, keyColumn = "id")
28 | int insert(E entity);
29 |
30 | /**
31 | * 更新一条记录
32 | *
33 | * @param entity entity
34 | * @return 受影响记录
35 | */
36 | @UpdateProvider(type = BaseSqlProvider.class, method = "update")
37 | int update(E entity);
38 |
39 | /**
40 | * 删除一条记录
41 | *
42 | * @param id id
43 | * @return 受影响记录
44 | */
45 | @DeleteProvider(type = BaseSqlProvider.class, method = "deleteById")
46 | int deleteById(Long id);
47 |
48 | /**
49 | * 根据id查询
50 | *
51 | * @param id id
52 | * @return Entity
53 | */
54 | @SelectProvider(type = BaseSqlProvider.class, method = "selectById")
55 | E selectById(Long id);
56 |
57 | /**
58 | * 根据属性查询一条记录
59 | *
60 | * @param function property
61 | * @param value value
62 | * @param R
63 | * @return Entity
64 | */
65 | @SelectProvider(type = BaseSqlProvider.class, method = "selectByProperty")
66 | E selectByProperty(@Param("property") SerializedFunction function, @Param("value") Object value);
67 |
68 | /**
69 | * 根据属性查询记录列表
70 | *
71 | * @param function property
72 | * @param value value
73 | * @param R
74 | * @return Entity
75 | */
76 | @SelectProvider(type = BaseSqlProvider.class, method = "selectByProperty")
77 | List selectListByProperty(@Param("property") SerializedFunction function, @Param("value") Object value);
78 |
79 | /**
80 | * 根据查询条件查询记录
81 | *
82 | * @param condition condition
83 | * @param Condition
84 | * @return List Entity
85 | */
86 | @SelectProvider(type = BaseSqlProvider.class, method = "selectList")
87 | List selectList(C condition);
88 |
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/mybatis/BaseSqlProvider.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.mybatis;
2 |
3 | import com.github.lit.support.data.Logic;
4 | import com.github.lit.support.data.SQL;
5 | import com.github.lit.support.data.SQLUtils;
6 | import com.github.lit.support.data.domain.TableMetaDate;
7 | import com.github.lit.support.util.lamabda.SerializedFunction;
8 | import com.github.lit.support.util.lamabda.SerializedLambdaUtils;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.apache.ibatis.builder.annotation.ProviderContext;
11 | import org.springframework.core.ResolvableType;
12 | import org.springframework.util.Assert;
13 |
14 | import java.lang.reflect.Type;
15 | import java.util.Map;
16 |
17 | /**
18 | * @author liulu
19 | * @version : v1.0
20 | * date : 7/24/18 11:04
21 | */
22 | @Slf4j
23 | public class BaseSqlProvider {
24 |
25 | public String insert(E entity) {
26 | Assert.notNull(entity, "entity must not null");
27 | return SQLUtils.insertSQL(entity, SQL.Type.MYBATIS).toString();
28 | }
29 |
30 | public String update(E entity) {
31 | Assert.notNull(entity, "entity must not null");
32 |
33 | return SQLUtils.updateSQL(entity, true, SQL.Type.MYBATIS).toString();
34 | }
35 |
36 | public String delete(ProviderContext context) {
37 | Class> entityClass = getEntityClass(context);
38 | return SQLUtils.deleteSQL(entityClass, SQL.Type.MYBATIS).toString();
39 | }
40 |
41 | public String selectById(ProviderContext context) {
42 | Class> entityClass = getEntityClass(context);
43 | TableMetaDate mataDate = TableMetaDate.forClass(entityClass);
44 |
45 | return new SQL().SELECT(mataDate.getBaseColumns())
46 | .FROM(mataDate.getTableName())
47 | .WHERE(mataDate.getKeyColumn() + Logic.EQ.getCode() + "#{" + mataDate.getKeyProperty() + "}")
48 | .toString();
49 | }
50 |
51 | public String selectByProperty(ProviderContext context, Map params) {
52 | SerializedFunction propertyFunction = (SerializedFunction) params.get("property");
53 | String property = SerializedLambdaUtils.getProperty(propertyFunction);
54 | Class> entityClass = getEntityClass(context);
55 | TableMetaDate mataDate = TableMetaDate.forClass(entityClass);
56 | String column = mataDate.getColumn(property);
57 |
58 | return new SQL().SELECT(mataDate.getBaseColumns())
59 | .FROM(mataDate.getTableName())
60 | .WHERE(column + Logic.EQ.getCode() + "#{value}")
61 | .toString();
62 | }
63 |
64 | public String selectByCondition(ProviderContext context, Object condition) {
65 | Class> entityClass = getEntityClass(context);
66 | return SQLUtils
67 | .selectSQL(entityClass, condition, null, SQL.Type.MYBATIS)
68 | .toString();
69 | }
70 |
71 | private Class> getEntityClass(ProviderContext context) {
72 | Class> mapperType = context.getMapperType();
73 | for (Type parent : mapperType.getGenericInterfaces()) {
74 | ResolvableType parentType = ResolvableType.forType(parent);
75 | if (parentType.getRawClass() == BaseMapper.class) {
76 | return parentType.getGeneric(0).getRawClass();
77 | }
78 | }
79 | return null;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/mybatis/EnambeMybatisSupport.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.mybatis;
2 |
3 | import org.springframework.context.annotation.Import;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * @author liulu
12 | * @version v1.0
13 | * date 2018-12-22 13:51
14 | */
15 | @Target({ElementType.TYPE})
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Import({MyBatisSupportConfigure.class})
18 | public @interface EnambeMybatisSupport {
19 | }
20 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/mybatis/MyBatisSupportConfigure.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.mybatis;
2 |
3 | import org.apache.ibatis.session.SqlSessionFactory;
4 |
5 | import javax.annotation.PostConstruct;
6 | import javax.annotation.Resource;
7 | import java.util.List;
8 |
9 | /**
10 | * @author liulu
11 | * @version v1.0
12 | * date 2018-12-11 19:49
13 | */
14 | public class MyBatisSupportConfigure {
15 |
16 | @Resource
17 | private List sqlSessionFactoryList;
18 |
19 | @PostConstruct
20 | public void addInterceptor() {
21 | //
22 | ResultMapInterceptor resultMapInterceptor = new ResultMapInterceptor();
23 | for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
24 | sqlSessionFactory.getConfiguration().addInterceptor(resultMapInterceptor);
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/data/mybatis/ResultMapInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.data.mybatis;
2 |
3 | import com.github.lit.support.data.domain.TableMetaDate;
4 | import org.apache.ibatis.cache.CacheKey;
5 | import org.apache.ibatis.executor.Executor;
6 | import org.apache.ibatis.mapping.BoundSql;
7 | import org.apache.ibatis.mapping.MappedStatement;
8 | import org.apache.ibatis.mapping.ResultMap;
9 | import org.apache.ibatis.mapping.ResultMapping;
10 | import org.apache.ibatis.plugin.Interceptor;
11 | import org.apache.ibatis.plugin.Intercepts;
12 | import org.apache.ibatis.plugin.Invocation;
13 | import org.apache.ibatis.plugin.Plugin;
14 | import org.apache.ibatis.plugin.Signature;
15 | import org.apache.ibatis.session.ResultHandler;
16 | import org.apache.ibatis.session.RowBounds;
17 | import org.springframework.util.ClassUtils;
18 | import org.springframework.util.CollectionUtils;
19 | import org.springframework.util.ReflectionUtils;
20 |
21 | import java.lang.reflect.Field;
22 | import java.util.ArrayList;
23 | import java.util.Collection;
24 | import java.util.Collections;
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.Properties;
28 |
29 | /**
30 | * User : liulu
31 | * Date : 2018/7/11 12:42
32 | * version $Id: ResultMapInterceptor.java, v 0.1 Exp $
33 | */
34 | @Intercepts({
35 | @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
36 | @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
37 | })
38 | public class ResultMapInterceptor implements Interceptor {
39 |
40 | @Override
41 | public Object intercept(Invocation invocation) throws Throwable {
42 | if (!(invocation.getTarget() instanceof Executor)) {
43 | return invocation.proceed();
44 | }
45 | MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
46 |
47 | // xml sql 不做处理
48 | if (ms.getResource().contains(".xml")) {
49 | return invocation.proceed();
50 | }
51 | ResultMap resultMap = ms.getResultMaps().iterator().next();
52 | if (!CollectionUtils.isEmpty(resultMap.getResultMappings())) {
53 | return invocation.proceed();
54 | }
55 | Class> mapType = resultMap.getType();
56 | if (ClassUtils.isAssignable(mapType, Collection.class)) {
57 | return invocation.proceed();
58 | }
59 | TableMetaDate mataDate = TableMetaDate.forClass(mapType);
60 | Map> fieldTypeMap = mataDate.getFieldTypeMap();
61 | //
62 | List resultMappings = new ArrayList<>(fieldTypeMap.size());
63 | for (Map.Entry entry : mataDate.getFieldColumnMap().entrySet()) {
64 | ResultMapping resultMapping = new ResultMapping.Builder(ms.getConfiguration(), entry.getKey(), entry.getValue(), fieldTypeMap.get(entry.getKey())).build();
65 | resultMappings.add(resultMapping);
66 | }
67 | ResultMap newRm = new ResultMap.Builder(ms.getConfiguration(), resultMap.getId(), mapType, resultMappings).build();
68 |
69 | Field field = ReflectionUtils.findField(MappedStatement.class, "resultMaps");
70 | ReflectionUtils.makeAccessible(field);
71 | ReflectionUtils.setField(field, ms, Collections.singletonList(newRm));
72 |
73 | return invocation.proceed();
74 | }
75 |
76 | @Override
77 | public Object plugin(Object target) {
78 | return Plugin.wrap(target, this);
79 | }
80 |
81 | @Override
82 | public void setProperties(Properties properties) {
83 | //
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/exception/BizException.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.exception;
2 |
3 | /**
4 | * User : liulu
5 | * Date : 2018-03-11 13:28
6 | * version $Id: BizException.java, v 0.1 Exp $
7 | */
8 | public class BizException extends LitException {
9 |
10 | private static final long serialVersionUID = 5060380635604270427L;
11 |
12 | public BizException() {
13 | super();
14 | }
15 |
16 | public BizException(ExceptionDefinition exceptionDefinition) {
17 | super(exceptionDefinition);
18 | }
19 |
20 | public BizException(String message) {
21 | super(message);
22 | }
23 |
24 | public BizException(String code, String message) {
25 | super(code, message);
26 | }
27 |
28 | public BizException(String message, Throwable cause) {
29 | super(message, cause);
30 | }
31 |
32 | public BizException(String code, String message, Throwable cause) {
33 | super(code, message, cause);
34 | }
35 |
36 | public BizException(Throwable cause) {
37 | super(cause);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/exception/ExceptionDefinition.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.exception;
2 |
3 | /**
4 | * @author liulu
5 | * @version v1.0
6 | * date 2019-02-12 10:49
7 | */
8 | public interface ExceptionDefinition {
9 |
10 | String getCode();
11 |
12 | String getMessage();
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/exception/LitException.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.exception;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * User : liulu
8 | * Date : 2018-03-11 13:37
9 | * version $Id: LitException.java, v 0.1 Exp $
10 | */
11 | class LitException extends RuntimeException {
12 |
13 | private static final long serialVersionUID = -7052223373308595812L;
14 |
15 | @Getter
16 | @Setter
17 | private String code;
18 |
19 | LitException() {
20 | super();
21 | }
22 |
23 | LitException(ExceptionDefinition exceptionDefinition) {
24 | super(exceptionDefinition.getMessage());
25 | this.code = exceptionDefinition.getCode();
26 | }
27 |
28 | LitException(String message) {
29 | super(message);
30 | }
31 |
32 | LitException(String code, String message) {
33 | super(message);
34 | this.code = code;
35 | }
36 |
37 | LitException(String message, Throwable cause) {
38 | super(message, cause);
39 | }
40 |
41 | LitException(String code, String message, Throwable cause) {
42 | super(message, cause);
43 | this.code = code;
44 | }
45 |
46 | LitException(Throwable cause) {
47 | super(cause);
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/exception/SysException.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.exception;
2 |
3 | /**
4 | * User : liulu
5 | * Date : 2018-03-11 13:36
6 | * version $Id: SysException.java, v 0.1 Exp $
7 | */
8 | public class SysException extends LitException {
9 |
10 | public SysException() {
11 | super();
12 | }
13 |
14 | public SysException(ExceptionDefinition exceptionDefinition) {
15 | super(exceptionDefinition);
16 | }
17 |
18 | public SysException(String message) {
19 | super(message);
20 | }
21 |
22 | public SysException(String code, String message) {
23 | super(code, message);
24 | }
25 |
26 | public SysException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | public SysException(String code, String message, Throwable cause) {
31 | super(code, message, cause);
32 | }
33 |
34 | public SysException(Throwable cause) {
35 | super(cause);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/util/DateTimeUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.util;
2 |
3 | import java.time.format.DateTimeFormatter;
4 | import java.util.Calendar;
5 | import java.util.Date;
6 |
7 | /**
8 | * User : liulu
9 | * Date : 2018/3/15 16:55
10 | * version $Id: DateTimeUtils.java, v 0.1 Exp $
11 | */
12 | public abstract class DateTimeUtils {
13 |
14 | private static final DateTimeFormatter DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
15 |
16 | private static final DateTimeFormatter TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
17 |
18 | private static final DateTimeFormatter DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
19 |
20 |
21 | public static Date firstDayOfMonth(Date origin) {
22 | Calendar calendar = Calendar.getInstance();
23 | calendar.setTime(origin);
24 | calendar.set(Calendar.DAY_OF_MONTH, 1);
25 | calendar.set(Calendar.HOUR_OF_DAY, 0);
26 | calendar.set(Calendar.MINUTE, 0);
27 | calendar.set(Calendar.SECOND, 0);
28 | return calendar.getTime();
29 | }
30 |
31 | public static Date lastDayOfMonth(Date origin) {
32 | Calendar calendar = Calendar.getInstance();
33 | calendar.setTime(origin);
34 | int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
35 | calendar.set(Calendar.DAY_OF_MONTH, actualMaximum);
36 | calendar.set(Calendar.HOUR_OF_DAY, 0);
37 | calendar.set(Calendar.MINUTE, 0);
38 | calendar.set(Calendar.SECOND, 0);
39 | return calendar.getTime();
40 | }
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/util/NameUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.util;
2 |
3 | /**
4 | * 命名工具类
5 | * User : liulu
6 | * Date : 2016-10-4 16:05
7 | */
8 | public abstract class NameUtils {
9 |
10 | private NameUtils() {}
11 |
12 | /**
13 | * 下划线分割命名转换为驼峰命名
14 | *
15 | * @param name 下划线命名
16 | * @return 驼峰命名
17 | */
18 | public static String getCamelName(String name) {
19 | return getCamelName(name, "_");
20 | }
21 |
22 | /**
23 | * 获取指定字符分隔的驼峰命名
24 | *
25 | * @param name 指定分隔符命名
26 | * @param delimiter 分隔符
27 | * @return 驼峰命名
28 | */
29 | public static String getCamelName(String name, String delimiter) {
30 |
31 | if (name == null || name.isEmpty()) {
32 | return "";
33 | }
34 |
35 | char delimiterChar = delimiter.charAt(0);
36 |
37 | StringBuilder sb = new StringBuilder();
38 | name = name.toLowerCase();
39 |
40 | for (int i = 0; i < name.length(); i++) {
41 | char c = name.charAt(i);
42 | if (c == delimiterChar) {
43 | i++;
44 | sb.append(Character.toUpperCase(name.charAt(i)));
45 | } else {
46 | sb.append(c);
47 | }
48 | }
49 |
50 | return sb.toString();
51 | }
52 |
53 | /**
54 | * 将名称首字母大写
55 | *
56 | * @param name 原名称
57 | * @return 首字母大写名称
58 | */
59 | public static String getFirstUpperName(String name) {
60 | if (name == null || name.isEmpty()) {
61 | return "";
62 | }
63 | return Character.toUpperCase(name.charAt(0)) + name.substring(1);
64 | }
65 |
66 | /**
67 | * @param name 原名称
68 | * @return 首字母小写名称
69 | */
70 | public static String getFirstLowerName(String name) {
71 | if (name == null || name.isEmpty()) {
72 | return "";
73 | }
74 | if (Character.isLowerCase(name.charAt(0))) {
75 | return name;
76 | }
77 | return Character.toLowerCase(name.charAt(0)) + name.substring(1);
78 | }
79 |
80 | /**
81 | * 驼峰命名转换为小写下划线分割命名
82 | *
83 | * @param name 驼峰命名
84 | * @return 下划线命名
85 | */
86 | public static String getUnderLineName(String name) {
87 | return getLowerDelimiterName(name, "_");
88 | }
89 |
90 | /**
91 | * 驼峰命名转换为小写指定分隔符命名
92 | *
93 | * @param name 驼峰命名
94 | * @param delimiter 指定分隔符
95 | * @return 小写指定分隔符命名
96 | */
97 | public static String getLowerDelimiterName(String name, String delimiter) {
98 | return getUpperDelimiterName(name, delimiter).toLowerCase();
99 | }
100 |
101 | /**
102 | * 驼峰命名转换为大写指定分隔符命名
103 | *
104 | * @param name 驼峰命名
105 | * @param delimiter 指定分隔符
106 | * @return 大写指定分隔符命名
107 | */
108 | public static String getUpperDelimiterName(String name, String delimiter) {
109 |
110 | if (name == null || name.isEmpty()) {
111 | return "";
112 | }
113 | StringBuilder sb = new StringBuilder();
114 | for (int i = 0; i < name.length(); i++) {
115 | char c = name.charAt(i);
116 | if (i > 0 && Character.isUpperCase(c)) {
117 | sb.append(delimiter);
118 | }
119 | sb.append(c);
120 | }
121 | return sb.toString().toUpperCase();
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/lit-support/src/main/java/com/github/lit/support/util/PropertyUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.lit.support.util;
2 |
3 | import java.io.*;
4 | import java.util.HashMap;
5 | import java.util.Iterator;
6 | import java.util.Map;
7 | import java.util.Properties;
8 |
9 | /**
10 | * User : liulu
11 | * Date : 2017-1-9 21:24
12 | * version $Id: PropertyUtils.java, v 0.1 Exp $
13 | */
14 | public abstract class PropertyUtils {
15 | /**
16 | * 属性文件后缀
17 | */
18 | private static final String PRO_SUFFIX = ".properties";
19 |
20 | /**
21 | * 配置文件保存map
22 | */
23 | private static Map propMap = new HashMap();
24 |
25 |
26 | /**
27 | * 加载资源文件
28 | *
29 | * @param resourceName 资源名
30 | * @return 资源输入流
31 | */
32 | public static InputStream loadResource(String resourceName) {
33 |
34 | try {
35 | File configFile = getConfigFile(resourceName);
36 | if (configFile == null) {
37 | InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName);
38 | return is;
39 | } else {
40 | return new FileInputStream(configFile);
41 | }
42 | } catch (FileNotFoundException e) {
43 | throw new RuntimeException("加载xml文件失败:" + resourceName, e);
44 | }
45 | }
46 |
47 | /**
48 | * 加载properties文件
49 | *
50 | * @param resourceName the resource name
51 | */
52 | public static void loadProperties(String resourceName) {
53 |
54 | try {
55 | if (!resourceName.endsWith(PRO_SUFFIX)) {
56 | resourceName += PRO_SUFFIX;
57 | }
58 | Properties prop = new Properties();
59 | prop.load(loadResource(resourceName));
60 | Iterator> iterator = prop.entrySet().iterator();
61 | while (iterator.hasNext()) {
62 | Map.Entry