自定義sql查詢並封裝為指定實體
阿新 • • 發佈:2019-02-11
原理:通過java反射,得到實體屬性對應的欄位名稱及型別,並用原生的jdbc執行查詢並封裝。
直接看原始碼:
1.實體:Zztest
2.註解類:JdbcMappingpackage demo.linj.test; import java.text.NumberFormat; public class Zztest { private String id; private String serviceTypeid; private Double totlaprice; @JdbcMapping("ID") public String getId() { return id; } public void setId(String id) { this.id = id; } @JdbcMapping("SERVICE_TPYEID") public String getServiceTypeid() { return serviceTypeid; } public void setServiceTypeid(String serviceTypeid) { this.serviceTypeid = serviceTypeid; } @JdbcMapping("TOTALPRICE") public Double getTotlaprice() { return totlaprice; } public void setTotlaprice(Double totlaprice) { this.totlaprice = totlaprice; } @Override public String toString() { return "['id':'"+id+"', 'serviceTypeid':'"+serviceTypeid+"','totalprice':'"+NumberFormat.getCurrencyInstance().format(totlaprice)+"']"; } }
3.訪問連結工具(DAO):LocalJdbcUtilspackage demo.linj.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface JdbcMapping { String value() default ""; }
=========================package demo.linj.test; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class LocalJdbcUtils { private String driver; private String url; private String username; private String password; public LocalJdbcUtils(String driver, String url, String username, String password) { this.driver = driver; this.url = url; this.username = username; this.password = password; } /**獲取資料庫連線*/ private Connection getConnection() { Connection conn = null; try { Class.forName(driver); conn = DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } /**得到實體每一個屬性*/ private HashMap<Field,Object[]> setEntityMap(Class<?> claz) throws Exception { HashMap<Field,Object[]> fieldCloumType = new HashMap<Field, Object[]>(); Field[] fields = claz.getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); String getMethod = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1); try { Method method = claz.getMethod(getMethod, new Class<?>[]{}); if(method == null) {//如果該屬性沒有對應的get方法,則不處理 System.out.println("there is no method of 'get' for field '"+fieldName+"'"); continue; } JdbcMapping jm = method.getAnnotation(JdbcMapping.class); if(jm == null) { throw new Exception("The method of 'get' for field named "+claz.getName()+"."+fieldName+" has no use @JdbcMapping annotation"); } fieldCloumType.put(field, new Object[]{jm.value(),method.getReturnType()});//{String,Class<?>} } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } return fieldCloumType; } /**使用原生態的jdbc查詢*/ public <E> List<E> findBySql(String sql, Class<? extends E> clz) throws Exception { List<E> list = new ArrayList<E>(); HashMap<Field,Object[]> fieldCloumType = setEntityMap(clz); Connection conn = getConnection(); try { PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet sets = pstmt.executeQuery(); while(sets.next()) { E z = clz.newInstance(); for (Field field : fieldCloumType.keySet()) { field.setAccessible(true); Object[] cloumType = fieldCloumType.get(field); if(((Class<?>)cloumType[1]).isAssignableFrom(String.class)) { field.set(z, sets.getString((String)cloumType[0])); } if(((Class<?>)cloumType[1]).isAssignableFrom(Double.class)) { field.set(z, sets.getDouble((String)cloumType[0])); } } list.add(z); } sets.close(); pstmt.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } return list; } }
4.測試類:
package demo.linj.test;
import java.util.List;
public class TestJdbcMappingEntity {
public static void main(String[] args) throws Exception {
LocalJdbcUtils u = new LocalJdbcUtils("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password");
List<Zztest> list = u.findBySql("select * from zztest", Zztest.class);
for (Zztest zztest : list) {
System.out.println(zztest);
}
}
}
5.輸出結果:
['id':'2', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥0.00']
['id':'1', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥10.00']
['id':'3', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥20.00']
['id':'4', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥15.00']
=================================
總結:本例只是一個簡單的使用原生jdbc的模仿,沒有使用AOP等工具類。但原理類似。重點在於JDBC的使用