PHP safe_mode開啟對於PHP系統函式有什麼影響
阿新 • • 發佈:2020-11-11
date: 2020-11-07 16:51:00
updated: 2020-11-07 16:58:00
Lombok
在類上使用註解 @Data
,會在編譯時自動新增 Setter-Getter 方法。
有一個需要避免踩坑的地方:屬性名前兩個字母都需要小寫,前兩個字母如果是小寫大寫會出現問題!
解決:
- 修改屬性名字,讓第二個字母小寫,或者說是規定所有的屬性的前兩個字母必須小寫
- 如果資料庫已經設計好,並且前後端介面對接好了,不想修改,那就專門為這種特殊的屬性使用idea生成get-set方法複製程式碼
現象:
@Data public class NMetaVerify{ private NMetaType nMetaType; private Long id; ....其他屬性 }
當我們使用Mybatis插入資料的時候,發現,其他屬性都能正常的插入,但是就是nMetaType屬性在資料庫一直是null.
原因:
Lombok對於第一個字母小寫,第二個字母大寫的屬性生成的get-set方法和Mybatis以及idea或者說是Java官方認可的get-set方法生成的不一樣:
@Data public class NMetaVerify { private Long id; private NMetaType nMetaType; private Date createTime; public void lombokFound(){ NMetaVerify nMetaVerify = new NMetaVerify(); nMetaVerify.setNMetaType(NMetaType.TWO); //注意:nMetaType的set方法為setNMetaType,第一個n字母大寫了, nMetaVerify.getNMetaType(); //getxxxx方法也是大寫 } }
idea,Mybatis,Java官方預設的行為為:
public class NMetaVerify { private Long id; private NMetaType nMetaType; private Date createTime; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public NMetaType getnMetaType() {//注意:nMetaType屬性的第一個字母小寫 return nMetaType; } public void setnMetaType(NMetaType nMetaType) {//注意:nMetaType屬性的第一個字母小寫 this.nMetaType = nMetaType; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }
Mybatis(3.4.6版本)解析get-set方法獲取屬性名字的原始碼:
package org.apache.ibatis.reflection.property;
import java.util.Locale;
import org.apache.ibatis.reflection.ReflectionException;
/**
* @author Clinton Begin
*/
public final class PropertyNamer {
private PropertyNamer() {
// Prevent Instantiation of Static Class
}
public static String methodToProperty(String name) {
if (name.startsWith("is")) {//is開頭的一般是bool型別,直接從第二個(索引)開始擷取(簡單粗暴)
name = name.substring(2);
} else if (name.startsWith("get") || name.startsWith("set")) {//set-get的就從第三個(索引)開始擷取
name = name.substring(3);
} else {
throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
}
//下面這個判斷很重要,可以分成兩句話開始解釋,解釋如下
//第一句話:name.length()==1
// 對於屬性只有一個字母的,例如private int x;
// 對應的get-set方法是getX();setX(int x);
//第二句話:name.length() > 1 && !Character.isUpperCase(name.charAt(1)))
// 屬性名字長度大於1,並且第二個(程式碼中的charAt(1),這個1是陣列下標)字母是小寫的
// 如果第二個char是大寫的,那就直接返回name
if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);//讓屬性名第一個字母小寫,然後加上後面的內容
}
return name;
}
public static boolean isProperty(String name) {
return name.startsWith("get") || name.startsWith("set") || name.startsWith("is");
}
public static boolean isGetter(String name) {
return name.startsWith("get") || name.startsWith("is");
}
public static boolean isSetter(String name) {
return name.startsWith("set");
}
}
Mybatis解析get-set方法為屬性名字測試:
@Test
public void foundPropertyNamer() {
String isName = "isName";
String getName = "getName";
String getnMetaType = "getnMetaType";
String getNMetaType = "getNMetaType";
Stream.of(isName,getName,getnMetaType,getNMetaType)
.forEach(methodName->System.out.println("方法名字是:"+methodName+" 屬性名字:"+ PropertyNamer.methodToProperty(methodName)));
}
方法名字是:isName 屬性名字:name
方法名字是:getName 屬性名字:name
方法名字是:getnMetaType 屬性名字:nMetaType //這個以及下面的屬性第二個字母都是大寫,所以直接返回name
方法名字是:getNMetaType 屬性名字:NMetaType