反射封装工具类----零SQL插入(实用版)

V_1.0 需求:开发一个工具方法,辅助初级程序员在不需要掌握sql命令和JDBC的情况下,实现对数据库的插入操作。

V_4.0  实现0sql插入操作需要解决的问题.

           1. 如何确认当前【陌生对象】关联的【表名】

           2. 如何确认当前表中需要添加数据的字段

           3. 如何将对象中数据和表中字段做一个一一对应

V_5.0 解决方案:

                    【实体类映射文件】描述某一个实体类与表的对象关系。

                    通过这个文件了解当前类关联的【表名称】

                    通过这个文件了解当前【表】和当前【对象】的字段和属性对应关系  

工具类实现:
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>

 

posted @ 2016-11-16 09:56  鹤少  阅读(304)  评论(0编辑  收藏  举报