1. 程式人生 > >JdbcTemplate 動態建立表並新增資料

JdbcTemplate 動態建立表並新增資料

之前寫了一個 使用JDBC查詢是否存在某表或檢視,按月動態生成表 ,但是他並不能進行公用,使用時需要每個人都寫自己的處理程式碼,為了方便使用,我寫了一個公共的處理方法,僅供參考。

為了考慮大家專案的整合,獲得JdbcTemplate我採用Spring配置,也為了方便大家直接執行,初始化Spring的方式是寫的Main方法

主要思路是:

使用Spring配置JdbcTemplate

通過一個代理物件和資料庫進行對應,這個物件除了id和一個tableName屬性外和資料庫的欄位名稱都是一致的

通過一個公共方法類來獲得代理類有那些屬性,用來建立表和新增時進行動態SQL的拼裝

核心處理是,先看有麼有該表,沒有建立插入,有的話直接插入

首先配置Spring,大家都會的

Xml程式碼  收藏程式碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop"  
  5.     xmlns:tx="http://www.springframework.org/schema/tx"
      
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  7.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  8.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
      
  9.     <!-- 資料來源 -->  
  10.     <bean id="dataSource"  
  11.         class="org.apache.commons.dbcp.BasicDataSource"  
  12.         destroy-method="close">  
  13.         <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
  14.         <property name="url"  
  15.             value="jdbc:mysql://192.168.0.69:3306/cui?useUnicode=true&amp;characterEncoding=UTF-8" />  
  16.         <property name="username" value="root" />  
  17.         <property name="password" value="root" />  
  18.         <!-- 連線池啟動時的初始值 -->  
  19.         <property name="initialSize" value="2" />  
  20.         <!-- 連線池的最大值 -->  
  21.         <property name="maxActive" value="2" />  
  22.         <!-- 最大空閒值.當經過一個高峰時間後,連線池可以慢慢將已經用不到的連線慢慢釋放一部分,一直減少到maxIdle為止 -->  
  23.         <property name="maxIdle" value="2" />  
  24.         <!--  最小空閒值.當空閒的連線數少於閥值時,連線池就會預申請去一些連線,以免洪峰來時來不及申請 -->  
  25.         <property name="minIdle" value="2" />  
  26.         <property name="defaultAutoCommit" value="true" />  
  27.     </bean>     
  28.     <!-- JDBC 操作模板 -->  
  29.     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  30.         <constructor-arg>  
  31.             <ref bean="dataSource"/>  
  32.         </constructor-arg>  
  33.     </bean>         
  34.     <!-- 用於初始化獲得Spring物件的類 -->  
  35.     <bean id="springfactory" class="com.SpringFactory"></bean>  
  36. </beans>  

com.SpringFactory物件是用來動態獲取Spring管理物件的類,之前部落格中提到過

Java程式碼  收藏程式碼
  1. package com;  
  2. import org.springframework.beans.BeansException;  
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.ApplicationContextAware;  
  5. /** 
  6.  * @說明 獲得Spring管理物件 
  7.  * @author cuisuqiang 
  8.  * @version 1.0 
  9.  * @since 
  10.  */  
  11. public class SpringFactory implements ApplicationContextAware {  
  12.     private static ApplicationContext context;  
  13.     @SuppressWarnings("static-access")  
  14.     public void setApplicationContext(ApplicationContext applicationContext)  
  15.             throws BeansException {  
  16.         this.context = applicationContext;  
  17.     }  
  18.     public static Object getObject(String id) {  
  19.         Object object = null;  
  20.         object = context.getBean(id);  
  21.         return object;  
  22.     }  
  23. }  

這個類可以根據配置的物件ID來獲得該物件的引用

我們還需要將引數中物件進行處理,獲得物件的屬性名稱和對應的值,這裡提供了一個公共方法,之前部落格提到過,只是改動了一些

Java程式碼  收藏程式碼
  1. package com;  
  2. import java.lang.reflect.Field;  
  3. import java.lang.reflect.Method;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6. /** 
  7.  * @說明 物件操縱高階方法 
  8.  * @author cuisuqiang 
  9.  * @version 1.0 
  10.  * @since 
  11.  */  
  12. public class ObjectUtil {     
  13.     /**   
  14.      * 返回一個物件的屬性和屬性值 
  15.      */    
  16.     @SuppressWarnings("unchecked")     
  17.     public static Map<String,String> getProperty(Object entityName) {   
  18.         Map<String,String> map = new HashMap<String, String>();  
  19.         try {  
  20.             Class c = entityName.getClass();  
  21.             // 獲得物件屬性  
  22.             Field field[] = c.getDeclaredFields();     
  23.             for (Field f : field) {     
  24.                 Object v = invokeMethod(entityName, f.getName(), null);  
  25.                 map.put(f.getName(), v.toString());  
  26.             }  
  27.         } catch (Exception e) {  
  28.             map = null;  
  29.         }  
  30.         return map;  
  31.     }  
  32.     /** 
  33.      * 獲得物件屬性的值 
  34.      */  
  35.     @SuppressWarnings("unchecked")  
  36.     private static Object invokeMethod(Object owner, String methodName,  
  37.             Object[] args) throws Exception {  
  38.         Class ownerClass = owner.getClass();  
  39.         methodName = methodName.substring(01).toUpperCase()  
  40.                 + methodName.substring(1);  
  41.         Method method = null;  
  42.         try {  
  43.             method = ownerClass.getMethod("get" + methodName);  
  44.         } catch (SecurityException e) {  
  45.         } catch (NoSuchMethodException e) {  
  46.             return " can't find 'get" + methodName + "' method";  
  47.         }  
  48.         return method.invoke(owner);  
  49.     }     
  50. }  

傳遞一個物件,就會返回該物件的屬性和屬性值的Map

再來看一下物件實體類,要注意這個類一定不要和實際的類混了,因為你的業務物件類中可能會有一些額外的欄位,這個會被公共方法的類解析而出問題的

Java程式碼  收藏程式碼
  1. package com;  
  2. /** 
  3.  * @說明 需要操作的實體 
  4.  * @author cuisuqiang 
  5.  * @version 1.0 
  6.  * @since 這個只能是代理物件,也就是說你需要和資料庫同步對屬性欄位,實際上我們在表中還動態添加了一個 tableName 欄位 
  7.  */  
  8. public class Users {      
  9.     private String userName;  
  10.     private String userPass;  
  11.     public String getUserName() {  
  12.         return userName;  
  13.     }  
  14.     public void setUserName(String userName) {  
  15.         this.userName = userName;  
  16.     }  
  17.     public String getUserPass() {  
  18.         return userPass;  
  19.     }  
  20.     public void setUserPass(String userPass) {  
  21.         this.userPass = userPass;  
  22.     }  
  23. }  

也就是說資料會有四個欄位 id,userName,userPass,tableName,其中id和tableName是無需關心的

核心處理類我先發程式碼:

Java程式碼  收藏程式碼
  1. package com;  
  2. import java.sql.Connection;  
  3. import java.sql.DatabaseMetaData;  
  4. import java.sql.ResultSet;  
  5. import java.text.SimpleDateFormat;  
  6. import java.util.Date;  
  7. import java.util.Map;  
  8. import java.util.Set;  
  9. import org.springframework.context.ApplicationContext;  
  10. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  11. import org.springframework.jdbc.core.JdbcTemplate;  
  12. /** 
  13.  * @說明 進行測試 
  14.  * @author cuisuqiang 
  15.  * @version 1.0 
  16.  * @since 
  17.  */  
  18. public class DbTest {     
  19.     private static ApplicationContext context = null;     
  20.     public static void main(String[] args) {  
  21.         context = new ClassPathXmlApplicationContext("applicationContext.xml");       
  22.         Users user = new Users();  
  23.         user.setUserName("[email protected]");  
  24.         user.setUserPass("http://cuisuqiang.iteye.com/");         
  25.         int re = insertObject("users",user);  
  26.         System.out.println("---->" + re + "<----");  
  27.     }     
  28.     public static int insertObject(String tableName,Object obj){  
  29.         int re = 0;       
  30.         try {  
  31.             JdbcTemplate jt = (JdbcTemplate)context.getBean("jdbcTemplate");  
  32.             SimpleDateFormat format = new SimpleDateFormat("yyyy_MM");            
  33.             String tname = tableName + "_" + format.format(new Date());  
  34.             // 如果有某表  
  35.             if(getAllTableName(jt,tname)){  
  36.                 // 儲存資料  
  37.                 re = saveObj(jt,tname,obj);  
  38.             }else{  
  39.                 // 動態建立表  
  40.                 re = createTable(jt,tname,obj);  
  41.                 // 儲存資料  
  42.                 re = saveObj(jt,tname,obj);  
  43.             }             
  44.         } catch (Exception e) {  
  45.             e.printStackTrace();  
  46.         }         
  47.         return re;  
  48.     }     
  49.     /** 
  50.      * 儲存方法,注意這裡傳遞的是實際的表的名稱 
  51.      */  
  52.     public static int saveObj(JdbcTemplate jt,String tableName,Object obj){  
  53.         int re = 0;  
  54.         try{