经过了昨天纠结技术选型,和一大堆xml配置,终于把架子搭好了。因为最近一次做java项目也在好多年以前了(毕竟用了pytohn以后谁也不想再回来java了),java的生态发生了长足的进步,本来想从原来的项目里面拿过来一些,发现除了java还剩下一点兼容性,其他的基本都淘汰了。太悲剧了!连个轮子都没。边学边做吧!好在几个月前又背了一次java课,虽然一些新技术看文档还能应付。spring虽然有改变但是也不大,mybatis也还能凑合用。开始码代码才发现一个非常悲剧的问题。tomcat依然不支持热加载,这肯定是不行了,必须解决。因为ssm的各种依赖加起来几十个包,修改个东西跑起来既然要20多秒 。写代码的时间都没加载的时间长好吧?于是网上开始找,虽然东西多但是哥一个都没成功,有因为依赖的,有版本的,话说这个java都用上maven了为啥版本管理还是这么烂,不过也不能埋怨java,其实在版本管理上其他语言也都是一丘之貉!!于是乎发现了jetty这个货,正好没用过,对于我这样的尝鲜党必须试试,经过一番折腾终于搞定了,鉴于版本和jar包的版本问题,至少这个我的配置成功了!

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.eclipse.jetty</groupId>
  5. <artifactId>jetty-maven-plugin</artifactId>
  6. <version>9.3.7.RC0</version>
  7. <configuration>
  8. <!--自动扫描文件改变并进行热部署的时间间隔,单位为秒。默认值为0,这代表着禁用扫描并热部署,只有一个大于0的配置可以使它生效。-->
  9. <scanIntervalSeconds>10</scanIntervalSeconds>
  10. <!--可选择的配置,如果没有设置,Jetty将创建ServerConnector实例来监听8080端口。-->
  11. <httpConnector>
  12. <!--port:连接监听的端口,默认8080;-->
  13. <port>8080</port>
  14. </httpConnector>
  15. <webApp>
  16. <!--你web应用的根路径(访问路径)。默认设置为“/”,如果你可以设置一个路径在“/”下面,例如/mycontext-->
  17. <contextPath>/exam</contextPath>
  18. </webApp>
  19. <!-- scanTargetPatterns 可选。如果你想扫描有一长串的额外文件,通过使用模式匹配表达式制定它们更加方便,它可以用来替代 <scanTargets>参数的枚举展示。这个参数包含一组<scanTargetPattern>。每一个都是由一个<directory>和<includes>[或者<excludes>]参数来指定文件的匹配模式。-->
  20. <scanTargetPatterns>
  21. <scanTargetPattern>
  22. <directory>src/main/webapp</directory>
  23. <excludes>
  24. <exclude>**/*.jsp</exclude>
  25. </excludes>
  26. <includes>
  27. <include>**/*.properties</include>
  28. <include>**/*.xml</include>
  29. </includes>
  30. </scanTargetPattern>
  31. </scanTargetPatterns>
  32. <!-- 设置系统属性
  33. 你可以为插件的执行操作按name/value成对的方式指定系统属性。 在别的文件中 通过 ${configuration.path} 取值-->
  34.  
  35. </configuration>
  36. </plugin>

修改以后idea按ctrl+f9即可重新构建,终于不用重新启动容器了。然后开始增删查改起来!
  毕竟是java一定都不虚,这玩意依然是所有语言里最繁琐的。撸两个页面已经好半天了。如果可以尽量推荐你用python,或者note.js。不要浪费生命!在写表insert的时候有个createTime字段,基本上每个表都有着字段,一个一个赋值有觉得太麻烦,也是想到python里面有装饰器这样的工具可以搞定这样的需求,那java中注解和装饰器差不多会不会有相应的解决 方法呢!goole一圈果然有,就是定义注解方式,然后在mybatis里面增加一个拦截器,拦截到以后使用反射机制拿到被注解的字段设置属性。东西不多,但是是一个很好地解释注解使用方式以及反射的好例子。这里贴上来,以后可以回顾看看!

  1. //定义注解
    @Retention(RetentionPolicy.RUNTIME)
  2. @Target({ElementType.FIELD})
  3. public @interface CreateTime {
  4. String value() default "";
  5. }
  6.  
  7. @Retention(RetentionPolicy.RUNTIME)
  8. @Target({ElementType.FIELD})
  9. public @interface UpdateTime{
  10. String value() default "";
  11. }
  1. //部分代码 在需要写入时间的字段上添加自己定义的注解
  2.  
  3. private String email;
  4. private String phoneNum;
  5. @CreateTime //我是注解 对 我
  6. private Date createTime;
  7. private String createTimeStr;
  8. private int createBy;
  9. private int fieldId;
  10. private String fieldName;
  11. private Date lastLoginTime;
  12. private String lastLoginTimeStr;
  1. import org.aopalliance.intercept.Invocation;
  2. import org.apache.ibatis.executor.Executor;
  3. import org.apache.ibatis.mapping.MappedStatement;
  4. import org.apache.ibatis.mapping.SqlCommandType;
  5. import org.apache.ibatis.plugin.Interceptor;
  6. import org.apache.ibatis.plugin.Intercepts;
  7. import org.apache.ibatis.plugin.Plugin;
  8. import org.apache.ibatis.plugin.Signature;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11.  
  12. import java.lang.reflect.Field;
  13. import java.util.Date;
  14. import java.util.Properties;
  15.  
  16. // 这个必须把引入的包也展示出来 因为我刚开始就引包错了 如果用的同学尽量看仔细
  17. //Object parameter = invocation.getArgs()[1]; 获取执行对象
  18. // 通过反射获取对象所有的Field
  19. // 遍历所有Field,查看是否有指定注解
  20. // 如果有@CreateTime或者@UpdateTime注解,则设置最新时间
  21.  
  22. @Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
  23. public class CustomInterceptor implements Interceptor {
  24.  
  25. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  26.  
  27. @Override
  28. public Object intercept(org.apache.ibatis.plugin.Invocation invocation) throws Throwable {
  29.  
  30. MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
  31.  
  32. // 获取 SQL 命令
  33. SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
  34.  
  35. // 获取参数
  36. Object parameter = invocation.getArgs()[1];
  37.  
  38. // 获取私有成员变量
  39. Field[] declaredFields = parameter.getClass().getDeclaredFields();
  40.  
  41. for (Field field : declaredFields) {
  42. if (field.getAnnotation(CreateTime.class) != null) { //如果注解上CreateTime
  43. if (SqlCommandType.INSERT.equals(sqlCommandType)) { // insert 语句插入 createTime
  44. System.out.println("经过");
  45. field.setAccessible(true);
  46. field.set(parameter, new Date());
  47. }
  48. }
  49.  
  50. if (field.getAnnotation(UpdateTime.class) != null) { // insert 或 update 语句插入 updateTime
  51. if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
  52. field.setAccessible(true);
  53. field.set(parameter, new Date());
  54. }
  55. }
  56. }
  57.  
  58. return invocation.proceed();
  59. }
  60.  
  61. @Override
  62. public Object plugin(Object target) {
  63. return Plugin.wrap(target, this);
  64. }
  65.  
  66. @Override
  67. public void setProperties(Properties properties) {
  68.  
  69. }

测试就不贴了 !保准成功!

燃尽图

暑假撸系统3- petty热更新 mybatis自动填充时间字段!的更多相关文章

  1. mybatis自动填充时间字段

    对于实体中的created_on和updated_on来说,它没有必要被开发人员去干预,因为它已经足够说明使用场景了,即在插入数据和更新数据时,记录当前时间,这对于mybatis来说,通过拦截器是可以 ...

  2. mysql每次update数据,自动更新对应表中时间字段

    mysql 已经创建完成表的情况下, 使得其中的时间字段 在每次 uodate 数据的时候 自动更新事件, 运行如下sql ALTER TABLE tab_name MODIFY COLUMN upd ...

  3. 暑假撸系统1-先把git后悔药准备好!

    学校规定让暑假自己撸一款在线考试系统,其实的确需要一个款在线的考试系统系统,因为平时学校是使用Excel讲解选择题的.基于这个目标那么就话不多说.开干! 本来趁着项目想练练手,使用些新学习的技能看看, ...

  4. 暑假撸系统7- 熊孩子的捣乱!javascript保存前台状态!

    系统大体框架已经搭的差不多了, 往下就是技术性的美化以及修补了,但这也是最最耗费时间的.在这个过程就发现了一个有意思的需求,这里把思路以及解决方案总结下. 因为做的是考试系统,不管是大或者小的考试,本 ...

  5. 暑假撸系统5- Thymeleaf 常用标签的

    上次博客已经是三天前了,后期修补和细化的东西多了,进度没有前几天那么明显了.因为原来工作大多是后端居多,如果非要前台也会选择一些相对对ui依赖比较小的框架,比如extjs,所以这次的基础排版就费劲了, ...

  6. 暑假撸系统6- Thymeleaf ajax交互!

    本来用Thymeleaf也没想着深度使用ajax,就是用也是非常传统的ajax方式提交然后js控制修改下变量.闲来无事的时候看Thymeleaf的教程发现一哥们的实现方式,以及实现思路,堪称惊奇,先说 ...

  7. 关于webpack下热更新?&自动刷新?的小记(非vue-cli)

    写本随笔时:webpack4.6.0 为何标题用?号,因为老衲也不知是否用词正确,大概是这样的说法: webpack4.0引入生产模式和开发模式,在开发时使用 webpack 打包后不压缩,所以只需要 ...

  8. EF部分字段更新,自动忽略null字段

    某个项目里的update代码是类似这样的 public T Update<T>(T entity) where T : ModelBase { var set = this.Set< ...

  9. mybatis的判定时间字段问题 java.lang.IllegalArgumentException: invalid comparison: cn.hutool.core.date.DateTime and java.lang.String

    今天听组员说: mybatis在3.30版本及以上判定时间时 <if test="date_time != null and date_time != '' "> da ...

随机推荐

  1. Word2010制作自动目录

    原文链接:https://www.toutiao.com/i6488296610873737741/ 原文从网上复制: 查看"开始"选项卡,"样式"功能组,我们 ...

  2. element ui 动态菜单解决方案集锦

    1.<分享一个VUE Element-UI 的多级菜单动态渲染的组件> 2.<饿了么组件库,element-ui开发精美的后台管理系统系列之(一)开发伸缩菜单> 3.<V ...

  3. Keil MDK STM32系列(六) 基于抽象外设库HAL的ADC模数转换

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  4. Kotlin 协程一 —— 全面了解 Kotlin 协程

    一.协程的一些前置知识 1.1 进程和线程 1.1.1基本定义 1.1.2为什么要有线程 1.1.3 进程与线程的区别 1.2 协作式与抢占式 1.2.1 协作式 1.2.2 抢占式 1.3 协程 二 ...

  5. 2月10日 体温APP开发总结

    1.Java代码 1.user package bean;public class User { private String name; private String riqi; private S ...

  6. gin中的多模板和模板继承的用法

    1. 简单用法 package main import ( "github.com/gin-contrib/multitemplate" "github.com/gin- ...

  7. gin使用BasicAuth中间件

    package mainimport ( "github.com/gin-gonic/gin" "net/http")// 模拟一些私人数据var secret ...

  8. IoC容器-Bean管理注解方式(完全注解开发)

    完全注解开发 (1)创建配置类,替代xml配置文件 (2)编写测试类 在实际中一般用springboot做

  9. 带你十天轻松搞定 Go 微服务系列(三)

    序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务(本文) 产品服务 订单服务 支付服务 RPC 服务 Auth ...

  10. Java安全之C3P0利用与分析

    Java安全之C3P0利用与分析 目录 Java安全之C3P0利用与分析 写在前面 C3P0 Gadget http base C3P0.getObject() 序列化 反序列化 Class.forN ...