基於 @SelectProvider 註解實現的無侵入的通用Dao
阿新 • • 發佈:2020-12-17
基於 @SelectProvider 註解實現的無侵入的通用Dao
程式碼設計
//實體 @Data //lombok public class User { private Integer id; /** * 是否可以,0/1 */ private Boolean available; /** * 使用者名稱 */ private String username; /** * 密碼 */ private String password; /** * 記錄生成時間,預設當前時間 */ private Date gmtCreate; /** * 記錄修改時間,預設當前時間 */ private Date gmtModified; } //通用dao public interface BaseDao<E,I> { @SelectProvider(type = BaseDaoProvider.class,method = "getById") E getById(I id); } //具體dao public interface UserDao extends BaseDao<User,Integer> { } //通用Provider,通過泛型反射獲取實體型別 public class BaseDaoProvider { public String getById(ProviderContext context) { return new SQL() {{ SELECT(getTableColumns(context)); FROM(getTableName(context)); WHERE("id = #{id}"); }}.toString(); } private String getTableName(ProviderContext context){ Class clazz = getEntityType(context); return SQLUtil.getTableName(clazz); } private String getTableColumns(ProviderContext context){ Class clazz = getEntityType(context); return SQLUtil.getTableColumns(clazz); } private Class getEntityType(ProviderContext context) { return (Class) ((ParameterizedType) (context.getMapperType().getGenericInterfaces()[0])).getActualTypeArguments()[0]; } } //sql工具類,通過實體獲取表名和列名,但資料庫和實體必須遵循下劃線轉駝峰規則 //即表列名必須全小寫,多單詞以下劃線分割,實體屬性必須為駝峰規則 public class SQLUtil { private static String toLowerCase(String camelStr) { String lowerCase = camelStr.replaceAll("[A-Z]", "_$0").toLowerCase(); if (lowerCase.startsWith("_")){ lowerCase = lowerCase.substring(1); } return lowerCase; } public static String getTableName(Class clazz){ String className = clazz.getSimpleName(); String tableName = toLowerCase(className); return tableName; } public static String getTableColumns(Class clazz) { Field[] fields = clazz.getDeclaredFields(); List<String> fieldNames = new ArrayList<>(); for (Field field : fields) { String fieldName = field.getName(); String columnName = toLowerCase(fieldName); fieldNames.add(columnName); } String columns = String.join(",",fieldNames); return columns; } }
測試
@SpringBootTest
class ApplicationTests {
@Resource
private UserDao2 userDao2;
@Test
void test1(){
User user = userDao2.getById(1);
System.out.println(user);
}
}
測試結果
- ==> Preparing: SELECT id,available,username,password,gmt_create,gmt_modified FROM user WHERE (id = ?)
- ==> Parameters: 1(Integer)
- <== Total: 1
- User(id=1, available=true, username=123, password=123, gmtCreate=Tue Dec 15 21:05:57 CST 2020, gmtModified=Tue Dec 15 21:05:57 CST 2020)