jueyue 发表于 2013-8-5 21:26:11

关于jdbc和代码分离自己的小方法

今天突然要写一个小的系统,因为什么都是新的,说要框架也要重新搭(bs下公司没有基础框架),ibatis自己没有怎么搭过,所以这次直接选择spring jdbc,但是要是喜欢ibatis的代码sql分离,所以自己百度了下发现spring 的jdbc代码分离有人写了,但是需要配置各个xml
,相信spring都是配置加自动的,所以自己,写了一部分,自动扫描map.xml然后加载,现在都是约定大于配置,这样我们约定放置sql的文件名和方式就可以了
下面是代码:
这个是主要的类,单例的package com.jueyue.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
/**
* sql map的基础类
* @author jueyue
*
*/
public class SQLMap {
      
      private static Logger logger = LoggerFactory.getLogger(SQLMap.class);

      private Map<String, String> sqlContainer = null;

      private String sqlFilePath = "/com/jueyue/service/impl";
      
      private static SQLMap instance;
      
      public static SQLMap getInstance(){
                if(instance == null){
                        instance = new SQLMap();
                }
                return instance;
      }

      public SQLMap() {
               
                initSqlContainer();
      }

      public SQLMap(String sqlFilePath) {

                this.sqlFilePath = sqlFilePath;
                initSqlContainer();
      }

      public String getSql(String key) {
                String sql = sqlContainer.get(key);
                if (sql == null || "".equals(sql))
                        logger.warn("不存在该SQL语句");
                if (logger.isDebugEnabled()) {
                        logger.debug("SQL:" + sql);
                }
                return sql;
      }


      private void initSqlContainer() {
                sqlContainer = new ConcurrentHashMap<String, String>();
                if (sqlFilePath == null || "".equals(sqlFilePath)) {
            throw new NullPointerException("sql语句文件不能为空!");
                }
                List<String> files = new ScanMapFile().getsqlMaps(sqlFilePath);
                for (String file : files) {
                        readSQLFromFile(file);
                }
      }

      private void readSQLFromFile(String fileName) {
                InputStream ips = null;
                try {
                        ips = new FileInputStream(new File(fileName));
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                }
                Document document = null;
                SAXReader saxReader = new SAXReader();
                try {
                        document = saxReader.read(ips);
                } catch (DocumentException e) {
                        logger.error("读取系统中用到的SQL 语句XML出错");
                        throw new RuntimeException("读取sql语句XML文件出错:" + e.getMessage());
                }
                Element root = document.getRootElement();
                @SuppressWarnings("unchecked")
                List<Element> sqlElements = (List<Element>)root.selectNodes("//sqlElement");
                String key;
                for (Element sql : sqlElements) {
                        key=sql.attribute("key").getValue();
                        if(sqlContainer.containsKey(key)){
                              logger.warn("key值:"+key+"重复");
                        }
                        sqlContainer.put(key, getSqlText(sql.getText()));
                }
                if (ips != null) {
                        try {
                              ips.close();
                        } catch (IOException e) {
                              logger.error("关闭输入流出错:" + e.getMessage());
                        }
                }
      }
      /**
         * 出去无效字段
         */
      private String getSqlText(String text) {
                return text.replaceAll("\\n", " ").replaceAll("\\t", " ");
      }

      public void setSqlFilePath(String sqlFilePath) {
                this.sqlFilePath = sqlFilePath;
      }

      @Override
      protected void finalize() throws Throwable {
                super.finalize();
                if (sqlContainer != null) {
                        sqlContainer.clear();
                        sqlContainer = null;
                }

      }

}下面这个是扫描类package com.copote.util;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
* 扫描service下面的所有map.xml
*
* @author jueyue 2013年8月5日
*/
public class ScanMapFile {
      
      private List<String> sqls;
      
      public ScanMapFile(){
                sqls =new ArrayList<String>();
      }
      
      publicList<String> getsqlMaps(String path){
                GetSql(ScanMapFile.class.getResource(path).getPath());
                return sqls;
      }

      /*
         * 递归调用查找指定文件加下所有文件
         */
      private void GetSql(String path) {
                File rootDir = new File(path);
                if (!rootDir.isDirectory()) {
                        if(rootDir.getName().equalsIgnoreCase("map.xml")){
                              sqls.add(rootDir.getAbsolutePath());
                        }
                } else {
                        String[] fileList = rootDir.list();
                        for (int i = 0; i < fileList.length; i++) {
                              path = rootDir.getAbsolutePath() + "\\" + fileList;
                              GetSql(path);
                        }
                }
      }
}我们扫描的是所有的map.xml这样就加载了所有的sql<?xml version="1.0" encoding="UTF-8"?>
<sqls>
      <sqlElement key="account.login">
                <![CDATA[
                        select *from user
      </sqlElement>
</sqls>然后在我们的dao里面这样写 @Override
      public AccountEntity login(AccountEntity account) {
                String sql = SQLMap.getInstance().getSql("account.login");//加载sql
                List<AccountEntity> temp = jdbcTemplate.query(sql,
                              new Object[] { account.getVAcctCode(), account.getVAcctPwd(),
                              account.getCorgId() }, new AccountRowMapper());
                return temp.size() == 1?temp.get(0):null;
      }这样我们就获取了对于的sql,就分离了,而且自动扫描
最后记得在web.xml添加启动监听,进行初始化


jeecg 首发

GIN 发表于 2013-8-6 13:18:36

话说你昨天就在搞这个啊

jeecg里面有springjdbc的sql分离啊看cgreport那块 我就用了

jueyue 发表于 2013-8-7 16:40:16

我看看,两个都在试
页: [1]
查看完整版本: 关于jdbc和代码分离自己的小方法