数据库字段自动填充功能在spring jpa、mybatis、quarkus中是怎么实现的 weir 2021-09-21 10:04:26.0 java,quarkus 602 数据库字段的自动填充是非常常见的功能,数据库表中都有些相同的字段比如创建人创建时间修改人修改时间这些字段如果还需要前端传进来显然比较啰嗦了。 在hibernate/jpa中早已有这样的实现,这个网上一大把。 mybatis呢如果你没用mybatis-plus,我想你也可以通过拦截器实现这样的功能 如果你用的是mybatis-plus那就更简单了,在这里也不做多说。 你要是用quarkus呢,我这两天就研究了这个问题最终解决了这个问题,看看在quarkus中是怎么实现的。 /** * * @ClassName: BaseEntity * @Description: 实体公共基类(表的创建时间 创建人 修改时间 修改人 分页的当前页 每页数据) * @author weir * @date 2021年8月25日 * */ @MappedSuperclass @TemplateData @EntityListeners(BaseEntityListener.class) public class BaseEntity extends PanacheEntityBase implements Serializable { private static final long serialVersionUID = 963030658916709085L; @Transient public Integer page = 0; @Transient public Integer rows = 10; @Column(name = "create_time") @CreationTimestamp public Date createTime; public Integer creator; @Column(name = "modify_time") @UpdateTimestamp public Date modifyTime; public Integer modifier; public String remark; } 这是我的实体基础类,看到 @EntityListeners(BaseEntityListener.class) 这个注解你应该看明白了 package com.weir.quarkus.base.system.handler; import com.weir.quarkus.base.system.entity.BaseEntity; import com.weir.quarkus.base.system.entity.SysUser; import io.vertx.core.json.JsonObject; import org.eclipse.microprofile.jwt.Claims; import org.eclipse.microprofile.jwt.JsonWebToken; import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.spi.CDI; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; @RequestScoped public class BaseEntityListener { public BaseEntityListener() {} private SysUser getUser(String userJson) { return new JsonObject(new JsonObject(userJson).getValue("user").toString()).mapTo(SysUser.class); } @PrePersist public void prePersist(Object target) { JsonWebToken context = CDI.current().select(JsonWebToken.class).get(); Object claim = context.getClaim(Claims.preferred_username.name()); SysUser user = getUser(claim.toString()); // System.out.println("---------------claim-----------" + claim.toString()); // System.out.println("---------------claim-----------" + user); if (target instanceof BaseEntity) { BaseEntity baseEntity = (BaseEntity) target; baseEntity.creator = user.id; // System.out.println("------------BaseEntity----------------" + user.getId()); } } @PreUpdate public void preUpdate(Object target) { JsonWebToken context = CDI.current().select(JsonWebToken.class).get(); Object claim = context.getClaim(Claims.preferred_username.name()); SysUser user = getUser(claim.toString()); if (target instanceof BaseEntity) { BaseEntity baseEntity = (BaseEntity) target; baseEntity.modifier = user.id; } } } 关键代码: JsonWebToken context = CDI.current().select(JsonWebToken.class).get(); Object claim = context.getClaim(Claims.preferred_username.name()); 我的项目安全框架基于jwt,在quarkus中获取jwt信息就需要 CDI.current().select(JsonWebToken.class).get(); 这样一句话,我贴出来登录代码和jwt加密代码一看便知缘由: package com.weir.quarkus.base.system.resource; import com.weir.quarkus.base.system.entity.SysModule; import com.weir.quarkus.base.system.entity.SysUser; import com.weir.quarkus.base.system.jwt.TokenService; import com.weir.quarkus.base.system.service.LoginService; import com.weir.quarkus.base.system.utils.AesEncyptUtil; import com.weir.quarkus.base.system.vo.LoginUserVo; import com.weir.quarkus.base.system.vo.ResultVo; import io.vertx.core.json.JsonObject; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * 登录生成token * * @author weir * */ @Path("jwt") @ApplicationScoped public class LoginResource { @Inject TokenService tokenService; @Inject LoginService loginService; @GET @Path("init") public String init() { loginService.init(); return "ok"; } @POST @Path("/login") public Response login(@RequestBody LoginUserVo user) { SysUser u = SysUser.find("userName", user.userName).firstResult(); if (u == null) { return Response.status(Status.BAD_REQUEST).entity(new ResultVo<>(400, "用户不存在")).build(); } List<SysModule> modules = SysModule .find("select m from SysModule m inner join SysRoleModule rm on m.id = rm.moduleId " + "INNER JOIN SysUserRole ur on rm.roleId=ur.roleId where ur.userId = ?1", u.id) .list(); if (!AesEncyptUtil.encrypt(user.password).equals(u.userPwd)) { return Response.status(Status.BAD_REQUEST).entity(new ResultVo<>(400, "用户名或密码错误")).build(); } Set<String> codes = modules.stream().map(SysModule::getCode).collect(Collectors.toSet()); // System.out.println("code----------------------" + codes); String ujson = new JsonObject().put("user", u).toString(); String token = tokenService.generateToken(u.email, ujson, codes); // System.out.println("token----------------------" + token); return Response.ok().entity(new ResultVo<>(200, null ,token)).build(); } } package com.weir.quarkus.base.system.jwt; import org.eclipse.microprofile.jwt.Claims; import org.jboss.logmanager.Logger; import org.jose4j.jwt.JwtClaims; import com.weir.quarkus.base.system.utils.TokenUtils; import javax.enterprise.context.RequestScoped; import java.util.Set; import java.util.UUID; @RequestScoped public class TokenService { public final static Logger LOGGER = Logger.getLogger(TokenService.class.getSimpleName()); public String generateUserToken(String email, String username, Set<String> group) { return generateToken(email, username, group); } public String generateToken(String subject, String name, Set<String> group) { try { JwtClaims jwtClaims = new JwtClaims(); jwtClaims.setIssuer("http://www.loveweir.com"); // change to your company jwtClaims.setJwtId(UUID.randomUUID().toString()); jwtClaims.setSubject(subject); jwtClaims.setClaim(Claims.upn.name(), subject); jwtClaims.setClaim(Claims.preferred_username.name(), name); //add more jwtClaims.setClaim(Claims.groups.name(), group); jwtClaims.setAudience("using-jwt"); jwtClaims.setExpirationTimeMinutesInTheFuture(86400); // TODO specify how long do you need String token = TokenUtils.generateTokenString(jwtClaims); LOGGER.info("TOKEN generated: " + token); return token; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } } 所以就是这么简单。 工程代码开源地址