反射封裝工具類----零SQL插入(實用版)

V_1.0 需求:開發一個工具方法,輔助初級程序員在不須要掌握sql命令和JDBC的狀況下,實現對數據庫的插入操做。java

V_4.0  實現0sql插入操做須要解決的問題.mysql

           1. 如何確認當前【陌生對象】關聯的【表名】程序員

           2. 如何確認當前表中須要添加數據的字段sql

           3. 如何將對象中數據和表中字段作一個一一對應數據庫

V_5.0 解決方案:app

                    【實體類映射文件】描述某一個實體類與表的對象關係。工具

                    經過這個文件瞭解當前類關聯的【表名稱】spa

                    經過這個文件瞭解當前【表】和當前【對象】的字段和屬性對應關係  code

工具類實現:
public class ReflectUtil {
    
    /**
     *  功能: 0sql插入
     *  步驟:
     *      1.將【實體類映射文件】加載到內存中。
            2.定位【陌生對象】隸屬的【類文件】
            3.拼接sql第一部分   insert into [表名]
               3.1 xPath="//@table"
               3.2 從【實體類映射文件】得到表名
               3.3. 拼接拼接sql第一部分       【insert into dept】
            4.拼接sql第二部分     insert into [表名] (字段名1,字段名2)
               4.1 從【實體類映射文件】自上而下得到全部的【property標籤】
               4.2 循環遍歷每個【property標籤】
                     
                4.2.1 從【property標籤】得到【colName屬性內容】,從而得到【字段名】
                4.2.2  將【字段名】拼接到sql命令----------insert into dept(DEPTNO,DNAME,
                                                                 LOC)
            5.拼接sql第三部分    insert into [表名] (字段名1,字段名2) 
                                              values(內容1,內容2);
                 5.1  循環遍歷每個【property標籤】
                      5.1.1 每次循環得到一個【property標籤】,依次讀取【colType】獲      得字段數據類型名,【name】 得到與當前字段對應的屬性名
                      5.1.2 到【實體類】定位同名的【屬性對象】 departId ====  
private int departId
                      5.1.3 強制要求JVM,讀取當前【實例對象】中指定【屬性】的內容    屬性對象.get(實例對象) Object value=obj.departId
                      5.1.4 根據當前【屬性對象】對應的【字段的數據類型名稱】,來決定讀取數據在拼接到sql命令時,是否須要添加''
 
            6. 在不考慮JDBC開發流程的狀況下,將拼接而成的sql命令輸送到數據庫中
                      ps.executeUpdate(sql)
     * 
     * @param obj
     * @param xmlPath
     * @throws Exception
     */
    public static void save(Object obj,String xmlPath,PreparedStatement ps)throws Exception{
                 //1.將【實體類映射文件】加載到內存中。
                 InputStream in = new FileInputStream(xmlPath);
                 SAXReader readerObj = new SAXReader();
                 Document xmlObj=readerObj.read(in);
                 
                 // 2.定位【陌生對象】隸屬的【類文件】
                 Class classObj= obj.getClass();
                 
                 //3.拼接sql第一部分   insert into [表名]
                 StringBuffer sql = new StringBuffer();
                 sql.append(" insert into ");
                 //3.1 xPath="//@table"
                 String xPath="//@table";
                 //3.2 從【實體類映射文件】得到表名
                 Attribute attrObj=(Attribute) xmlObj.selectSingleNode(xPath);
                 String tableName = attrObj.getValue(); //dept
                 //3.3. 拼接拼接sql第一部分       【insert into dept】
                 sql.append(tableName);
                 
                 //4.拼接sql第二部分     insert into [表名] (字段名1,字段名2)
                 //4.1 從【實體類映射文件】自上而下得到全部的【property標籤】
                  xPath="//property";
                  List<Element> propertyList=xmlObj.selectNodes(xPath);
                  //4.2 循環遍歷每個【property標籤】
                   int num =1;
                   sql.append(" (");
                   for(Element proElement:propertyList){
               //4.2.1 從【property標籤】得到【colName屬性內容】,從而得到【字段名】
                       String colName= proElement.attributeValue("colName");
                       //4.2.2  將【字段名】拼接到sql命令
                       sql.append(colName);
                       if(num<propertyList.size()){
                           sql.append(",");
                           num++;
                       }
                   }
                   sql.append(") ");
                   
 //5.拼接sql第三部分    insert into [表名] (字段名1,字段名2)  values(內容1,內容2);
                   // 5.1  循環遍歷每個【property標籤】
                   num =1;
                   sql.append(" values(");
                   for(Element proElement:propertyList){
// 5.1.1 每次循環得到一個【property標籤】,依次讀取【colType】得到字段數據類型名,【name】 得到與當前字段對應的屬性名
                       String colType = proElement.attributeValue("colType");
                       String fieldName = proElement.attributeValue("name");
// 5.1.2 到【實體類】定位同名的【屬性對象】 departId ====  private int departId
                       Field fieldObj=classObj.getDeclaredField(fieldName);
                       fieldObj.setAccessible(true);
                     //5.1.3 強制要求JVM,讀取當前【實例對象】中指定【屬性】的內容
                       Object value=fieldObj.get(obj);
//5.1.4 根據當前【屬性對象】對應的【字段的數據類型名稱】,來決定讀取數據在拼接到sql命令時,是否須要添加''
                       if("int".equals(colType) || "double".equals(colType)){
                           sql.append(value);
                       }else if("char".equals(colType) || "varchar".equals(colType)){
                           sql.append("'");
                           sql.append(value);
                           sql.append("'");
                       }else if("date".equals(colType)){
                            // mysql,容許將一個用字符串描述的數據,直接賦值給Date
                            Date date =(Date)value;
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                            sql.append("'");
                            sql.append(sdf.format(date));
                            sql.append("'");
                       }
                       if(num<propertyList.size()){
                           sql.append(",");
                           num++;
                       }
                   }
                   sql.append(")");
                   
                   //輸出拼接而成的sql
                   System.out.println(sql.toString());
             // 在不考慮JDBC開發流程的狀況下,將拼接而成的sql命令輸送到數據庫中
                   ps.executeUpdate(sql.toString());
                  
    }

}
表和實體類映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean classPath="com.xiehe.entily.DeptVO" table="dept">
         <property name="deptNo" type="int" colName="DEPTNO" colType ="int"></property>
         <property name="dName" type="java.lang.String" colName="DNAME" colType="varchar"></property>
         <property name="loc" type="java.lang.String" colName="LOC" colType="varchar"></property>
    </bean>
</beans>
相關文章
相關標籤/搜索