在不断地设计就发现,DAO的封装,几乎只会朝着这3个方向发展,一种是MyBatis这样,基于模版引擎,或者类似模版引擎的;另一种就是像Hibernate,把数据映射发挥到极致;或者像Beetl,二者兼有。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* "org.sqlite.JDBC"
* "com.mysql.jdbc.driver"
*
* @author 41320
* @date 2017年4月7日,21:28:33
*/
public class SessionFactory {
final static Logger log = LoggerFactory.getLogger(SessionFactory.class);
private static String sUrl = null;
public void build(String driver, String url) throws IOException {
try{
Class.forName(driver);
SessionFactory.sUrl = url;
} catch(Exception e){
throw new IOException("无法建立数据库连接:" + url, e);
}
}
public static Connection getConnection(){
try {
return DriverManager.getConnection(sUrl);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 作为Connection的一个包装类,提取了JDBC中常用的方法,简化数据库的操作难度,
* 依托于SessionFactory,可以单独作为工具类使用,或者作为EasyDao的基类使用
*
* @author 41320
* @date 2017年4月7日,21:28:33
*/
public class Session implements AutoCloseable {
private Connection conn;
/**
* 执行一条Sql语句,包括Insert、Delete、Update
* @param sql
* @param params
* @return
*/
public int executeUpdate(String sql, Object... params) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
setParams(preparedStatement, params);
return preparedStatement.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
/**
* 执行一条带参数查询语句,通过回调函数处理结果
* @param parser
* @param sql
* @param params
* @param <T>
* @return
*/
public <T> T queryOne(ResultSetParser<T> parser, String sql, Object... params) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
setParams(preparedStatement, params);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
resultSet.next();
return parser.parse(resultSet);
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
/**
* 执行一条带参数查询语句,通过回调函数处理结果
*
* @param sql
* @param params
* @return Object
* @throws SQLException
*/
public Map<String, Object> queryAsMap(String sql, Object... params) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
setParams(preparedStatement, params);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
ResultSetMetaData metaData = resultSet.getMetaData();
int cols = metaData.getColumnCount();
resultSet.next();
Map<String, Object> map = new HashMap<>(cols);
for (int i = 0; i < cols; i++) {
String key = metaData.getColumnName(i + 1);
Object value = resultSet.getObject(i + 1);
map.put(key.toUpperCase(), value);
}
return map;
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
/**
* 执行一条带参数查询语句,通过回调函数处理结果
*
* @param parser
* @param sql
* @param params
* @return Object
*/
public <T> List<T> queryList(ResultSetParser<T> parser, String sql, Object... params) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
setParams(preparedStatement, params);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
List<T> retList = new ArrayList<T>();
while (resultSet.next()) {
retList.add(parser.parse(resultSet));
}
return retList;
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
/**
* 执行一条带参数查询语句,通过回调函数处理结果
*
* @param sql
* @param params
* @return Object
*/
public List<Map<String, Object>> queryAsListMap(String sql, Object... params) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
setParams(preparedStatement, params);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
ResultSetMetaData metaData = resultSet.getMetaData();
int cols = metaData.getColumnCount();
List<Map<String, Object>> res = new ArrayList<>();
while (resultSet.next()) {
Map<String, Object> map = new HashMap<>(cols);
for (int i = 0; i < cols; i++) {
String key = metaData.getColumnName(i + 1);
Object value = resultSet.getObject(i + 1);
map.put(key.toUpperCase(), value);
}
res.add(map);
}
return res;
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public int queryCount(String sql, Object... params) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
setParams(preparedStatement, params);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
resultSet.next();
return resultSet.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
private int queryCntBySql(String sql, Object... params) {
int idx = sql.indexOf(" from ");
if (idx < 0) {
sql = sql.toLowerCase();
idx = sql.indexOf(" from ");
}
String cntSql = "select count(*) " + sql.substring(idx);
return queryCount(cntSql, params);
}
public <T> Page queryPage(ResultSetParser<T> parser, String sql, Object... params) {
Page page = new Page();
page.list = this.queryList(parser, sql, params);
page.total = queryCntBySql(sql, params);
return page;
}
public Page queryPage(String sql, Object... params) {
Page page = new Page();
page.list = this.queryAsListMap(sql, params);
page.total = queryCntBySql(sql, params);
return page;
}
/**
* 执行插入操作
*
* @param sql -
* @param args -
* @return 自增的ID
*/
public Integer insert(String sql, Object... args) {
try (PreparedStatement ps = conn.prepareStatement(sql)) {
setParams(ps, args);
ps.executeUpdate();
try (ResultSet rs = ps.getGeneratedKeys()) {
if (rs != null) {
return rs.getInt(1);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public void beginTrancation(String methodName) {
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 提交事务,关闭连接,并且清除引用
*/
public void commit() {
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 事务回滚
*/
public void rollback() {
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 关闭并清除引用
*/
@Override
public void close() {
try {
if (conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* PreparedStatement参数注入
* @param pstmt
* @param params
* @throws SQLException
*/
private void setParams(PreparedStatement pstmt, Object... params) throws SQLException {
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
}
/**
* 结果集处理回调
*/
@FunctionalInterface
public interface ResultSetParser<T> {
T parse(ResultSet rs);
}
/**
* 分页,按需调整
*/
public class Page {
public int total;
public List<?> list;
}
}