JdbcTemplate 動態建立表並新增資料
阿新 • • 發佈:2019-02-02
之前寫了一個 使用JDBC查詢是否存在某表或檢視,按月動態生成表 ,但是他並不能進行公用,使用時需要每個人都寫自己的處理程式碼,為了方便使用,我寫了一個公共的處理方法,僅供參考。
為了考慮大家專案的整合,獲得JdbcTemplate我採用Spring配置,也為了方便大家直接執行,初始化Spring的方式是寫的Main方法
主要思路是:
使用Spring配置JdbcTemplate
通過一個代理物件和資料庫進行對應,這個物件除了id和一個tableName屬性外和資料庫的欄位名稱都是一致的
通過一個公共方法類來獲得代理類有那些屬性,用來建立表和新增時進行動態SQL的拼裝
核心處理是,先看有麼有該表,沒有建立插入,有的話直接插入
首先配置Spring,大家都會的:
Xml程式碼- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:aop="http://www.springframework.org/schema/aop"
-
xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
- <!-- 資料來源 -->
- <bean id="dataSource"
- class="org.apache.commons.dbcp.BasicDataSource"
- destroy-method="close">
- <property name="driverClassName" value="com.mysql.jdbc.Driver" />
- <property name="url"
- value="jdbc:mysql://192.168.0.69:3306/cui?useUnicode=true&characterEncoding=UTF-8" />
- <property name="username" value="root" />
- <property name="password" value="root" />
- <!-- 連線池啟動時的初始值 -->
- <property name="initialSize" value="2" />
- <!-- 連線池的最大值 -->
- <property name="maxActive" value="2" />
- <!-- 最大空閒值.當經過一個高峰時間後,連線池可以慢慢將已經用不到的連線慢慢釋放一部分,一直減少到maxIdle為止 -->
- <property name="maxIdle" value="2" />
- <!-- 最小空閒值.當空閒的連線數少於閥值時,連線池就會預申請去一些連線,以免洪峰來時來不及申請 -->
- <property name="minIdle" value="2" />
- <property name="defaultAutoCommit" value="true" />
- </bean>
- <!-- JDBC 操作模板 -->
- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
- <constructor-arg>
- <ref bean="dataSource"/>
- </constructor-arg>
- </bean>
- <!-- 用於初始化獲得Spring物件的類 -->
- <bean id="springfactory" class="com.SpringFactory"></bean>
- </beans>
com.SpringFactory物件是用來動態獲取Spring管理物件的類,之前部落格中提到過:
Java程式碼- package com;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- /**
- * @說明 獲得Spring管理物件
- * @author cuisuqiang
- * @version 1.0
- * @since
- */
- public class SpringFactory implements ApplicationContextAware {
- private static ApplicationContext context;
- @SuppressWarnings("static-access")
- public void setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- this.context = applicationContext;
- }
- public static Object getObject(String id) {
- Object object = null;
- object = context.getBean(id);
- return object;
- }
- }
這個類可以根據配置的物件ID來獲得該物件的引用
我們還需要將引數中物件進行處理,獲得物件的屬性名稱和對應的值,這裡提供了一個公共方法,之前部落格提到過,只是改動了一些:
Java程式碼- package com;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * @說明 物件操縱高階方法
- * @author cuisuqiang
- * @version 1.0
- * @since
- */
- public class ObjectUtil {
- /**
- * 返回一個物件的屬性和屬性值
- */
- @SuppressWarnings("unchecked")
- public static Map<String,String> getProperty(Object entityName) {
- Map<String,String> map = new HashMap<String, String>();
- try {
- Class c = entityName.getClass();
- // 獲得物件屬性
- Field field[] = c.getDeclaredFields();
- for (Field f : field) {
- Object v = invokeMethod(entityName, f.getName(), null);
- map.put(f.getName(), v.toString());
- }
- } catch (Exception e) {
- map = null;
- }
- return map;
- }
- /**
- * 獲得物件屬性的值
- */
- @SuppressWarnings("unchecked")
- private static Object invokeMethod(Object owner, String methodName,
- Object[] args) throws Exception {
- Class ownerClass = owner.getClass();
- methodName = methodName.substring(0, 1).toUpperCase()
- + methodName.substring(1);
- Method method = null;
- try {
- method = ownerClass.getMethod("get" + methodName);
- } catch (SecurityException e) {
- } catch (NoSuchMethodException e) {
- return " can't find 'get" + methodName + "' method";
- }
- return method.invoke(owner);
- }
- }
傳遞一個物件,就會返回該物件的屬性和屬性值的Map
再來看一下物件實體類,要注意這個類一定不要和實際的類混了,因為你的業務物件類中可能會有一些額外的欄位,這個會被公共方法的類解析而出問題的
Java程式碼- package com;
- /**
- * @說明 需要操作的實體
- * @author cuisuqiang
- * @version 1.0
- * @since 這個只能是代理物件,也就是說你需要和資料庫同步對屬性欄位,實際上我們在表中還動態添加了一個 tableName 欄位
- */
- public class Users {
- private String userName;
- private String userPass;
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public String getUserPass() {
- return userPass;
- }
- public void setUserPass(String userPass) {
- this.userPass = userPass;
- }
- }
也就是說資料會有四個欄位 id,userName,userPass,tableName,其中id和tableName是無需關心的
核心處理類我先發程式碼:
Java程式碼- package com;
- import java.sql.Connection;
- import java.sql.DatabaseMetaData;
- import java.sql.ResultSet;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Map;
- import java.util.Set;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.jdbc.core.JdbcTemplate;
- /**
- * @說明 進行測試
- * @author cuisuqiang
- * @version 1.0
- * @since
- */
- public class DbTest {
- private static ApplicationContext context = null;
- public static void main(String[] args) {
- context = new ClassPathXmlApplicationContext("applicationContext.xml");
- Users user = new Users();
- user.setUserName("[email protected]");
- user.setUserPass("http://cuisuqiang.iteye.com/");
- int re = insertObject("users",user);
- System.out.println("---->" + re + "<----");
- }
- public static int insertObject(String tableName,Object obj){
- int re = 0;
- try {
- JdbcTemplate jt = (JdbcTemplate)context.getBean("jdbcTemplate");
- SimpleDateFormat format = new SimpleDateFormat("yyyy_MM");
- String tname = tableName + "_" + format.format(new Date());
- // 如果有某表
- if(getAllTableName(jt,tname)){
- // 儲存資料
- re = saveObj(jt,tname,obj);
- }else{
- // 動態建立表
- re = createTable(jt,tname,obj);
- // 儲存資料
- re = saveObj(jt,tname,obj);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return re;
- }
- /**
- * 儲存方法,注意這裡傳遞的是實際的表的名稱
- */
- public static int saveObj(JdbcTemplate jt,String tableName,Object obj){
- int re = 0;
- try{