关于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 首发 话说你昨天就在搞这个啊
jeecg里面有springjdbc的sql分离啊看cgreport那块 我就用了 我看看,两个都在试
页:
[1]