diff --git a/README-ZH.md b/README-ZH.md index 1711e63..c57eaa0 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -1,7 +1,7 @@
- +
[![Build Status](https://travis-ci.org/crossoverJie/cicada.svg?branch=master)](https://travis-ci.org/crossoverJie/cicada) @@ -28,6 +28,7 @@ - [x] 代码简洁,没有过多依赖。 - [x] 一行代码即可启动 HTTP 服务。 - [x] [自定义拦截器](#自定义拦截器)。 +- [x] [自定义全局异常](#自定义全局异常). - [x] 灵活的传参方式。 - [x] `json` 响应格式。 - [x] [自定义配置](#自定义配置)。 @@ -41,7 +42,7 @@ 创建一个 maven 项目,引入核心依赖。 -```java +```xml top.crossoverjie.opensource cicada-core @@ -49,6 +50,16 @@ ``` +当然也推荐额外再引入一个 `IOC` 容器插件: + +```xml + + top.crossoverjie.opensource + cicada-ioc + 2.0.4 + +``` + 启动类: ```java @@ -244,6 +255,26 @@ public class ExecuteTimeInterceptor implements CicadaInterceptor { } ``` +## 自定义全局异常 + +现在你可以自定义全局异常,就像这样: + +```java +@CicadaBean +public class ExceptionHandle implements GlobalHandelException { + private final static Logger LOGGER = LoggerBuilder.getLogger(ExceptionHandle.class); + + @Override + public void resolveException(CicadaContext context, Exception e) { + LOGGER.error("Exception", e); + WorkRes workRes = new WorkRes(); + workRes.setCode("500"); + workRes.setMessage(e.getClass().getName()); + context.json(workRes); + } +} +``` + ## 性能测试 @@ -255,6 +286,11 @@ public class ExecuteTimeInterceptor implements CicadaInterceptor { ## 更新记录 +### v2.0.2 +- 修复 [#40](https://github.com/TogetherOS/cicada/issues/40) +- 新增全局异常接口。 +- 通过类类型获取 bean。 + ### v2.0.1 - 更新 Logo ,美化日志。 - 支持 `Cookie` diff --git a/README.md b/README.md index 7314667..0be2e2e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@
- +
[![Build Status](https://travis-ci.org/crossoverJie/cicada.svg?branch=master)](https://travis-ci.org/crossoverJie/cicada) @@ -33,6 +33,7 @@ If you are interested, please click [Star](https://github.com/crossoverJie/cicad - [x] Clean code, without too much dependency. - [x] One line of code to start the HTTP service. - [x] [Custom interceptor](#custom-interceptor). +- [x] [Custom exception handle](#custom-exception-handle). - [x] Flexible parameters way. - [x] Response `json`. - [x] Start with `jar`. @@ -48,7 +49,7 @@ If you are interested, please click [Star](https://github.com/crossoverJie/cicad Create a project with `Maven`, import core dependency. -```java +```xml top.crossoverjie.opensource cicada-core @@ -56,6 +57,15 @@ Create a project with `Maven`, import core dependency. ``` +Of course, it is recommended to introduce an additional `IOC` container plugin: +```xml + + top.crossoverjie.opensource + cicada-ioc + 2.0.4 + +``` + start class: ```java @@ -259,10 +269,30 @@ public class ExecuteTimeInterceptor implements CicadaInterceptor { } ``` +## Custom exception handle + +You can define global exception handle,like this: + +```java +@CicadaBean +public class ExceptionHandle implements GlobalHandelException { + private final static Logger LOGGER = LoggerBuilder.getLogger(ExceptionHandle.class); + + @Override + public void resolveException(CicadaContext context, Exception e) { + LOGGER.error("Exception", e); + WorkRes workRes = new WorkRes(); + workRes.setCode("500"); + workRes.setMessage(e.getClass().getName()); + context.json(workRes); + } +} +``` + ## Performance Test -![](https://ws4.sinaimg.cn/large/006tNbRwly1fv4luap7w0j31kw0iwdnu.jpg) +![](https://user-images.githubusercontent.com/15684156/50533885-5dd41900-0b6e-11e9-925f-6ee563664f85.png) > Test Conditions: 100 threads and 100 connections ;1G RAM/4 CPU @@ -271,6 +301,11 @@ public class ExecuteTimeInterceptor implements CicadaInterceptor { ## ChangeLog +### v2.0.2 +- fix [#40](https://github.com/TogetherOS/cicada/issues/40) +- add global handle exception interface. +- get bean by class type. + ### v2.0.1 - Logo. - Cookie Support. diff --git a/cicada-base/pom.xml b/cicada-base/pom.xml index 2e7ce39..15dc682 100644 --- a/cicada-base/pom.xml +++ b/cicada-base/pom.xml @@ -5,12 +5,12 @@ cicada top.crossoverjie.opensource - 2.0.2 + 2.0.4 4.0.0 cicada-base - 1.0.2 + 1.0.3 jar diff --git a/cicada-core/pom.xml b/cicada-core/pom.xml index 4309602..051f103 100644 --- a/cicada-core/pom.xml +++ b/cicada-core/pom.xml @@ -5,12 +5,12 @@ cicada top.crossoverjie.opensource - 2.0.2 + 2.0.4 4.0.0 cicada-core - 2.0.2 + 2.0.4 jar cicada-core diff --git a/cicada-core/src/main/java/top/crossoverjie/cicada/server/CicadaServer.java b/cicada-core/src/main/java/top/crossoverjie/cicada/server/CicadaServer.java index 0de5302..ebb55ea 100644 --- a/cicada-core/src/main/java/top/crossoverjie/cicada/server/CicadaServer.java +++ b/cicada-core/src/main/java/top/crossoverjie/cicada/server/CicadaServer.java @@ -1,6 +1,6 @@ package top.crossoverjie.cicada.server; -import top.crossoverjie.cicada.server.bootstrap.NettyBootStrap; +import top.crossoverjie.cicada.server.bootstrap.BootStrap; import top.crossoverjie.cicada.server.config.CicadaSetting; /** @@ -21,7 +21,10 @@ public final class CicadaServer { */ public static void start(Class clazz,String path) throws Exception { CicadaSetting.setting(clazz,path) ; - NettyBootStrap.startCicada(); + + CicadaSetting.initHandle(); + + BootStrap.startCicada(); } diff --git a/cicada-core/src/main/java/top/crossoverjie/cicada/server/bean/CicadaBeanManager.java b/cicada-core/src/main/java/top/crossoverjie/cicada/server/bean/CicadaBeanManager.java index 506899e..3ac5852 100644 --- a/cicada-core/src/main/java/top/crossoverjie/cicada/server/bean/CicadaBeanManager.java +++ b/cicada-core/src/main/java/top/crossoverjie/cicada/server/bean/CicadaBeanManager.java @@ -46,8 +46,7 @@ public static CicadaBeanManager getInstance() { public void initBean(String packageName) throws Exception { Map> cicadaBean = ClassScanner.getCicadaBean(packageName); - Class bean = ClassScanner.getCustomRouteBean(); - cicadaBeanFactory = (CicadaBeanFactory) bean.newInstance() ; + cicadaBeanFactory = ClassScanner.getCicadaBeanFactory() ; for (Map.Entry> classEntry : cicadaBean.entrySet()) { Object instance = classEntry.getValue().newInstance(); diff --git a/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/NettyBootStrap.java b/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/BootStrap.java similarity index 98% rename from cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/NettyBootStrap.java rename to cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/BootStrap.java index a599143..e745052 100644 --- a/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/NettyBootStrap.java +++ b/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/BootStrap.java @@ -28,9 +28,9 @@ * Date: 2018/9/10 21:56 * @since JDK 1.8 */ -public class NettyBootStrap { +public class BootStrap { - private final static Logger LOGGER = LoggerBuilder.getLogger(NettyBootStrap.class); + private final static Logger LOGGER = LoggerBuilder.getLogger(BootStrap.class); private static AppConfig appConfig = AppConfig.getInstance() ; private static EventLoopGroup boss = new NioEventLoopGroup(1,new DefaultThreadFactory("boss")); diff --git a/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/InitializeHandle.java b/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/InitializeHandle.java new file mode 100644 index 0000000..c9338e9 --- /dev/null +++ b/cicada-core/src/main/java/top/crossoverjie/cicada/server/bootstrap/InitializeHandle.java @@ -0,0 +1,13 @@ +package top.crossoverjie.cicada.server.bootstrap; + +/** + * initialize something about db/redis/kafka etc. + */ +public abstract class InitializeHandle { + + /** + * + * @throws Exception + */ + public abstract void handle() throws Exception; +} diff --git a/cicada-core/src/main/java/top/crossoverjie/cicada/server/config/CicadaSetting.java b/cicada-core/src/main/java/top/crossoverjie/cicada/server/config/CicadaSetting.java index 98c912f..303079b 100644 --- a/cicada-core/src/main/java/top/crossoverjie/cicada/server/config/CicadaSetting.java +++ b/cicada-core/src/main/java/top/crossoverjie/cicada/server/config/CicadaSetting.java @@ -2,6 +2,7 @@ import top.crossoverjie.cicada.server.CicadaServer; import top.crossoverjie.cicada.server.bean.CicadaBeanManager; +import top.crossoverjie.cicada.server.bootstrap.InitializeHandle; import top.crossoverjie.cicada.server.configuration.AbstractCicadaConfiguration; import top.crossoverjie.cicada.server.configuration.ApplicationConfiguration; import top.crossoverjie.cicada.server.configuration.ConfigurationHolder; @@ -50,6 +51,15 @@ public static void setting(Class clazz, String rootPath) throws Exception { } + public static void initHandle() throws Exception{ + List> configuration = ClassScanner.getInitHandles(AppConfig.getInstance().getRootPackageName()); + for (Class clazz : configuration) { + InitializeHandle handle = (InitializeHandle) clazz.newInstance(); + handle.handle(); + } + } + + private static void logo() { System.out.println(LOGO); Thread.currentThread().setName(APPLICATION_THREAD_MAIN_NAME) ; diff --git a/cicada-core/src/main/java/top/crossoverjie/cicada/server/reflect/ClassScanner.java b/cicada-core/src/main/java/top/crossoverjie/cicada/server/reflect/ClassScanner.java index 8563f2c..54b2d0a 100644 --- a/cicada-core/src/main/java/top/crossoverjie/cicada/server/reflect/ClassScanner.java +++ b/cicada-core/src/main/java/top/crossoverjie/cicada/server/reflect/ClassScanner.java @@ -7,6 +7,7 @@ import top.crossoverjie.cicada.server.annotation.CicadaBean; import top.crossoverjie.cicada.server.annotation.Interceptor; import top.crossoverjie.cicada.server.bean.CicadaDefaultBean; +import top.crossoverjie.cicada.server.bootstrap.InitializeHandle; import top.crossoverjie.cicada.server.configuration.AbstractCicadaConfiguration; import top.crossoverjie.cicada.server.configuration.ApplicationConfiguration; import top.crossoverjie.cicada.server.enums.StatusEnum; @@ -18,7 +19,15 @@ import java.net.JarURLConnection; import java.net.URL; import java.net.URLDecoder; -import java.util.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -42,6 +51,8 @@ public final class ClassScanner { private static List> configurationList = null; + private static List> initHandleList = null; + /** * get Configuration @@ -74,6 +85,33 @@ public static List> getConfiguration(String packageName) throws Excepti } return configurationList; } + + /** + * + * @param packageName + * @return + * @throws Exception + */ + public static List> getInitHandles(String packageName) throws Exception{ + if (initHandleList == null){ + Set> clsList = getClasses(packageName); + + if (clsList == null || clsList.isEmpty()) { + return initHandleList; + } + + initHandleList = new ArrayList<>(16); + for (Class cls : clsList) { + + if (cls.getSuperclass() != InitializeHandle.class) { + continue; + } + initHandleList.add(cls) ; + } + } + return initHandleList ; + } + /** * get @CicadaAction & @CicadaBean * @@ -230,7 +268,7 @@ private static void baseScanner(String packageName,Set set) { } - public static void findAndAddClassesInPackageByFile(String packageName, + private static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, Set> classes) { File dir = new File(packagePath); if (!dir.exists() || !dir.isDirectory()) { @@ -258,12 +296,26 @@ public static void findAndAddClassesInPackageByFile(String packageName, private static final String BASE_PACKAGE = "top.crossoverjie.cicada"; + /** + * get CicadaFactory object by spi. + * @return + */ + public static CicadaBeanFactory getCicadaBeanFactory() { + ServiceLoader cicadaBeanFactories = ServiceLoader.load(CicadaBeanFactory.class); + if (cicadaBeanFactories.iterator().hasNext()){ + return cicadaBeanFactories.iterator().next() ; + } + + return new CicadaDefaultBean(); + } + /** * get custom route bean * @return * @throws Exception */ - public static Class getCustomRouteBean() throws Exception { + @Deprecated + public static Class getBeanFactory() throws Exception { List> classList = new ArrayList<>(); @@ -295,8 +347,8 @@ public static Class getCustomRouteBean() throws Exception { return classList.get(0); } - - public static Set> getCustomRouteBeanClasses(String packageName) throws Exception { + @Deprecated + private static Set> getCustomRouteBeanClasses(String packageName) throws Exception { if (cicada_classes == null){ cicada_classes = new HashSet<>(32) ; diff --git a/cicada-db/pom.xml b/cicada-db/pom.xml new file mode 100644 index 0000000..4c23c1d --- /dev/null +++ b/cicada-db/pom.xml @@ -0,0 +1,61 @@ + + + + cicada + top.crossoverjie.opensource + 2.0.2 + + 4.0.0 + + cicada-db + 0.0.1 + + + + + mysql + mysql-connector-java + 5.1.47 + + + + com.alibaba + druid + 1.1.21 + + + + junit + junit + + + + com.healthmarketscience.sqlbuilder + sqlbuilder + 3.0.0 + + + + org.projectlombok + lombok + 1.16.20 + provided + + + + ch.qos.logback + logback-access + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + + \ No newline at end of file diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/DBConnection.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/DBConnection.java new file mode 100644 index 0000000..504998b --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/DBConnection.java @@ -0,0 +1,38 @@ +package top.crossoverjie.cicada.db; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-19 17:34 + * @since JDK 1.8 + */ +public class DBConnection { + private static final String URL="jdbc:mysql://localhost:3306/ssm?charset=utf8mb4"; + private static final String NAME="root"; + private static final String PASSWORD="root"; + + public static void main(String[] args) throws Exception{ + + //1.加载驱动程序 + Class.forName("com.mysql.jdbc.Driver"); + + //2.获得数据库的连接 + Connection conn = DriverManager.getConnection(URL, NAME, PASSWORD); + //3.通过数据库的连接操作数据库,实现增删改查 + Statement stmt = conn.createStatement(); + //选择import java.sql.ResultSet; + ResultSet rs = stmt.executeQuery("select * from user"); + //如果对象中有数据,就会循环打印出来 + while(rs.next()){ + System.out.println(rs.getInt("id")+","+rs.getString("name")); + } + rs.close(); + stmt.close(); + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/FieldName.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/FieldName.java new file mode 100644 index 0000000..6818fec --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/FieldName.java @@ -0,0 +1,16 @@ +package top.crossoverjie.cicada.db.annotation; + + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface FieldName { + + String value() default "" ; +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/OriginName.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/OriginName.java new file mode 100644 index 0000000..b7803d3 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/OriginName.java @@ -0,0 +1,16 @@ +package top.crossoverjie.cicada.db.annotation; + + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OriginName { + + String value() default "" ; +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/PrimaryId.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/PrimaryId.java new file mode 100644 index 0000000..627c1fb --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/annotation/PrimaryId.java @@ -0,0 +1,15 @@ +package top.crossoverjie.cicada.db.annotation; + + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface PrimaryId { + +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/ConnectionFactory.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/ConnectionFactory.java new file mode 100644 index 0000000..f4374e5 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/ConnectionFactory.java @@ -0,0 +1,20 @@ +package top.crossoverjie.cicada.db.core; + +import java.sql.Connection; + +/** + * Function: + * + * @author crossoverJie + * Date: 2020-02-28 00:35 + * @since JDK 1.8 + */ +public interface ConnectionFactory { + + /** + * get db connection + * @param sqlSession + * @return + */ + Connection getConnection(SqlSession sqlSession) ; +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/ConnectionPool.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/ConnectionPool.java new file mode 100644 index 0000000..39f8b1c --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/ConnectionPool.java @@ -0,0 +1,17 @@ +package top.crossoverjie.cicada.db.core; + +import java.sql.Connection; + +/** + * Function: + * + * @author crossoverJie + * Date: 2020-02-28 00:42 + * @since JDK 1.8 + */ +public class ConnectionPool implements ConnectionFactory { + @Override + public Connection getConnection(SqlSession sqlSession) { + return null; + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/DBQuery.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/DBQuery.java new file mode 100644 index 0000000..078d09f --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/DBQuery.java @@ -0,0 +1,123 @@ +package top.crossoverjie.cicada.db.core; + + +import com.healthmarketscience.sqlbuilder.BinaryCondition; +import com.healthmarketscience.sqlbuilder.SelectQuery; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable; +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.annotation.OriginName; +import top.crossoverjie.cicada.db.model.Model; +import top.crossoverjie.cicada.db.reflect.Instance; +import top.crossoverjie.cicada.db.reflect.ReflectTools; +import top.crossoverjie.cicada.db.sql.Condition; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-19 19:40 + * @since JDK 1.8 + */ +@Slf4j +public final class DBQuery extends SqlSessionFactory{ + + private Class targetClass; + + private List conditions = new ArrayList<>(); + + private DbTable dbTable ; + + private Map columnMap = new HashMap<>() ; + + public DBQuery query(Class clazz) { + this.targetClass = clazz; + dbTable = super.origin().addTable(targetClass.getAnnotation(OriginName.class).value()) ; + return this; + } + + public DBQuery addCondition(Condition condition) { + conditions.add(condition); + return this; + } + + public List all() { + List result = null; + String sql = buildSQL(); + Statement statement = null; + try { + statement = super.origin().getConnection().createStatement(); + log.debug("execute sql>>>>>{}", sql); + ResultSet resultSet = statement.executeQuery(sql); + result = new ArrayList<>(); + + Map fields = new HashMap<>(8); + while (resultSet.next()) { + for (Field field : targetClass.getDeclaredFields()) { + String dbField = ReflectTools.getDbField(field); + + //get value from db + Method method = resultSet.getClass().getMethod(ReflectTools.getMethod(field.getType().getName()), String.class); + + Object value = method.invoke(resultSet, dbField); + + fields.put(field.getName(), value); + + } + + // transfer DB value to custom model + T transfer = Instance.transfer(targetClass, fields); + result.add(transfer); + } + resultSet.close(); + } catch (Exception e) { + log.error("Exception", e); + } finally { + try { + statement.close(); + } catch (SQLException e) { + log.error("Exception", e); + } + } + + + return result; + } + + public T first() { + return this.all().get(0); + } + + private String buildSQL() { + SelectQuery selectQuery = new SelectQuery() ; + + for (Field field : targetClass.getDeclaredFields()) { + String dbField = ReflectTools.getDbField(field); + + DbColumn dbColumn = dbTable.addColumn(dbField); + selectQuery.addColumns(dbColumn) ; + columnMap.put(dbField,dbColumn) ; + } + + for (Condition condition : conditions) { + Condition.Filter filter = condition.getCondition(); + DbColumn dbColumn = columnMap.get(filter.getFiled()); + selectQuery.addCondition(BinaryCondition.equalTo(dbColumn,filter.getValue())) ; + } + + return selectQuery.validate().toString(); + + } + + +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/DefaultConnection.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/DefaultConnection.java new file mode 100644 index 0000000..e3bdd3a --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/DefaultConnection.java @@ -0,0 +1,32 @@ +package top.crossoverjie.cicada.db.core; + +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.DriverManager; + +/** + * Function: + * + * @author crossoverJie + * Date: 2020-02-28 00:37 + * @since JDK 1.8 + */ +@Slf4j +public class DefaultConnection implements ConnectionFactory { + + private Connection connection; + + @Override + public Connection getConnection(SqlSession sqlSession) { + if (connection == null) { + try { + Class.forName("com.mysql.jdbc.Driver"); + connection = DriverManager.getConnection(sqlSession.getUrl(), sqlSession.getUserName(), sqlSession.getPwd()); + } catch (Exception e) { + log.error("Exception", e); + } + } + return connection; + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/SqlSession.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/SqlSession.java new file mode 100644 index 0000000..ea486f1 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/SqlSession.java @@ -0,0 +1,75 @@ +package top.crossoverjie.cicada.db.core; + +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbSchema; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbSpec; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.sql.Connection; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-19 22:57 + * @since JDK 1.8 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class SqlSession { + + private Connection connection; + + + @Getter + private String userName; + + @Getter + private String pwd; + + @Getter + private String url; + + private static SqlSession session; + + private static DbSchema schema; + + private static ConnectionFactory connectionFactory ; + + public static SqlSession getInstance() { + return session; + } + + public static void init(String userName, String pwd, String url) { + session = new SqlSession(userName, pwd, url); + String database = getDataBaseName(url); + schema = new DbSpec().addSchema(database); + + // FIXME: 2020-02-28 temporary + connectionFactory = new DefaultConnection() ; + } + + + private SqlSession(String userName, String pwd, String url) { + this.userName = userName; + this.pwd = pwd; + this.url = url; + } + + public Connection getConnection() { + return connectionFactory.getConnection(session) ; + } + + public DbTable addTable(String tableName){ + return schema.addTable(tableName) ; + } + + + + private static String getDataBaseName(String url) { + int i1 = url.lastIndexOf("/") ; + int i2 = url.indexOf("?") ; + return url.substring(i1 +1 , i2); + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/SqlSessionFactory.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/SqlSessionFactory.java new file mode 100644 index 0000000..bf0e0d5 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/SqlSessionFactory.java @@ -0,0 +1,22 @@ +package top.crossoverjie.cicada.db.core; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-12-23 15:41 + * @since JDK 1.8 + */ +public abstract class SqlSessionFactory { + + private SqlSession origin; + + public SqlSessionFactory() { + origin = SqlSession.getInstance(); + } + + public SqlSession origin(){ + return this.origin ; + } + +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/DBHandle.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/DBHandle.java new file mode 100644 index 0000000..521eb04 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/DBHandle.java @@ -0,0 +1,26 @@ +package top.crossoverjie.cicada.db.core.handle; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-12-03 23:35 + * @since JDK 1.8 + */ +public interface DBHandle { + + /** update model + * @param obj model of db entity + * @return + */ + int update(Object obj) ; + + + /** + * insert model + * @param obj + * @return + */ + void insert(Object obj) ; + +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/DBHandler.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/DBHandler.java new file mode 100644 index 0000000..6bb6eb8 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/DBHandler.java @@ -0,0 +1,131 @@ +package top.crossoverjie.cicada.db.core.handle; + +import com.healthmarketscience.sqlbuilder.BinaryCondition; +import com.healthmarketscience.sqlbuilder.InsertQuery; +import com.healthmarketscience.sqlbuilder.UpdateQuery; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable; +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.annotation.OriginName; +import top.crossoverjie.cicada.db.annotation.PrimaryId; +import top.crossoverjie.cicada.db.core.SqlSessionFactory; +import top.crossoverjie.cicada.db.model.Model; +import top.crossoverjie.cicada.db.reflect.Instance; +import top.crossoverjie.cicada.db.reflect.ReflectTools; + +import java.lang.reflect.Field; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-12-03 23:53 + * @since JDK 1.8 + */ +@Slf4j +public class DBHandler extends SqlSessionFactory implements DBHandle { + + private DbTable dbTable; + + + + @Override + public int update(Object obj) { + if (obj instanceof Model) { + dbTable = super.origin().addTable(obj.getClass().getAnnotation(OriginName.class).value()); + + Map primaryCondition = new HashMap<>(1); + UpdateQuery updateQuery = new UpdateQuery(dbTable); + for (Field field : obj.getClass().getDeclaredFields()) { + String dbField = ReflectTools.getDbField(field); + + Object filedValue = Instance.getFiledValue(obj, field); + if (null == filedValue) { + continue; + } + + if (field.getAnnotation(PrimaryId.class) != null) { + primaryCondition.put(dbTable.addColumn(dbField), (Integer) filedValue); + } else { + DbColumn dbColumn = dbTable.addColumn(dbField); + updateQuery.addSetClause(dbColumn, filedValue); + } + + } + for (Map.Entry entry : primaryCondition.entrySet()) { + updateQuery.addCondition(BinaryCondition.equalTo(entry.getKey(), entry.getValue())); + } + + Statement statement = null; + try { + statement = super.origin().getConnection().createStatement(); + log.debug("execute sql>>>>>{}", updateQuery.validate().toString()); + return statement.executeUpdate(updateQuery.toString()); + } catch (SQLException e) { + log.error("SQLException", e); + } finally { + try { + statement.close(); + } catch (SQLException e) { + log.error("SQLException", e); + } + } + return 0; + } else { + return 0; + } + } + + @Override + public void insert(Object obj) { + dbTable = super.origin().addTable(obj.getClass().getAnnotation(OriginName.class).value()); + InsertQuery insertSelectQuery = new InsertQuery(dbTable); + List values = new ArrayList<>(); + + for (Field field : obj.getClass().getDeclaredFields()) { + String dbField = ReflectTools.getDbField(field); + Object filedValue = Instance.getFiledValue(obj, field); + if (null == filedValue) { + continue; + } + + insertSelectQuery.addPreparedColumns(dbTable.addColumn(dbField)); + values.add(field); + } + + log.debug("execute sql>>>>>{}", insertSelectQuery.validate().toString()); + StringBuilder sb = new StringBuilder(); + PreparedStatement statement = null; + try { + statement = super.origin().getConnection().prepareStatement(insertSelectQuery.toString()); + for (int i = 0; i < values.size(); i++) { + Field value = values.get(i); + if (value.getType() == Integer.class) { + statement.setInt(i+1, (Integer) Instance.getFiledValue(obj, value)); + } + if (value.getType() == String.class) { + statement.setString(i+1, (String) Instance.getFiledValue(obj, value)); + } + sb.append(value.getName() + "=" + Instance.getFiledValue(obj, value) + "\t") ; + } + log.debug("params >>>>>>>>>[{}]", sb.toString()); + statement.execute() ; + } catch (SQLException e) { + log.error("SQLException", e); + } finally { + try { + statement.close(); + } catch (SQLException e) { + log.error("SQLException", e); + } + } + + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/HandleProxy.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/HandleProxy.java new file mode 100644 index 0000000..9018ebe --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/core/handle/HandleProxy.java @@ -0,0 +1,58 @@ +package top.crossoverjie.cicada.db.core.handle; + +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.listener.DataChangeListener; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-12-04 00:00 + * @since JDK 1.8 + */ +@Slf4j +public class HandleProxy { + + private Class clazz; + + public HandleProxy(Class clazz) { + this.clazz = clazz; + } + + private DataChangeListener listener ; + + public T getInstance(DataChangeListener listener) { + this.listener = listener ; + return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {clazz}, new ProxyInvocation(DBHandler.class)); + } + public T getInstance() { + return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {clazz}, new ProxyInvocation(DBHandler.class)); + } + + + private class ProxyInvocation implements InvocationHandler { + + private Object target ; + + public ProxyInvocation(Class clazz){ + try { + this.target = clazz.newInstance() ; + } catch (Exception e) { + log.error("exception={}",e); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object invoke = method.invoke(target, args); + if (null != listener){ + listener.listener(args[0]); + } + return invoke ; + } + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/listener/DataChangeListener.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/listener/DataChangeListener.java new file mode 100644 index 0000000..72aff35 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/listener/DataChangeListener.java @@ -0,0 +1,18 @@ +package top.crossoverjie.cicada.db.listener; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-12-23 02:25 + * @since JDK 1.8 + */ +public interface DataChangeListener { + + /** + * When db changed, we will callback this method to execute custom business. + * Warning: be careful blocking thread. + * @param obj Model of db declare + */ + void listener(Object obj) ; +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/model/Model.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/model/Model.java new file mode 100644 index 0000000..1a91383 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/model/Model.java @@ -0,0 +1,11 @@ +package top.crossoverjie.cicada.db.model; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-20 00:10 + * @since JDK 1.8 + */ +public abstract class Model { +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/reflect/Instance.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/reflect/Instance.java new file mode 100644 index 0000000..a516943 --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/reflect/Instance.java @@ -0,0 +1,76 @@ +package top.crossoverjie.cicada.db.reflect; + +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.model.Model; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-20 01:01 + * @since JDK 1.8 + */ +@Slf4j +public class Instance { + + public static T transfer(Class target, String filedName, Object value) { + if (filedName == null || value == null){ + throw new RuntimeException("argument is null!") ; + } + T obj = null; + try { + obj = target.newInstance(); + filedName = methodName(filedName) ; + Method method = target.getMethod("set" + filedName ,value.getClass()); + method.invoke(obj, value); + return obj; + } catch (Exception e) { + log.error("exception",e); + } + + return obj; + } + + + public static T transfer(Class target, Map params){ + T obj = null ; + try { + obj = target.newInstance() ; + for (Map.Entry param : params.entrySet()) { + String filedName = methodName(param.getKey()) ; + Method method = target.getMethod("set" + filedName ,param.getValue().getClass()); + method.invoke(obj,param.getValue()) ; + } + }catch (Exception e){ + log.error("exception",e); + } + return obj; + } + + + private static String methodName(String filedName){ + char c = filedName.charAt(0); + filedName = filedName.replace(c,Character.toUpperCase(c)) ; + return filedName ; + } + + + /** + * @param obj + * @param field + * @return + */ + public static Object getFiledValue(Object obj, Field field){ + try { + Method method = obj.getClass().getDeclaredMethod("get" + methodName(field.getName())); + return method.invoke(obj) ; + } catch (Exception e) { + log.error("Exception", e); + } + return null ; + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/reflect/ReflectTools.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/reflect/ReflectTools.java new file mode 100644 index 0000000..2d3538a --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/reflect/ReflectTools.java @@ -0,0 +1,47 @@ +package top.crossoverjie.cicada.db.reflect; + +import top.crossoverjie.cicada.db.annotation.FieldName; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-22 00:54 + * @since JDK 1.8 + */ +public class ReflectTools { + + private static final Map TYPE_MAPPING = new HashMap<>(8); + + static { + TYPE_MAPPING.put(Integer.class.getName(), "getInt"); + TYPE_MAPPING.put(String.class.getName(), "getString"); + TYPE_MAPPING.put(Double.class.getName(), "getDouble"); + TYPE_MAPPING.put(Float.class.getName(), "getFloat"); + } + + public static String getMethod(String methodType){ + return TYPE_MAPPING.get(methodType) ; + } + + + /** + * Convert model field to DB field + * @param field + * @return + */ + public static String getDbField(Field field) { + String dbField; + FieldName fieldAnnotation = field.getAnnotation(FieldName.class); + if (fieldAnnotation != null) { + dbField = fieldAnnotation.value(); + } else { + dbField = field.getName(); + } + return dbField; + } +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/sql/Condition.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/sql/Condition.java new file mode 100644 index 0000000..df9259d --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/sql/Condition.java @@ -0,0 +1,39 @@ +package top.crossoverjie.cicada.db.sql; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-28 00:49 + * @since JDK 1.8 + */ +public abstract class Condition { + + public Condition(String property, Object value){ + + } + + public int type(){ + return 0 ; + } + + public Condition process(String property, Object value){ + return this ; + } + + + public Filter getCondition(){ + return null ; + } + + @Data + @AllArgsConstructor + public static class Filter{ + private String filed ; + private Object value ; + } + +} diff --git a/cicada-db/src/main/java/top/crossoverjie/cicada/db/sql/EqualToCondition.java b/cicada-db/src/main/java/top/crossoverjie/cicada/db/sql/EqualToCondition.java new file mode 100644 index 0000000..2cf320b --- /dev/null +++ b/cicada-db/src/main/java/top/crossoverjie/cicada/db/sql/EqualToCondition.java @@ -0,0 +1,35 @@ +package top.crossoverjie.cicada.db.sql; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-28 01:29 + * @since JDK 1.8 + */ +public class EqualToCondition extends Condition { + + private Filter filter = null ; + private int type = 1; + + public EqualToCondition(String property, Object value) { + super(property, value); + filter = new Filter(property,value) ; + } + + @Override + public Condition process(String property, Object value) { + filter = new Filter(property,value) ; + return this ; + } + + @Override + public Filter getCondition() { + return filter ; + } + + @Override + public int type() { + return type ; + } +} diff --git a/cicada-db/src/test/java/top/crossoverjie/cicada/db/SQLBuilder.java b/cicada-db/src/test/java/top/crossoverjie/cicada/db/SQLBuilder.java new file mode 100644 index 0000000..b3e67db --- /dev/null +++ b/cicada-db/src/test/java/top/crossoverjie/cicada/db/SQLBuilder.java @@ -0,0 +1,64 @@ +package top.crossoverjie.cicada.db; + +import com.healthmarketscience.sqlbuilder.BinaryCondition; +import com.healthmarketscience.sqlbuilder.InsertQuery; +import com.healthmarketscience.sqlbuilder.SelectQuery; +import com.healthmarketscience.sqlbuilder.UpdateQuery; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbSchema; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbSpec; +import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable; +import org.junit.Assert; +import org.junit.Test; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-24 01:13 + * @since JDK 1.8 + */ +public class SQLBuilder { + + @Test + public void test() { + DbSpec _spec = new DbSpec(); + DbSchema _schema1 = _spec.addSchema("Schema1"); + DbTable _table1 = _schema1.addTable("Table1"); + DbColumn _table1_col1 = _table1.addColumn("col1", "VARCHAR", 213); + DbColumn _table1_col2 = _table1.addColumn("col2", "VARCHAR", 213); + SelectQuery selectQuery1 = new SelectQuery() + .addColumns(_table1_col1, _table1_col2); + + String selectStr1 = selectQuery1.toString(); + Assert.assertEquals(selectStr1, + "SELECT t0.col1,t0.col2 FROM Schema1.Table1 t0"); + } + + + @Test + public void update(){ + DbSpec _spec = new DbSpec(); + DbSchema _schema1 = _spec.addSchema("Schema1"); + DbTable _table1 = _schema1.addTable("Table1"); + DbColumn _table1_col1 = _table1.addColumn("col1", "VARCHAR", 213); + DbColumn _table1_col2 = _table1.addColumn("col2", "VARCHAR", 213); + UpdateQuery updateQuery = new UpdateQuery(_table1) + .addSetClause(_table1_col1,"abc2") + .addCondition(BinaryCondition.equalTo(_table1_col1,"abc")) ; + System.out.println(updateQuery.toString()); + } + + @Test + public void insert(){ + DbSpec _spec = new DbSpec(); + DbSchema _schema1 = _spec.addSchema("Schema1"); + DbTable _table1 = _schema1.addTable("Table1"); + DbColumn _table1_col1 = _table1.addColumn("col1", "VARCHAR", 213); + DbColumn _table1_col2 = _table1.addColumn("col2", "VARCHAR", 213); + InsertQuery insertSelectQuery = new InsertQuery(_table1) ; + insertSelectQuery.addPreparedColumns(_table1_col1,_table1_col2) ; + + System.out.println(insertSelectQuery.toString()); + } +} diff --git a/cicada-db/src/test/java/top/crossoverjie/cicada/db/core/DBQueryTest.java b/cicada-db/src/test/java/top/crossoverjie/cicada/db/core/DBQueryTest.java new file mode 100644 index 0000000..3012fe8 --- /dev/null +++ b/cicada-db/src/test/java/top/crossoverjie/cicada/db/core/DBQueryTest.java @@ -0,0 +1,31 @@ +package top.crossoverjie.cicada.db.core; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import top.crossoverjie.cicada.db.model.User; +import top.crossoverjie.cicada.db.sql.EqualToCondition; + +import java.util.List; + +@Slf4j +public class DBQueryTest { + + @Test + public void query(){ + SqlSession.init("root","root","jdbc:mysql://localhost:3306/ssm?charset=utf8mb4"); + List all = new DBQuery().query(User.class).all(); + for (User user : all) { + log.info(user.toString()); + } + } + @Test + public void query2(){ + SqlSession.init("root","root","jdbc:mysql://localhost:3306/ssm?charset=utf8mb4"); + List all = new DBQuery().query(User.class).addCondition(new EqualToCondition("password","abc123")) + .addCondition(new EqualToCondition("id",1)).all(); + for (User user : all) { + log.info(user.toString()); + } + } + +} \ No newline at end of file diff --git a/cicada-db/src/test/java/top/crossoverjie/cicada/db/core/handle/DBHandleImplTest.java b/cicada-db/src/test/java/top/crossoverjie/cicada/db/core/handle/DBHandleImplTest.java new file mode 100644 index 0000000..6871020 --- /dev/null +++ b/cicada-db/src/test/java/top/crossoverjie/cicada/db/core/handle/DBHandleImplTest.java @@ -0,0 +1,39 @@ +package top.crossoverjie.cicada.db.core.handle; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import top.crossoverjie.cicada.db.core.SqlSession; +import top.crossoverjie.cicada.db.listener.DataChangeListener; +import top.crossoverjie.cicada.db.model.User; + +@Slf4j +public class DBHandleImplTest { + + @Test + public void update2(){ + SqlSession.init("root","root","jdbc:mysql://localhost:3306/ssm?charset=utf8mb4&useUnicode=true&characterEncoding=utf-8"); + User user = new User(); + user.setId(1); + user.setName("abc"); + DBHandle handle = (DBHandle) new HandleProxy(DBHandle.class).getInstance(new DataChangeListener() { + @Override + public void listener(Object obj) { + User user2 = (User) obj; + log.info("call back " + user2.toString()); + } + }); + int x = handle.update(user) ; + System.out.println(x); + } + + + @Test + public void insert(){ + SqlSession.init("root","root","jdbc:mysql://localhost:3306/ssm?charset=utf8mb4&useUnicode=true&characterEncoding=utf-8"); + User user = new User(); + user.setName("abc"); + user.setDescription("哈哈哈"); + DBHandle handle = (DBHandle) new HandleProxy(DBHandle.class).getInstance() ; + handle.insert(user) ; + } +} \ No newline at end of file diff --git a/cicada-db/src/test/java/top/crossoverjie/cicada/db/model/User.java b/cicada-db/src/test/java/top/crossoverjie/cicada/db/model/User.java new file mode 100644 index 0000000..5aaf2c1 --- /dev/null +++ b/cicada-db/src/test/java/top/crossoverjie/cicada/db/model/User.java @@ -0,0 +1,30 @@ +package top.crossoverjie.cicada.db.model; + +import lombok.Data; +import lombok.ToString; +import top.crossoverjie.cicada.db.annotation.FieldName; +import top.crossoverjie.cicada.db.annotation.OriginName; +import top.crossoverjie.cicada.db.annotation.PrimaryId; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-20 11:26 + * @since JDK 1.8 + */ +@Data +@OriginName("user") +@ToString +public class User extends Model { + @PrimaryId + private Integer id ; + private String name ; + private String password ; + + @FieldName(value = "city_id") + private Integer cityId ; + + private String description ; + +} diff --git a/cicada-db/src/test/java/top/crossoverjie/cicada/db/reflect/InstanceTest.java b/cicada-db/src/test/java/top/crossoverjie/cicada/db/reflect/InstanceTest.java new file mode 100644 index 0000000..ea16f43 --- /dev/null +++ b/cicada-db/src/test/java/top/crossoverjie/cicada/db/reflect/InstanceTest.java @@ -0,0 +1,52 @@ +package top.crossoverjie.cicada.db.reflect; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import top.crossoverjie.cicada.db.annotation.FieldName; +import top.crossoverjie.cicada.db.model.User; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class InstanceTest { + + @Test + public void transfer() { + User user = Instance.transfer(User.class, "id", 123); + log.info("user={}", user.toString()); + } + + @Test + public void transfers(){ + Map fields = new HashMap<>() ; + fields.put("id" ,100) ; + fields.put("name", "张三") ; + User user = Instance.transfer(User.class, fields); + log.info("user={}", user.toString()); + } + + @Test + public void filed(){ + Field[] fields = User.class.getDeclaredFields(); + for (Field field : fields) { + FieldName annotation = field.getAnnotation(FieldName.class); + String fieldName = "" ; + if (annotation != null){ + fieldName = annotation.value() ; + } + + log.info(field.getName() + " fieldName="+fieldName ); + } + } + + @Test + public void getFiledValue() throws NoSuchFieldException { + User user = new User() ; + user.setId(1); + user.setName("abc"); + Object name = Instance.getFiledValue(user, user.getClass().getDeclaredField("name")); + System.out.println(name); + } +} \ No newline at end of file diff --git a/cicada-example/pom.xml b/cicada-example/pom.xml index 6c5b6e5..7f02301 100644 --- a/cicada-example/pom.xml +++ b/cicada-example/pom.xml @@ -5,7 +5,7 @@ cicada top.crossoverjie.opensource - 2.0.2 + 2.0.4 4.0.0 2.0.2 @@ -18,19 +18,31 @@ top.crossoverjie.opensource cicada-core - 2.0.2 + 2.0.4 top.crossoverjie.opensource cicada-ioc - 2.0.2 + 2.0.4 com.google.guava guava + + top.crossoverjie.opensource + cicada-db + 0.0.1 + + + + org.projectlombok + lombok + 1.16.20 + provided + diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/DemoAction.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/DemoAction.java index 4550d3c..ce5d14b 100644 --- a/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/DemoAction.java +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/DemoAction.java @@ -26,6 +26,7 @@ * @since JDK 1.8 */ @CicadaAction(value = "demoAction") +@Deprecated public class DemoAction implements WorkAction { diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/RouteAction.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/RouteAction.java index fec0557..204ab9d 100644 --- a/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/RouteAction.java +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/action/RouteAction.java @@ -1,8 +1,14 @@ package top.crossoverjie.cicada.example.action; -import org.slf4j.Logger; -import top.crossoverjie.cicada.base.log.LoggerBuilder; +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.core.DBQuery; +import top.crossoverjie.cicada.db.core.handle.DBHandle; +import top.crossoverjie.cicada.db.core.handle.HandleProxy; +import top.crossoverjie.cicada.db.sql.EqualToCondition; import top.crossoverjie.cicada.example.exception.ExceptionHandle; +import top.crossoverjie.cicada.example.listener.UserSaveListener; +import top.crossoverjie.cicada.example.listener.UserUpdateListener; +import top.crossoverjie.cicada.example.model.User; import top.crossoverjie.cicada.example.req.DemoReq; import top.crossoverjie.cicada.server.action.req.Cookie; import top.crossoverjie.cicada.server.action.res.WorkRes; @@ -11,35 +17,68 @@ import top.crossoverjie.cicada.server.bean.CicadaBeanManager; import top.crossoverjie.cicada.server.context.CicadaContext; +import java.util.List; + /** * Function: * * @author crossoverJie - * Date: 2018/11/13 01:12 + * Date: 2018/11/13 01:12 * @since JDK 1.8 */ @CicadaAction("routeAction") +@Slf4j public class RouteAction { - private static final Logger LOGGER = LoggerBuilder.getLogger(RouteAction.class); - @CicadaRoute("getUser") - public void getUser(DemoReq req){ + public void getUser(DemoReq req) { + log.info(req.toString()); + WorkRes reqWorkRes = new WorkRes<>(); - LOGGER.info(req.toString()); - WorkRes reqWorkRes = new WorkRes<>() ; - reqWorkRes.setMessage("hello =" + req.getName()); - CicadaContext.getContext().json(reqWorkRes) ; + List all = new DBQuery().query(User.class) + .addCondition(new EqualToCondition("password", "abc123")) + .addCondition(new EqualToCondition("id", req.getId())).all(); + + reqWorkRes.setDataBody(all); + CicadaContext.getContext().json(reqWorkRes); + } + + + @CicadaRoute("saveUser") + public void saveUser(DemoReq req) { + DBHandle handle = (DBHandle) new HandleProxy(DBHandle.class).getInstance(new UserSaveListener()); + User user = new User(); + user.setName(req.getName()); + handle.insert(user); + WorkRes workRes = new WorkRes(); + workRes.setCode("200"); + workRes.setMessage("success"); + CicadaContext.getContext().json(workRes); + } + + @CicadaRoute("updateUser") + public void updateUser(DemoReq req) { + DBHandle handle = (DBHandle) new HandleProxy(DBHandle.class).getInstance(new UserUpdateListener()); + User user = new User(); + user.setId(req.getId()); + user.setName(req.getName()); + int count = handle.update(user); + + WorkRes workRes = new WorkRes(); + workRes.setCode("200"); + workRes.setMessage("success"); + workRes.setDataBody(count); + CicadaContext.getContext().json(workRes); } @CicadaRoute("getUserText") - public void getUserText(DemoReq req){ + public void getUserText(DemoReq req) { - LOGGER.info(req.toString()); - WorkRes reqWorkRes = new WorkRes<>() ; + log.info(req.toString()); + WorkRes reqWorkRes = new WorkRes<>(); reqWorkRes.setMessage("hello =" + req.getName()); - Cookie cookie = new Cookie() ; + Cookie cookie = new Cookie(); cookie.setName("cookie"); cookie.setValue(req.getName()); CicadaContext.getResponse().setCookie(cookie); @@ -47,26 +86,26 @@ public void getUserText(DemoReq req){ } @CicadaRoute("getInfo") - public void getInfo(DemoReq req){ + public void getInfo(DemoReq req) { Cookie cookie = CicadaContext.getRequest().getCookie("cookie"); - WorkRes reqWorkRes = new WorkRes<>() ; + WorkRes reqWorkRes = new WorkRes<>(); reqWorkRes.setMessage("getInfo =" + req.toString() + "cookie=" + cookie.toString()); - CicadaContext.getContext().json(reqWorkRes) ; + CicadaContext.getContext().json(reqWorkRes); } @CicadaRoute("getReq") - public void getReq(CicadaContext context,DemoReq req){ - WorkRes reqWorkRes = new WorkRes<>() ; + public void getReq(CicadaContext context, DemoReq req) { + WorkRes reqWorkRes = new WorkRes<>(); reqWorkRes.setMessage("getReq =" + req.toString()); - context.json(reqWorkRes) ; + context.json(reqWorkRes); } @CicadaRoute("test") - public void test(CicadaContext context){ + public void test(CicadaContext context) { ExceptionHandle bean = CicadaBeanManager.getInstance().getBean(ExceptionHandle.class); - LOGGER.info("====" +bean.getClass()); + log.info("====" + bean.getClass()); context.html("

12345

"); } diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/exception/ExceptionHandle.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/exception/ExceptionHandle.java index 2bc538c..70e2d3e 100644 --- a/cicada-example/src/main/java/top/crossoverjie/cicada/example/exception/ExceptionHandle.java +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/exception/ExceptionHandle.java @@ -24,7 +24,7 @@ public void resolveException(CicadaContext context, Exception e) { LOGGER.error("Exception", e); WorkRes workRes = new WorkRes(); workRes.setCode("500"); - workRes.setMessage(e.getClass().getName()); + workRes.setMessage(e.getClass().getName() + "系统运行出现异常"); context.json(workRes); } } diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/init/DBInit.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/init/DBInit.java new file mode 100644 index 0000000..fe6642f --- /dev/null +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/init/DBInit.java @@ -0,0 +1,28 @@ +package top.crossoverjie.cicada.example.init; + +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.core.SqlSession; +import top.crossoverjie.cicada.server.bootstrap.InitializeHandle; +import top.crossoverjie.cicada.server.configuration.ApplicationConfiguration; +import top.crossoverjie.cicada.server.configuration.ConfigurationHolder; + +/** + * Function: + * + * @author crossoverJie + * Date: 2020-02-18 01:40 + * @since JDK 1.8 + */ +@Slf4j +public class DBInit extends InitializeHandle { + + @Override + public void handle() throws Exception { + ApplicationConfiguration configuration = (ApplicationConfiguration) ConfigurationHolder.getConfiguration(ApplicationConfiguration.class); + String username = configuration.get("db.username"); + String pwd = configuration.get("db.pwd"); + String url = configuration.get("db.url"); + SqlSession.init(username, pwd, url); + log.info("db init success!!"); + } +} diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/listener/UserSaveListener.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/listener/UserSaveListener.java new file mode 100644 index 0000000..0ccc41c --- /dev/null +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/listener/UserSaveListener.java @@ -0,0 +1,19 @@ +package top.crossoverjie.cicada.example.listener; + +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.listener.DataChangeListener; + +/** + * Function: + * + * @author crossoverJie + * Date: 2020-03-29 01:33 + * @since JDK 1.8 + */ +@Slf4j +public class UserSaveListener implements DataChangeListener { + @Override + public void listener(Object obj) { + log.info("user save data={}", obj.toString()); + } +} diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/listener/UserUpdateListener.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/listener/UserUpdateListener.java new file mode 100644 index 0000000..9ddd46f --- /dev/null +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/listener/UserUpdateListener.java @@ -0,0 +1,19 @@ +package top.crossoverjie.cicada.example.listener; + +import lombok.extern.slf4j.Slf4j; +import top.crossoverjie.cicada.db.listener.DataChangeListener; + +/** + * Function: + * + * @author crossoverJie + * Date: 2020-03-29 01:33 + * @since JDK 1.8 + */ +@Slf4j +public class UserUpdateListener implements DataChangeListener { + @Override + public void listener(Object obj) { + log.info("user update data={}", obj.toString()); + } +} diff --git a/cicada-example/src/main/java/top/crossoverjie/cicada/example/model/User.java b/cicada-example/src/main/java/top/crossoverjie/cicada/example/model/User.java new file mode 100644 index 0000000..d59512a --- /dev/null +++ b/cicada-example/src/main/java/top/crossoverjie/cicada/example/model/User.java @@ -0,0 +1,31 @@ +package top.crossoverjie.cicada.example.model; + +import lombok.Data; +import lombok.ToString; +import top.crossoverjie.cicada.db.annotation.FieldName; +import top.crossoverjie.cicada.db.annotation.OriginName; +import top.crossoverjie.cicada.db.annotation.PrimaryId; +import top.crossoverjie.cicada.db.model.Model; + +/** + * Function: + * + * @author crossoverJie + * Date: 2019-11-20 11:26 + * @since JDK 1.8 + */ +@Data +@OriginName("user") +@ToString +public class User extends Model { + @PrimaryId + private Integer id ; + private String name ; + private String password ; + + @FieldName(value = "city_id") + private Integer cityId ; + + private String description ; + +} diff --git a/cicada-example/src/main/resources/application.properties b/cicada-example/src/main/resources/application.properties index 5cd3e60..7ace7b1 100644 --- a/cicada-example/src/main/resources/application.properties +++ b/cicada-example/src/main/resources/application.properties @@ -1,4 +1,8 @@ # application port cicada.port = 5688 -cicada.root.path = /cicada-example \ No newline at end of file +cicada.root.path = /cicada-example + +db.url=jdbc:mysql://localhost:3306/ssm?charset=utf8mb4&useUnicode=true&characterEncoding=utf-8 +db.username=root +db.pwd=root \ No newline at end of file diff --git a/cicada-example/src/main/resources/logback.xml b/cicada-example/src/main/resources/logback.xml index 9081d89..65ddfc7 100644 --- a/cicada-example/src/main/resources/logback.xml +++ b/cicada-example/src/main/resources/logback.xml @@ -1,6 +1,6 @@ - + diff --git a/cicada-ioc/pom.xml b/cicada-ioc/pom.xml index 7d0c396..605e4b2 100644 --- a/cicada-ioc/pom.xml +++ b/cicada-ioc/pom.xml @@ -5,12 +5,12 @@ cicada top.crossoverjie.opensource - 2.0.2 + 2.0.4 4.0.0 cicada-ioc - 2.0.2 + 2.0.4 jar diff --git a/cicada-ioc/src/main/java/top/crossoverjie/cicada/bean/ioc/CicadaIoc.java b/cicada-ioc/src/main/java/top/crossoverjie/cicada/bean/ioc/CicadaIoc.java index 9160b69..51b17e3 100644 --- a/cicada-ioc/src/main/java/top/crossoverjie/cicada/bean/ioc/CicadaIoc.java +++ b/cicada-ioc/src/main/java/top/crossoverjie/cicada/bean/ioc/CicadaIoc.java @@ -4,7 +4,7 @@ import top.crossoverjie.cicada.base.bean.CicadaBeanFactory; import top.crossoverjie.cicada.base.log.LoggerBuilder; -import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; import java.util.Map; /** @@ -18,7 +18,7 @@ public class CicadaIoc implements CicadaBeanFactory { private static final Logger LOGGER = LoggerBuilder.getLogger(CicadaIoc.class) ; - private static Map beans = new HashMap<>(16) ; + private static Map beans = new ConcurrentHashMap<>(16) ; @Override public void register(Object object) { diff --git a/cicada-ioc/src/main/resources/META-INF/services/top.crossoverjie.cicada.base.bean.CicadaBeanFactory b/cicada-ioc/src/main/resources/META-INF/services/top.crossoverjie.cicada.base.bean.CicadaBeanFactory new file mode 100644 index 0000000..c3b0d04 --- /dev/null +++ b/cicada-ioc/src/main/resources/META-INF/services/top.crossoverjie.cicada.base.bean.CicadaBeanFactory @@ -0,0 +1 @@ +top.crossoverjie.cicada.bean.ioc.CicadaIoc \ No newline at end of file diff --git a/pom.xml b/pom.xml index a3207fd..414c201 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ top.crossoverjie.opensource cicada pom - 2.0.2 + 2.0.4 cicada Fast, lightweight Web framework based on Netty @@ -24,11 +24,12 @@ cicada-example cicada-ioc cicada-base + cicada-db 4.11 - 4.1.21.Final + 4.1.42.Final 1.1.11 UTF-8 UTF-8 @@ -36,7 +37,7 @@ github - https://github.com/TogetherOS/cicadaissues + https://github.com/TogetherOS/cicada/issues @@ -101,8 +102,9 @@ top.crossoverjie.opensource cicada-base - 1.0.2 + 1.0.3 +