# jquicker **Repository Path**: oli-home/jquicker ## Basic Information - **Project Name**: jquicker - **Description**: Java快速开发框架 - **Primary Language**: Java - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2018-09-02 - **Last Updated**: 2022-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 简介 + jquicker 是一个简易web框架,目的是提升日常开发效率 + 框架借鉴了Spring的控制反转、依赖注入、Aop等核心思想,并简化了Spring的大量配置 + # 简单示例 ## Controller示例 + `@Controller`标注Controller组件 + `@Mapping`映射请求路径: + 自动绑定参数,支持基本类型、包装类型及自定义对象 ``` /** * 用户相关操作 * * @catalog user * @catalogName 用户 * @date 2019年10月16日 下午11:07:23 */ @Controller @Mapping(value = "/user") public class UserController { // 自定义日志文件名的log static Logger myLog = JLogger.use("myLog"); @Resource private static UserService userService; @Resource private static UserAddressService userAddressService; /** * 进入页面 * * @return * @author OL */ @ResponseView @Mapping(value = "/index") public View index() { return new View("index.jsp"); } /** * 添加用户 * * @memo 新增用户,保存到数据库 * @param user * @return * @author OL * @data 2019年10月16日 下午11:10:15 */ // @Validate("addUser") @Mapping(value = "/add") @LogPoint(id = "addUser", desc = "添加用户") public Result add(User user, UserAddress address) { // JLogger use demo JLogger.debug("添加用户"); userService.insert(user); // 事务1 userAddressService.insert(address); // 事务2 myLog.info("添加用户成功"); return Result.success(user); } /** * 删除用户 * * @param id * @return */ @Mapping(value = "/delete", method = RequestMethod.POST) public Result delete(String id) { userService.delete(id); return new Result(); } @Mapping(value = "/update") public Result update(User user) { userService.update(user); return new Result(); } /** * 根据ID查询用户信息 * * @param id * xx主键 * @return * @author OL */ @Mapping(value = { "/getById", "/getUserById" }) public Result getById(String id) { JLogger.debug("trace0"); User user = userService.getByPks(id); if (user != null) { user.put("desc", "嘿嘿"); user.put("nickname", "小明"); } JLogger.debug("trace1"); return Result.success(user); } @Mapping(value = "/detail") public User getById2(User user) { user = userService.getByPks(user); return user; } /** * 根据ID查询用户信息 * * @param id * xx主键 * @return * @author OL */ @Mapping(value = "/{id}") public Result getById2(@Variable("id") String id) { JLogger.info("接收参数id:{}", id); User user = userService.getByPks(id); return Result.success(user); } @Around(advice = ControllerAspect.class) @Mapping(value = "/getList") public Result getList(User user) { List list = userService.getList(user); Result result = Result.success(list); return result; } @Mapping(value = "/getPager") public Result getPager(User user, Pager pager) { pager = userService.getPager(user, pager); Result result = Result.success(pager); return result; } } ``` ## Service示例 + `@Service`标注Service组件 + `@Transactional`开启事务 ``` /** * Generated by JQuicker. */ public interface UserService extends BaseService { public User getByPks(String id); } /** * Generated by JQuicker. */ @Service @Transactional public class UserServiceImpl implements UserService { @Resource private UserDao userDao; @Override public int insert(User user) { return userDao.insert(user); } @Override public User getByPks(String id) { return userDao.getByPks(id); } @Override public List getList(User user) { return userDao.getList(user); } @Override public Pager getPager(User user, Pager pager) { return userDao.getPager(user, pager); } } ``` ## Dao示例 + `@AutoProxy`标注Dao组件 并自动添加动态代理实现 - 以当前类名为namespace、方法名为sqlId查找sql模板 ``` /** * Generated by JQuicker. */ @AutoProxy public interface UserDao extends BaseDao { public User getByPks(String id); } ``` ## sql模板示例 ``` #namespace("com.jquicker.dao.UserDao") -- 申明变量 #var entity = "com.jquicker.entity.User" -- 新增 #sql(id="insert", paramType="${entity}") INSERT INTO user (id, name, password, mobile, remark) VALUES (#{id}, #{name}, #{password}, #{mobile}, #{remark}); -- 删除 #sql(id="delete") DELETE FROM user WHERE 1 = 1 AND id = #{id} -- 根据主键更新 #sql(id="update") UPDATE user SET id = id #if(id){ , id = #{id} } #if(name){ , name = #{name} } #if(password){ , password = #{password} } #if(mobile){ , mobile = #{mobile} } #if(remark){ , remark = #{remark} } WHERE 1 = 1 AND id = #{id} -- 查询 #sql(id="getByPks", resultType="${entity}") SELECT * FROM user WHERE 1 = 1 AND id = #{id} -- 根据条件查询列表 #sql(id="getList", resultType="${entity}") SELECT * FROM user WHERE 1 = 1 #if(id){ AND id = #{id} } #if(name){ AND name = #{name} } #if(password){ AND password = #{password} } #if(mobile){ AND mobile = #{mobile} } #if(remark){ AND remark = #{remark} } #ORDER BY# -- 根据条件分页查询 #sql(id="getPager", resultType="${entity}", ds="read") SELECT * FROM user WHERE 1 = 1 #if(id){ AND id = #{id} } #if(name){ AND name = #{name} } #if(password){ AND password = #{password} } #if(mobile){ AND mobile = #{mobile} } #if(remark){ AND remark = #{remark} } #ORDER BY# ``` ## 事务管理 ## 多数据源支持 + 1、Dao类OR方法上注解(仅支持自动代理实现的dao): ``` @DataSource("read") public User getByPks(String id); ``` + 2、有实现类的Dao需自己创建多数据源`TemplateDao`实例 ``` private TemplateDao dao = new TemplateDao(); private TemplateDao readDao = new TemplateDao("read"); ``` ## 拦截器示例 + `@Interceptor`标注Interceptor组件,必须继承`JQuickerInterceptor`类 - `path`:拦截路径,默认为空全局拦截 - `level`:level值越大,执行优先级越高 ``` @Interceptor(path = "/**", level = 98, enable = true) public class GlobalInterceptor extends JQuickerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, JQuickerInterceptor interceptor) { JLogger.debug("{}.preHandle() executed..", this.getClass().getSimpleName()); return true; } @Override public void afterHandle(HttpServletRequest request, HttpServletResponse response, JQuickerInterceptor interceptor, Object returnObj) { JLogger.debug("{}.afterHandle() executed..", this.getClass().getSimpleName()); // 设置请求耗时 long begin = RequestContextHolder.begin(); if(returnObj instanceof Result){ ((Result) returnObj).setRuntime(System.currentTimeMillis() - begin); } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, JQuickerInterceptor interceptor, Exception ex) { JLogger.debug("{}.afterCompletion() executed..", this.getClass().getSimpleName()); } } ``` ## AOP示例 + `@Aspect`标注切面组件 + `@Before`、`@After`、`@AfterReturning`、`@AfterThrowing` ``` /** * AOP使用示例 * @author OL */ @Aspect public class AopTest { @Before(matches = { "**.dao.**.*.insert" }, level = 1) public void brfore1(JoinPoint point) { JLogger.info("AopTest.brfore1 执行"); } @Before(matches = { "com.jquicker.service.impl.*.test*(..)" }, level = 1) public void brfore7(JoinPoint point) { JLogger.info("AopTest.brfore7 执行"); } @After(matches = { "com.jquicker.service.impl.*.test*" }, level = 1) public void after(JoinPoint point, Object result, Exception e) { JLogger.info("AopTest.after 执行"); JLogger.info("Return:{}", result); if (e != null) { JLogger.error(e.getMessage(), e); } } @AfterReturning(matches = { "com.jquicker.service.impl.*.test*" }, level = 1) public void afterReturning(JoinPoint point, Object result) { JLogger.info("AopTest.afterReturning 执行"); JLogger.info("Return:{}", result); } @AfterThrowing(matches = { "com.jquicker.service.impl.*.test*" }, level = 1) public void afterThrowing(JoinPoint point, Exception e) { JLogger.info("AopTest.afterThrowing 执行"); JLogger.error(e.getMessage(), e); } @AfterThrowing(matches = { "com.jquicker.service.impl.*.test*" }, level = 0) public Result afterThrowing1(JoinPoint point, Exception e) { JLogger.info("AopTest.afterThrowing1 执行"); // JLogger.error(e.getMessage(), e); return Result.failure("AOP处理异常之后的返回"); } } ``` ## 定时任务 + `@Task`标注任务组件 + `@Schedule`标注任务方法 ``` @Task public class TimerTest { @Schedule(period = 20, enable = true) public void test1(){ System.out.println("定时任务1执行了"); } } ``` ## 配置文件 ``` ############### 系统环境匹配文件 ############### # 该文件中的所有匹配项key都是固定的, 不可随意改变 ############################################## # 需要扫描的jar包, 模糊匹配原则(多个以“,”分隔) component.scan.jars= + 静态资源路径(避免静态资源的请求被框架拦截而出现404) resources.mapping=*.html,*.js,*.jpg,*.css,/resources/* + 当进入框架过滤器但没有匹配的mapping时会重定向到该地址(可以是页面或者controller映射地址) error.404=/error/404 # 当服务器抛出没有处理的异常时会重定向到该地址(可以是页面或者controller映射地址) error.500=/error/500 + 数据源 db.type=mysql db.showSql=true db.url=jdbc:mysql://127.0.0.1:3306/jquicker_test?useUnicode=true&characterEncoding=UTF-8 db.username=root db.password=123456 #db.dataSourceType=Druid ``` ## 生成代码 ``` public class CodeBuilder { private CodeGenerator generator; @Before public void before() throws IOException { Properties dbConfig = new Properties(); dbConfig.put("db.url", "jdbc:mysql://192.168.9.86:3306/jquicker_test?useUnicode=true&characterEncoding=UTF-8"); dbConfig.put("db.username", "root"); dbConfig.put("db.password", "123456"); dbConfig.put("db.driverClassName", "com.mysql.cj.jdbc.Driver"); // 指定jquicker-plugin-generator.jar所在路径 String jarPath = PathUtils.getProjectRootPath() + "\\tmp\\jquicker-plugin-generator.jar"; // 指定代码基本路径(可直接指定到项目路径,但是会覆盖已有同名文件) String basePath = "D:\\tmp\\code"; generator = new CodeGenerator(dbConfig); generator.setJarPath(jarPath); generator.setBasePath(basePath); generator.setCodePath("src\\main\\java"); // 源码目录 generator.setResourcePath("src\\main\\resources"); // 资源文件目录 generator.setSqlFolder("mapper"); // sql文件目录 generator.setEntityPackage("com.jquicker.entity"); // 实体包名 generator.setVoPackage("com.jquicker.vo"); // VO包名 generator.setDaoPackage("com.jquicker.dao"); // dao层包名 generator.setServicePackage("com.jquicker.service"); // 业务层包名 generator.setControllerPackage("com.jquicker.controller"); // 控制层包名 generator.setOverride(true); // 覆盖生成 } @Test public void generate() throws SQLException, IOException { List list = new ArrayList(); // list.add(new TableFilter("test_", "test_", "test")); list.add(new TableFilter("user", "", "user")); generator.generate(list.toArray(new TableFilter[0])); Windows.open(generator.getBasePath()); } } ``` # Demo项目地址 + https://gitee.com/ol-source/jquicker-demo/tree/master # 使用 + ### Maven中央仓库坐标 ``` com.jquicker jquicker-core 2.0.0 ``` + ### 保留参数名编译(JDK1.8以上) + 命令:javac -parameters Xxx.java + eclipse: Window --> Preferences --> Java --> Compiler --> 勾选 Store information about method parameters(usable via reflection) + idea: File --> Settings --> Build,Execution,Deployment->Compiler --> Java Compiler --> 在 Additional command line parameters后面填上 -parameters Maven: ``` org.apache.maven.plugins maven-compiler-plugin 3.1 1.8 1.8 UTF-8 -parameters ``` Ant: