1.如果有对象返回已有对象,没有创建新对象
QuesionnairResult result = this.get(id).map(QuesionnairMapper.INSTANCE::toResult).orElseGet(QuesionnairResult::new);
2.类加上 @Transactional(readOnly = true)只读数据
创建更新删除方法加上 表示异常就回滚
@Transactional(rollbackFor = Exception.class)
3.流式计算的坑,属性名需要大小(注解是mybatis的名字)不然得不到属性
@Column(name = "q_title")
private String QTitle;
weekendCriteria.andEqualTo(Quesionnair::getQTitle, "用车");
4.命名规范不要 一个字母加一个单词,这样lombok生成错误 qTitle(x) quesTitle(对)
5.代理生成的代码需要清除后运行,特别是实体类名字更改,导致其他实体类名字也更改,转换实体类生成的代码出错
git需要打钩再把时间提交上去
6.swagger访问页面是http://localhost:8080//swagger-ui/index.html#/
7.判断字符串先判断null,后判断空
if ( param.getTitle() != null && !(param.getTitle()).equals("") ) {
8.springmvc识别不出date对象,使用字符串最方便
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String createTime; //而且mybatis支持
9.jrebel 注解和静态页面刷新不了需要重启
10.使用雪花策略,比自增长好,可以解决分布式自增长导致id重复的问题
public class BaseAutoIdEntity extends BaseEntity {
@Id
@KeySql(
genId = CustomerIdGenerator.class
)
private Long id;
public BaseAutoIdEntity(Long id) {
this.id = id;
}
public Long getId() {
return this.id;
}
public void setId(final Long id) {
this.id = id;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof BaseAutoIdEntity)) {
return false;
} else {
BaseAutoIdEntity other = (BaseAutoIdEntity)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof BaseAutoIdEntity;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
return result;
}
public String toString() {
return "BaseAutoIdEntity(id=" + this.getId() + ")";
}
public BaseAutoIdEntity() {
}
}
//继承即可,不能写id字段,因为父类已经指定了
11.前端拉取项目需要用 全局安装git,package-lock.json要删除不然安装不了
12.注解可能导错包 导致传不了数据
@RequestBody
13.以前数据库自增长id想返回 需要写配置文件和mapper,雪花id恰好解决问题 可自己手动生成根据表和列名
//雪花自增长
CustomerIdGenerator customerIdGenerator = new CustomerIdGenerator();
Long aLong = customerIdGenerator.genId("q_useranswer", "id");
qUseranswerSaveParam.setId(aLong);
//mysql自带的自增长
<insert id="insertAdvantage" parameterType="SysAdvantage" useGeneratedKeys="true" keyProperty="advantageId">
insert into sys_advantage(
<if test="advantageId != null and advantageId != 0">advantage_id,</if>
<if test="advantageName != null and advantageName != ''">advantage_name,</if>
<if test="advantageSort != null and advantageSort != ''">advantage_sort,</if>
<if test="status != null and status != ''">status,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
create_time
)values(
<if test="advantageId != null and advantageId != 0">#{advantageId},</if>
<if test="advantageName != null and advantageName != ''">#{advantageName},</if>
<if test="advantageSort != null and advantageSort != ''">#{advantageSort},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
sysdate()
)
</insert>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
</configuration>
14.动态sql判断int是否为空
<!-- 判断 int 类型参数是否为空 -->
<if test="param != null and param != 0">
<!-- 如果参数不为空,则执行相应的 SQL 语句 -->
#{param}
</if>
15.加密方式
1.对称加密 用相同的秘钥加密解密 DES AES
2.非对称加密 使用公钥加密 私钥解密
3.散列加密 MD5 SHA 不可逆
4.消息认证码 MAC 秘钥和消息生成固定长度的字符串,验证信息完整性和真实性 HMAC
5.数字签名 私钥加密 公钥解密, 也属于一种特殊的对称加密
//注意,长度必须是16的倍数,使用hash不影响原来位数,和hash配合使用
//我使用了AES(DES的升级)分块加密
//使用MD5和AES混合加密
public class AESUtil {
private static final String ALGORITHM = "AES";
public static String encrypt(String data,String md5Key) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(md5Key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String encryptedData,String md5Key) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(md5Key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
public static void main(String[] args) throws Exception {
String originalData = "Hello, World!xxxxxx";
System.out.println("Original Data: " + originalData);
String s = MD5Utils.md5Hex(originalData.getBytes());
String s1 = MD5Utils.md5Hex(s.getBytes());
String encryptedData = AESUtil.encrypt(originalData,s1);
System.out.println("Encrypted Data: " + encryptedData);
String decryptedData = AESUtil.decrypt(encryptedData,s1);
System.out.println("Decrypted Data: " + decryptedData);
}
}
public class AESKeyGenerator {
public static String generateAESKeyFromUUID() {
UUID uuid = UUID.randomUUID();
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
byte[] keyBytes = bb.array();
SecretKeySpec aes = new SecretKeySpec(keyBytes, "AES");
return bytesToHex(aes.getEncoded());
}
public static void main(String[] args) {
String s = AESKeyGenerator.generateAESKeyFromUUID();
System.out.println(s);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02X", b));
}
return result.toString();
}
}
16.对数据库数据进行加密,废掉了mysql的模糊查询功能? 敏感的加密数据需要查询(特殊情况可能需要使用触发器解决,最后使用了加密较为隐私的手机号)
17.git查询代码量,直接在gitlab查看变化数量,git的指定了但是不能查(查出了全部代码)
18.前端想要post发送请求,后端请求题接收不到get的参数,用rest风格可以
19.跨域,访问任何路径都会200,需要debug
20.以字段名perPage 为准,注解名字无效的
public class PageableParam {
("页码,不传是默认为1")
private Integer page = 1;
("每页数量,不传是默认为10")
("per_page")
private Integer perPage = 10;
<repositories>
<repository>
<id>aliyunmaven</id>
<name>Aliyun Maven Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
22.给前端最好提供内网穿透效率比较高(免费内网穿透的网站)
//网上有大量教程
https://ngrok.com/