随着shh2各种操作方便框架。越来越多JAVA WEB效率,可是,假设在不了解这些框架使用的场合的情况下,一拿到项目就盲目地选择这些框架进行系统架构的搭建,就有可能造成非常多不是必需的资源浪费。

在项目开发中。对数据库的CRUD操作我们一般都是无法避免的操作,尽管hibernate封装的非常完美,可是。因为本人对这个框架的底层原理不是非常了解,每次使用的时候心里总认为没底。代码一旦出现异常,非常多时候都没法高速有效地解决。因此,为了让代码异常处理风险控制在自己的可控范围内,还是决定先将数据的CRUD持久化操作(DAO)用自己的方式通过JDBC进行一次封装,以便更好地管理自己的代码。

关于Hibernate框架的使用,还是先弄懂它的一些底层实现原理后。再依据项目的须要酌情选择使用。

以下详细讲讲通过我自己的方式对有关DAO层数据库基本CRUD操作的JAVA实现(此处已MySQL为例,其它数据库仅仅需做部分改动就可以)。

备注:若要试用本演示样例,仅仅需依照给出的顺序依次复制代码建立对应的类就可以。另外。在项目lib文件夹下增加mysql链接jar包。

  (1)定义数据源常量类

package com.jkitn.jkits.common;

/**
* 定义数据源常量类
* @author xdweleven
* @version 1.0
*/
public class JdbcConfig {
/** 数据库驱动 */
public static final String DRIVERCLASSNAME = "com.mysql.jdbc.Driver";
/** 数据库URL */
public static final String URL = "jdbc:mysql://localhost:3306/app_jkit";
/** 数据库username */
public static final String USERNAME = "root";
/** 数据库password */
public static final String PASSWORD = "root";
}

(2)定义结果集(ResultSet)到pojo对象的映射

package com.jkitn.jkits.dao.common;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; /**
* 说明:实现结果集到pojo对象的映射
* @author xdweleven
* @version 1.0
*/
public class RowMapper<T>{
private Class<T> objectClass; public RowMapper(Class<T> objectClass) {
this.objectClass = objectClass;
} /**
* 实现单条记录到对象的映射
* @param rs 结果集
* @param rowNum 当前行数
* @return
* @throws SQLException
*/
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
try {
T object = objectClass.newInstance();
// 得到结果集的字段集合
ResultSetMetaData metaData = rs.getMetaData();
int columnNum = metaData.getColumnCount();
Field[] fields = object.getClass().getDeclaredFields();
// 设置对象属性的值。若不存在。则设置为null.
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
int flag = 0;
for (int j = 1; j <= columnNum; j++) {
if (metaData.getColumnName(j).toLowerCase().equals(field.getName().toLowerCase())) {
flag = 1;
break;
}
}
field.setAccessible(true);
if (flag == 1) {
this.typeMapper(field, object, rs);
}else {
field.set(object, null);
}
field.setAccessible(false);
}
return object;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
} /**
* 实现多条记录到结果集的映射
* @param rs
* @return
*/
public List<T> mapRows(ResultSet rs){
int rowNum = 0;
List<T> objList = new ArrayList<T>();
try {
while(rs.next()){
objList.add(this.mapRow(rs, rowNum++));
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
return objList;
} /**
* 类型的映射
* @param field
* @param obj
* @param rs
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws SQLException
*/
private void typeMapper(Field field, Object obj, ResultSet rs) {
String typeName = field.getType().getName(); // 得到字段类型
try {
if (typeName.equals("java.lang.String")) {
field.set(obj, rs.getString(field.getName()));
} else if (typeName.equals("int")
|| typeName.equals("java.lang.Integer")) {
field.set(obj, rs.getInt(field.getName()));
} else if (typeName.equals("long")
|| typeName.equals("java.lang.Long")) {
field.set(obj, rs.getLong(field.getName()));
} else if (typeName.equals("float")
|| typeName.equals("java.lang.Float")) {
field.set(obj, rs.getFloat(field.getName()));
} else if (typeName.equals("double")
|| typeName.equals("java.lang.Double")) {
field.set(obj, rs.getDouble(field.getName()));
} else if (typeName.equals("boolean")
|| typeName.equals("java.lang.Boolean")) {
field.set(obj, rs.getBoolean(field.getName()));
} else if (typeName.equals("java.util.Date")) {
field.set(obj, rs.getTimestamp(field.getName()));
} else {
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

  (3)定义数据库连接辅助类DBConn

package com.jkitn.jkits.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; import com.jkitn.jkits.dao.common.RowMapper; /**
* 定义数据库连接辅助类DBConn
* @author xdweleven
* @version 1.0
*/
public class DBConn {
private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null; /**
* 创建数据库的连接
* @return 返回数据库连接对象
*/
public Connection getConn(){
try {
// 载入数据库驱动
Class.forName(JdbcConfig.DRIVERCLASSNAME);
// 创建Connection接口对象。用于获取MySQL数据库的连接对象
conn = DriverManager.getConnection(JdbcConfig.URL, JdbcConfig.USERNAME, JdbcConfig.PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
} /**
* 更新数据库操作(包含增删改操作)
* @param sql 待运行sql语句
* @param objs 用于设置预编译语句中带入的參数
* @return null
* @throws Exception
*/
public int execUpdate(String sql, Object ...objs) throws Exception{
// 获取预编译环境
pstmt = this.getConn().prepareStatement(sql);
if(objs != null && objs.length > 0){
for(int i = 0; i < objs.length; i++){
pstmt.setObject(i+1, objs[i]);
}
}
// 运行更新语句
int result = pstmt.executeUpdate();
// 断开连接。释放资源
this.close(rs, pstmt, conn);
return result;
} /**
* 数据库查询操作
* @param sql 待运行sql语句
* @param objs 用于设置预编译语句中带入的參数
* @return 类T的List数据类型,即返回查询到的全部数据信息
* @throws Exception
*/
public <T> List<T> execQuery(String sql, RowMapper<T> mapper, Object ...objs) throws Exception{
// 获取预编译环境
pstmt = this.getConn().prepareStatement(sql);
if(objs != null && objs.length > 0){
for(int i = 0; i < objs.length; i++){
pstmt.setObject(i+1, objs[i]);
}
}
// 运行更新语句
rs = pstmt.executeQuery();
// 运行关系到对象的映射
List<T> result = mapper.mapRows(rs);
// 断开连接。释放资源
this.close(rs, pstmt, conn);
return result;
} /**
* 运行运行的SQL语句并返回结果集
* @param sql SQL语句
* @param params 參数
* @return 返回结果集
*/
public ResultSet queryForResultSet(String sql, Object... objs) throws Exception{
// 获取预编译环境
pstmt = conn.prepareStatement(sql);
if(objs != null && objs.length > 0){
for(int i = 0; i < objs.length; i++){
pstmt.setObject(i+1, objs[i]);
}
}
// 运行更新语句
rs = pstmt.executeQuery();
// 断开连接,释放资源
this.close(null, pstmt, conn);
return rs;
} /**
* 关闭数据库连接,释放所占的系统资源
* @param rs结果集、ppst预编译命令、conn数据库
* @return null
* @throws Exception
*/
public void close(ResultSet rs, PreparedStatement ppst, Connection conn) throws Exception{
if(rs != null){
rs.close();
}
if(ppst != null){
ppst.close();
}
if(conn != null){
conn.close();
}
}
}

 (4)定义通用分页查询实体类

package com.jkitn.jkits.common;

import java.util.List;

/**
* 说明:实现通用分页查询实体类
* @author xdweleven
* @version 1.0
*/
public class PageBean<T> {
private int totalRows; // 总记录数
private int totalPages; // 总页数
private int curPage; // 当前页码
private int prePage; // 上一页页码
private int nextPage; // 下一页页码
private int rowsPerPage; // 每页显示的记录数
private List<T> pageList; // 当前页的数据集 /**
* 初始化分页bean对象
* @param totalRows 总记录数
* @param rowsPerPage 每页显示的记录数
*/
public void initPageBean(int totalRows, int rowsPerPage){
this.rowsPerPage = rowsPerPage;
this.totalRows = totalRows;
this.totalPages = (this.totalRows-1)/this.rowsPerPage + 1;
// 设置上一页
if(this.curPage == 1){
this.setPrePage(1);
}else{
this.setPrePage(this.curPage-1);
}
// 设置下一页
if(this.curPage == this.totalPages){
this.setNextPage(this.totalPages);
}else{
this.setNextPage(this.curPage + 1);
}
} /**
* 生成SQLServer的分页查询语句
* @param sql 原始sql语句
* @param curPage 第几页
* @param rowsPerPage 每页多少行
*/
public String getPageSQLServer(String sql, int curPage, int rowsPerPage){
String afterFrom = sql.toLowerCase().substring(sql.indexOf("from"));
String pageSql = null;
if(afterFrom.indexOf("where") == -1){
pageSql = "select top "+ rowsPerPage + " * "+afterFrom
+" where id not in(select top "+rowsPerPage*(curPage-1)+" id "
+afterFrom+" order by id desc)"+"order by id desc";
}else{
pageSql = "select top "+ rowsPerPage + " * "+afterFrom
+" and id not in(select top "+rowsPerPage*(curPage-1)+" id "
+afterFrom+" order by id desc)"+"order by id desc";
}
return pageSql;
} /**
* 生成MySql分页sql语句
* @param sql 原始sql语句
* @param curPage 第几页
* @param rowsPerPage 每页多少行
* @return 返回分页SQL语句
*/
public String getPageMySQL(String sql, int curPage, int rowsPerPage){
String pageSql = sql+" limit "+ (curPage-1)*rowsPerPage+","+rowsPerPage;
return pageSql;
} /**
* 生成Oracle分页查询语句
* @param sql 原始sql语句
* @return 返回分页SQL语句
*/
public String getOrclPageSql(String sql){
int begin = (curPage - 1) * rowsPerPage;
int end = begin + rowsPerPage;
StringBuffer pagingSelect = new StringBuffer(300);
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
pagingSelect.append(sql);
pagingSelect.append(" ) row_ where rownum <= "+end+") where rownum_ > "+begin);
return pagingSelect.toString();
} public List<T> getPageList() {
return pageList;
} public void setPageList(List<T> pageList) {
this.pageList = pageList;
}
public int getTotalRows() {
return totalRows;
} public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
} public int getTotalPages() {
return totalPages;
} public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
} public int getCurPage() {
return curPage;
} public void setCurPage(int curPage) {
this.curPage = curPage;
} public int getPrePage() {
return prePage;
} public void setPrePage(int prePage) {
this.prePage = prePage;
} public int getNextPage() {
return nextPage;
} public void setNextPage(int nextPage) {
this.nextPage = nextPage;
} public int getRowsPerPage() {
return rowsPerPage;
} public void setRowsPerPage(int rowsPerPage) {
this.rowsPerPage = rowsPerPage;
}
}

 (5)定义SQL语句的经常用法工具类

package com.jkitn.jkits.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 说明:自己主动生成对象的增删改查SQL语句的通用方法工具类
* @author xdweleven
* @version 1.0
*/
public class SQLUtil {
/**
* 自己主动生成插入指定对象的SQL语句,不包括对象属性的值为空的字段
* @param obj 待生成插入SQL语句的对象
* @param tableName 待插入语句相应的数据库表的名称
* @return 返回一个包括SQL语句、SQL语句參数值及參数值类型的Map对象
*/
public static Map<String, Object> generateInsertExceptNull(Object obj, String tableName) {
StringBuffer columnStrBuf = new StringBuffer(); // 记录数据表的字段名称
StringBuffer paramStrBuf = new StringBuffer(); // 记录SQL语句相应插入的占位符
List<Object> paramValues = new ArrayList<Object>(); // 记录对象參数值
List<Integer> paramsType = new ArrayList<Integer>(); // 记录參数值类型
// 查询待插入对象的属性值不为空的属性名称
List<Object> fieldList = ReflectionUtil.getNotNullField(obj);
try {
for (int i = 0; i < fieldList.size(); i++) {
Field field = (Field) fieldList.get(i);
field.setAccessible(true);
// 记录对象属性名称
columnStrBuf.append(field.getName());
if (i != fieldList.size() - 1) {
columnStrBuf.append(",");
} // 记录插入SQL语句的參数占位符
if("class java.util.Date".equals(field.getType().toString())
&& field.get(obj) != null){
String timeStr = DateUtil.formatDate((Date)field.get(obj), "yyyy-MM-dd HH:mm:ss");
paramStrBuf.append("to_date(?, 'yyyy-MM-dd HH24:mi:ss')");
paramValues.add(timeStr);
// 记录对象属性的数据类型
paramsType.add(getOrclDataType(field.getType().toString()));
}else{
paramStrBuf.append("?");
paramValues.add(field.get(obj));
// 记录对象属性的数据类型
paramsType.add(getOrclDataType(field.getType().toString()));
} if (i != fieldList.size() - 1) {
paramStrBuf.append(",");
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
// 生成插入操作的SQL语句
StringBuffer sb = new StringBuffer();
sb.append("insert into ");
sb.append(tableName);
sb.append(" (");
sb.append(columnStrBuf);
sb.append(") ");
sb.append("values");
sb.append(" (");
sb.append(paramStrBuf);
sb.append(")");
// 将生成的SQL语句、SQL语句參数值及各參数值的数据类型用map保存并返回
Map<String, Object> sqlMap = new HashMap<String, Object>();
sqlMap.put("sql", sb.toString());
sqlMap.put("paramsValues", paramValues.toArray());
sqlMap.put("paramsTypes", paramsType.toArray());
return sqlMap;
} /**
* 自己主动生成插入指定对象的SQL语句,包括对象属性的值为空的字段,不包括自增长主键,若不存在,调用时直接置为null.
* @param obj 待生成插入SQL语句的对象
* @param tableName 待插入语句相应的数据库表的名称
* @param keyColumn 数据表主键名称
* @return 返回一个包括SQL语句、SQL语句參数值及參数值类型的Map对象
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public static Map<String, Object> generateInsertWithNull(Object obj,
String tableName, String keyColumn) throws IllegalArgumentException, IllegalAccessException {
StringBuffer columnStrBuf = new StringBuffer();
StringBuffer paramStrBuf = new StringBuffer(); // 记录SQL语句相应插入的占位符
List<Object> columnNameList = new ArrayList<Object>(); // 记录数据表的字段名称
List<Object> paramValues = new ArrayList<Object>(); // 记录对象參数值
List<Integer> paramsType = new ArrayList<Integer>(); // 记录參数值类型
Field[] fields = obj.getClass().getDeclaredFields();
for(int i = 0; i < fields.length; i++){
fields[i].setAccessible(true);
// 记录对象属性名称
if(!fields[i].getName().equalsIgnoreCase(keyColumn)){ // 非主键列记录插入SQL语句的參数占位符
columnStrBuf.append(fields[i].getName());
columnNameList.add(fields[i].getName());
if (i != fields.length - 1) {
columnStrBuf.append(",");
}
if("class java.util.Date".equals(fields[i].getType().toString())
&& fields[i].get(obj) != null){
String timeStr = DateUtil.formatDate((Date)fields[i].get(obj), "yyyy-MM-dd HH:mm:ss");
paramStrBuf.append("to_date(? , 'yyyy-MM-dd HH24:mi:ss')");
paramValues.add(timeStr);
// 记录对象属性的数据类型
paramsType.add(getOrclDataType(fields[i].getType().toString()));
}else{
paramStrBuf.append("?");
paramValues.add(fields[i].get(obj));
// 记录对象属性的数据类型
paramsType.add(getOrclDataType(fields[i].getType().toString()));
}
if (i != fields.length - 1) {
paramStrBuf.append(",");
}
}
}
// 生成插入操作的SQL语句
StringBuffer sb = new StringBuffer();
sb.append("insert into ");
sb.append(tableName);
sb.append(" (");
sb.append(columnStrBuf);
sb.append(") ");
sb.append("values");
sb.append(" (");
sb.append(paramStrBuf);
sb.append(")");
// 将生成的SQL语句、SQL语句的列名称用map保存并返回
Map<String, Object> sqlMap = new HashMap<String, Object>(); /*
System.out.println(sb.toString());
System.out.println(columnNameList.toString());
System.out.println(paramValues.toString());
System.out.println(paramsType.toString());
*/
sqlMap.put("sql", sb.toString());
sqlMap.put("columnNameList", columnNameList.toArray());
sqlMap.put("paramsValues", paramValues.toArray());
sqlMap.put("paramsTypes", paramsType.toArray());
return sqlMap;
} /**
* 自己主动生成更新指定对象的SQL语句
* @param obj 待生成更新SQL语句的对象
* @param tableName 待更新语句相应的数据库表的名称
* @param keyColumn 待更新记录的限定字段
* @return 返回一个包括SQL语句及參数值的数组
*/
public static Object[] generateUpdate(Object obj, String tableName, String keyColumn) {
StringBuffer columnSB = new StringBuffer();
List<Object> params = new ArrayList<Object>();
Object keyValue = null;
// 获取属性值不为空的数据表字段名称
List<Object> fieldList = ReflectionUtil.getNotNullField(obj);
try {
for (int i = 0; i < fieldList.size(); i++) {
Field field = (Field) fieldList.get(i);
field.setAccessible(true); if (field.getName().equalsIgnoreCase(keyColumn)) {
keyValue = field.get(obj);
} else {
columnSB.append(field.getName());
if("class java.util.Date".equals(field.getType().toString())
&& field.get(obj) != null){
String timeStr = DateUtil.formatDate((Date)field.get(obj), "yyyy-MM-dd HH:mm:ss");
columnSB.append("=to_date(?, 'yyyy-MM-dd HH24:mi:ss')");
params.add(timeStr);
}else{
columnSB.append("=?");
params.add(field.get(obj));
}
if (i != fieldList.size() - 1) {
columnSB.append(",");
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
if (keyValue == null) {
throw new IllegalArgumentException("数据表 [" + tableName+ "] 中的字段'"+keyColumn+"'的值不能为空.");
}else{
params.add(keyValue);
}
StringBuffer sb = new StringBuffer();
sb.append("update ");
sb.append(tableName);
sb.append(" set ");
if(columnSB.length() >= 0){
sb.append(columnSB);
}else{
sb.append(keyColumn);
sb.append("=? ");
params.add(keyValue);
}
sb.append(" where ");
sb.append(keyColumn);
sb.append("=? ");
return new Object[] { sb.toString(), params.toArray() };
} /**
* 返回java数据类型相应的Oracle数据库的数据类型值
* @param javaType java数据类型
* @return 返回Oracle数据表的字段数据类型
*/
public static int getOrclDataType(String javaType){
if("class java.lang.String".equals(javaType)){
return java.sql.Types.VARCHAR;
}else if("class java.lang.Integer".equals(javaType) || "int".equals(javaType)){
return java.sql.Types.INTEGER;
}else if("class java.lang.Double".equals(javaType) || "double".equals(javaType)){
return java.sql.Types.DOUBLE;
}else if("class java.lang.Float".equals(javaType) || "float".equals(javaType)){
return java.sql.Types.FLOAT;
}else if("char".equals(javaType)){
return java.sql.Types.CHAR;
}else if("class java.lang.Long".equals(javaType) || "long".equals(javaType)){
return java.sql.Types.NUMERIC;
}else if("class java.util.Date".equals(javaType)){
return java.sql.Types.DATE;
}else{
return java.sql.Types.VARCHAR;
}
} /**
* 生成SQL语句中的where子句及where子句中參数值
* @param obj where条件子句的对象
* @return 返回条件不为空的where子句
* @throws Exception
* @throws
*/
public static Map<String, Object> generateWhereStr(Object obj) throws Exception{
StringBuffer whereStrBuf = new StringBuffer(); // where子句
List<Object> whereParamValues = new ArrayList<Object>(); // where子句中的參数值
whereStrBuf.append(" where 1 = 1 ");
if(obj != null){
Field[] fields = obj.getClass().getDeclaredFields();
for(int i = 0; i < fields.length; i++){
fields[i].setAccessible(true);
Object columnName = fields[i].get(obj);
if(columnName != null && !"".equals(columnName)){
whereStrBuf.append(" and ");
whereStrBuf.append(fields[i].getName());
whereStrBuf.append("=?");
whereParamValues.add(columnName);
}
}
}
Map<String, Object> whereMap = new HashMap<String, Object>(); /* System.out.println(whereStrBuf.toString());
System.out.println(whereParamValues);
*/
whereMap.put("whereStr", whereStrBuf.toString());
whereMap.put("whereParamValues", whereParamValues.toArray());
return whereMap;
} }

 (6)扩展JAVA对象的反射工具类

package com.jkitn.jkits.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List; /**
* 说明:扩展JAVA对象的反射机制
* @author xdweleven
* @version 1.0
*/
public class ReflectionUtil { /**
* 设置对象的指定属性名称的属性值
* @param obj 待设置的对象
* @param fieldName 对象属性名称
* @param value 属性值
*/
public static void setFieldValue(Object obj, String fieldName, Object value) {
Class<? extends Object> c = obj.getClass();
try {
Field field = null;
Field[] fields = c.getDeclaredFields();
for(int i = 0; i < fields.length; i++){
String fieldNameTemp = fields[i].getName();
if(fieldNameTemp.equalsIgnoreCase(fieldName)){
field = c.getDeclaredField(fieldNameTemp);
field.setAccessible(true);
field.set(obj, value);
return;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**
* 获取对象的指定属性名称的属性值
* @param obj 待设置的对象
* @param fieldName 对象属性名称
*/
public static Object getFieldValue(Object obj, String fieldName) {
Class<? extends Object> c = obj.getClass();
Field[] fields = c.getDeclaredFields();
try {
for(int i = 0; i < fields.length; i++){
if(fields[i].getName().equalsIgnoreCase(fieldName)){
fields[i].setAccessible(true);
return fields[i].get(obj);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
} /**
* 获取对象的属性值不为空的属性名称
* @param obj 待获取的对象
* @return 返回属性值不为空的对象的属性名称列表
*/
public static List<Object> getNotNullField(Object obj) {
Class<? extends Object> c = obj.getClass();
List<Object> list = new ArrayList<Object>();
try {
Field[] fields = c.getDeclaredFields();
for(int i = 0; i < fields.length; i++){
fields[i].setAccessible(true);
if(fields[i].get(obj) != null){
list.add(fields[i]);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return list;
}
}

 (7)定义实现数据库的CRUD基本操作BaseDao

package com.jkitn.jkits.dao.common;

import java.io.Serializable;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map; import com.jkitn.jkits.common.DBConn;
import com.jkitn.jkits.common.PageBean;
import com.jkitn.jkits.util.ReflectionUtil;
import com.jkitn.jkits.util.SQLUtil; /**
* 说明:封装实现数据库的CRUD相关的底层操作。
* @author xdweleven
* @version 1.0
*/
public class BaseDao{
// 获取数据库链接实例
private DBConn dbconn = new DBConn();
/** 数据库表的前缀 */
public static final String TB_PREFIX = "tb_jkit_";
/** 数据库表的查询前缀 */
public static final String SELECT_TB_PREFIX = "select * from tb_jkit_";
/** 升序排列 */
public static final String ASC = "asc";
/** 降序排列 */
public static final String DESC = "desc"; /**
* 依据ID查找对象
* @param classType 对象类型
* @param columnName 编号字段名称
* @param id 对象编号
* @return 返回实体对象
*/
public <T> T queryById(Class<T> classType, String columnName, Serializable id)
throws Exception{
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append(SELECT_TB_PREFIX);
sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
sqlBuffer.append(" where ");
sqlBuffer.append(columnName);
sqlBuffer.append(" = ? ");
this.showSQL(sqlBuffer.toString());
return dbconn.execQuery(sqlBuffer.toString(), new RowMapper<T>(classType),
new Object[]{id}).get(0);
} /**
* 查询全部指定class类型的对象信息
* @param classType 对象类型
* @return 返回实体对象列表
*/
public <T> List<T> queryAll(Class<T> classType) throws Exception{
String sql = SELECT_TB_PREFIX + this.toLowerCaseFirstOne(classType.getSimpleName());
this.showSQL(sql);
return dbconn.execQuery(sql, new RowMapper<T>(classType));
} /**
* 查询指定对象类型的对象信息,并依照指定的排序字段进行升序或降序排序
* @param classType 对象类型
* @param orderColumn 排序字段
* @param ascOrDesc 降序或升序:asc表示升序。desc表示降序
* @return 返回实体对象列表
*/
public <T> List<T> queryAllWithOrder(Class<T> classType, String orderColumn,
String ascOrDesc) throws Exception{
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append(SELECT_TB_PREFIX);
sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
sqlBuffer.append(" order by ");
sqlBuffer.append(orderColumn);
sqlBuffer.append(" ");
sqlBuffer.append(ascOrDesc);
this.showSQL(sqlBuffer.toString());
return dbconn.execQuery(sqlBuffer.toString(), new RowMapper<T>(classType));
} /**
* 查询指定SQL语句的对象信息列表
* @param sql 查询语句
* @param classType 对象类型
* @param params SQL语句參数
* @return 返回实体对象列表
*/
public <T> List<T> query(String sql, Class<T> classType, Object... params)
throws Exception{
this.showSQL(sql);
return dbconn.execQuery(sql, new RowMapper<T>(classType), params);
} /**
* 查询指定SQL语句的对象信息列表
* @param sql 查询语句
* @param classType 对象类型
* @param params SQL语句參数
* @return 返回实体对象列表
*/
public <T> T queryForObj(String sql, Class<T> classType, Object... params)
throws Exception{
this.showSQL(sql);
return dbconn.execQuery(sql, new RowMapper<T>(classType), params).get(0);
} /**
* 分页查询实体对象列表信息
* @param sql 原始的SQL语句
* @param classType 对象类型
* @param curPage 当前页码
* @param rowsPerPage 每页显示的记录数
* @param params SQL语句參数
* @return 返回当前页码的分页对象
*/
public <T> PageBean<T> queryByPage(String sql, Class<T> classType, int curPage,
int rowsPerPage, Object... params) throws Exception{
// 获取记录总数
int totalRows = this.getTotalRows(sql, params);
PageBean<T> pageBean = new PageBean<T>();
pageBean.setCurPage(curPage); // 设置当前页码
pageBean.initPageBean(totalRows, rowsPerPage); // 初始化分页对象的相关属性
// 生成当前分页查询语句(MySql)
String pageSql = pageBean.getPageMySQL(sql, curPage, rowsPerPage);
this.showSQL(pageSql);
// 运行查询操作
pageBean.setPageList(dbconn.execQuery(sql, new RowMapper<T>(classType), params));
return pageBean;
} /**
* 保存对象到数据库中,若数据库中的用户表有自增序列,则须要指出表中自增列的字段名称,另外,
* 数据库中相应的自增序列的名称需按例如以下格式取名:class名称_自增列字段名称_SEQ,
* 比如用户的class为Users,自增序列字段名称为id,则数据库中的自增序列的名称取名为USERS_ID_SEQ.
* @param obj 实体对象
* @param sequenceKeyColumn 数据表自增序列的字段名称,若不存在。则置为null。 * @return 返回被更新的记录数
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public <T> int insert(T obj, String sequenceKeyColumn) throws Exception{
String tableName = TB_PREFIX + this.toLowerCaseFirstOne(obj.getClass().getSimpleName());
// 自己主动生成对象的无自增序列插入SQL语句及其相关插入的參数值和类型
Map<String, Object> sqlMap = SQLUtil.generateInsertWithNull(obj, tableName, sequenceKeyColumn);
String sql = sqlMap.get("sql").toString(); // SQL语句
Object[] paramsValues = (Object[])sqlMap.get("paramsValues"); // SQL语句的參数值
// int[] paramsTypes = this.parseArrayToInt((Object[])sqlMap.get("paramsTypes")); // 參数值类型
this.showSQL(sql);
return dbconn.execUpdate(sql, paramsValues);
} /**
* 更新对象
* @param obj 待更新的实体对象
* @param keyColumn 更新对象的限定条件字段名称
* @return 返回被更新的记录数
*/
public <T> int update(T obj, String keyColumn) throws Exception{
String tableName = TB_PREFIX + this.toLowerCaseFirstOne(obj.getClass().getSimpleName());
// 自己主动生成对象的更新操作的SQL语句及其參数值
Object[] updateSql = SQLUtil.generateUpdate(obj, tableName, keyColumn);
this.showSQL(updateSql[0].toString());
return dbconn.execUpdate(updateSql[0].toString(), (Object[])updateSql[1]);
} /**
* 删除对象
* @param obj 待更新的实体对象
* @param keyColumn 删除的限定条件字段
* @return 返回被删除的记录数
*/
public <T> int delete(T obj, String keyColumn) throws Exception{
// 获取限定条件的值
Object keyValue = ReflectionUtil.getFieldValue(obj, keyColumn);
if(keyValue == null){
throw new RuntimeException("["+obj.getClass()+"]中不存在属性'"+keyColumn+"'或属性值为空.");
}
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append("delete from ");
sqlBuffer.append(TB_PREFIX);
sqlBuffer.append(this.toLowerCaseFirstOne(obj.getClass().getSimpleName()));
sqlBuffer.append(" where ");
sqlBuffer.append(keyColumn);
sqlBuffer.append(" = ? ");
this.showSQL(sqlBuffer.toString());
return dbconn.execUpdate(sqlBuffer.toString(), keyValue.toString());
} /**
* 删除指定编号的实体对象
* @param classType 对象类型
* @param keyColumn ID相应的数据表列名称
* @param id 实体对象编号
* @return 返回删除的记录数
*/
public <T> int deleteById(Class<T> classType, String keyColumn, Serializable id)
throws Exception{
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append("delete from ");
sqlBuffer.append(TB_PREFIX);
sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
sqlBuffer.append(" where ");
sqlBuffer.append(keyColumn);
sqlBuffer.append(" = ? ");
this.showSQL(sqlBuffer.toString());
return dbconn.execUpdate(sqlBuffer.toString(), id);
} /**
* 批量删除指定编号的实体对象
* @param classType 对象类型
* @param idColumnName 编号字段名称
* @param ids 待删除对象的编号数组
*/
public <T> int deleteByIds(Class<T> classType, String idColumnName,
Serializable[] ids) throws Exception{
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append("delete from ");
sqlBuffer.append(TB_PREFIX);
sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
sqlBuffer.append(" where ");
sqlBuffer.append(idColumnName);
sqlBuffer.append(" = ? ");
this.showSQL(sqlBuffer.toString());
int rowNums = 0; // 删除的记录数
for(int i = 0; i < ids.length; i++){
rowNums += this.deleteById(classType, idColumnName, ids[i]);
}
return rowNums;
} /**
* 更新操作
* @param sql 删除操作的SQL语句
* @param params SQL语句中的參数值
* @return 返回删除的记录数
*/
public int update(String sql, Object... params) throws Exception{
this.showSQL(sql);
return dbconn.execUpdate(sql, params);
} /**
* 批量更新对象
* @param objs 待更新的实体对象列表
* @param keyColumn 主键字段名称
*/
public <T> int batchUpdate(List<T> objs, String keyColumn) throws Exception{
if(objs == null || objs.isEmpty()){
return 0;
}
int updateNum = 0;
// 自己主动生成对象的更新操作的SQL语句及其參数值
for(int i = 0; i < objs.size(); i++){
T obj = objs.get(i);
updateNum += this.update(obj, keyColumn);
}
return updateNum;
} /**
* 批量插入对象
* @param objs 待新增的实体对象列表
* @param keyColumn 数据表主键列名称
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public <T> int batchInsert(List<T> objs, String keyColumn) throws Exception {
if(objs == null || objs.isEmpty()){
return 0;
}
int updateNum = 0;
// 自己主动生成对象的更新操作的SQL语句及其參数值
for(int i = 0; i < objs.size(); i++){
T obj = objs.get(i);
updateNum += this.insert(obj, keyColumn);
}
return updateNum;
} /**
* 统计指定统计数量的SQL语句
* @param sql 待运行的SQL语句
* @param params SQL语句參数值
* @return 返回记录总数
* @throws Exception
*/
public int getTotalRows(String sql, Object... params) throws Exception{
String totalRowsSql = "select count(*) totalRows from ( "+sql+" )";
this.showSQL(totalRowsSql);
ResultSet rs = dbconn.queryForResultSet(totalRowsSql, params);
while(rs.next()){
return rs.getInt("totalRows");
}
return 0;
} /**
* 删除操作
* @param sql 删除操作的SQL语句
* @param params SQL语句中的參数值
* @return 返回删除的记录数
*/
public int delete(String sql, Object... params) throws Exception{
this.showSQL(sql);
return dbconn.execUpdate(sql, params);
} /**
* 获取下一个指定自增序列的值(MySql)
* @param classType 对象类型
* @param seqColName 自增字段名称
* @return 返回指定表的主键自增序列的最新值
*/
public <T> int getNextAutoIncrementVal(Class<T> classType, String seqColName) throws Exception{
StringBuffer sqlBuf = new StringBuffer();
sqlBuf.append("select max(");
sqlBuf.append(seqColName);
sqlBuf.append(")+1 nextId from ");
sqlBuf.append(TB_PREFIX);
sqlBuf.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
this.showSQL(sqlBuf.toString());
ResultSet rs = dbconn.queryForResultSet(sqlBuf.toString());
if(rs.next()){
return rs.getInt("nextId");
}else{
return 0;
}
} /**
* 首字母转小写
* @param str 待转换的字符创
* @return 返回首字母小写后的字符串
*/
public String toLowerCaseFirstOne(String str){
if(Character.isLowerCase(str.charAt(0))){
return str;
}else{
return (new StringBuilder()).append(Character.toLowerCase(str.charAt(0))).
append(str.substring(1)).toString();
}
} /**
* 首字母转大写
* @param str 待转换的字符串
* @return 返回首字母大写的字符串
*/
public String toUpperCaseFirstOne(String str){
if(Character.isUpperCase(str.charAt(0))){
return str;
}else{
return (new StringBuilder()).append(Character.toUpperCase(str.charAt(0))).
append(str.substring(1)).toString();
}
} /**
* 打印SQL语句
* @param sql
*/
public void showSQL(String sql){
System.out.println(sql);
} }

以上是依据自己的理解封装的一些经常使用DAO层操作,并已运用到部署上线的两个项目中,眼下尚未报出BUG。

但在效率方面,个人认为还有非常多地方须要优化的地方。比方说批量增删改操作。依据我个人PC机測试的结果,使用JDBC自带的批量操作。要比上述简单循环的操作速度要慢,但我还是认为这部分的效率还有非常大的提升空间,希望能有位IT大卡给我指点一二,不胜感激!

版权声明:本文博客原创文章,博客,未经同意,不得转载。

JAVA实现DAO基本层CRUD操作的更多相关文章

  1. 【JAVA解析XML文件实现CRUD操作】

    一.简介. 1.xml解析技术有两种:dom和sax 2.dom:Document Object Model,即文档对象模型,是W3C组织推荐的解析XML的一种方式. sax:Simple API f ...

  2. java框架篇---hibernate之CRUD操作

    CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...

  3. Java框架-mybatis02基本的crud操作

    1.搭建mybatis框架 1)导入相关jar包 2)编写核心配置文件(配置数据库连接的相关信息以及配置mapper映射文件) 3)编写dao操作 4)编写mapper映射文件 5)编写实体类 2.执 ...

  4. Java数据库连接——JDBC基础知识(操作数据库:增删改查)

    一.JDBC简介 JDBC是连接java应用程序和数据库之间的桥梁. 什么是JDBC? Java语言访问数据库的一种规范,是一套API. JDBC (Java Database Connectivit ...

  5. Mybatis基于代理Dao实现CRUD操作 及 Mybatis的参数深入

    Mybatis基于代理Dao实现CRUD操作 使用要求: 1.持久层接口和持久层接口的映射配置必须在相同的包下 2.持久层映射配置中mapper标签的namespace属性取值必须是持久层接口的全限定 ...

  6. java oop第09章_JDBC02(CRUD操作)

    第09章_JDBC02(CRUD操作) CRUD(CREATE . RETIVE . UPDATE . DELETE)增删改查. DAO中会提供一些CRUD操作方法,调用者可以通过调用这些方法完成相应 ...

  7. 【Java EE 学习 44】【Hibernate学习第一天】【Hibernate对单表的CRUD操作】

    一.Hibernate简介 1.hibernate是对jdbc的二次开发 2.jdbc没有缓存机制,但是hibernate有. 3.hibernate的有点和缺点 (1)优点:有缓存,而且是二级缓存: ...

  8. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. Mybatis学习之自定义持久层框架(五) 自定义持久层框架:封装CRUD操作

    前言 上一篇文章我们完成了生产sqlSession的工作,与数据库的连接和创建会话的工作都已完成,今天我们可以来决定会话的内容了. 封装CRUD操作 首先我们需要创建一个SqlSession接口类,在 ...

随机推荐

  1. Hadoop-2.2.0中国文献—— MapReduce 下一代 -- 公平调度

    目的 此文档描写叙述了 FairScheduler, Hadoop 的一个可插入式的调度器.同意 YARN 应用在一个大集群中公平地共享资源. 简单介绍 公平调度是一种分配资源给应用的方法,以致到最后 ...

  2. HTTPS原理(转)

    HTTPS是什么 HTTPS全称为Hypertext Transfer Protocol over Secure Socket Layer,及以安全为目标的HTTP通道,简单说就是HTTP的安全版本. ...

  3. SE 2014年5月27日

    R1模拟总部,R2 与R3模拟分部 如图配置 要求使用 GRE over IPSec VPN 主模式,启用动态路由协议rip使得总部与两分部内网可相互通讯,但要求分部用户数据流不允许互通! 步骤: 1 ...

  4. Entity Framework6使用SQL Server Compact免安装部署

    原文:Entity Framework6使用SQL Server Compact免安装部署 使用Nuget安装以下包: EntityFramework.6.0.2 EntityFramework.Sq ...

  5. VC6.0入门使用

    软件下载地址 http://pan.baidu.com/s/1qWuqFAO 新建win console 32 project,然后新建header文件.最后新建source cpp文件.如图所看到的

  6. hdu 2051 Bitset (java)

    问题: 之前做过类似题,但这次仍然不能解决相关问题. 字符串倒过来输:StringBuffer str=new StringBuffer(s); s=str.reverse().toString() ...

  7. uva 11722 - Joining with Friend(概率)

    题目连接:uva 11722 - Joining with Friend 题目大意:你和朋友乘火车,而且都会路过A市.给定两人可能到达A市的时段,火车会停w.问说两人能够见面的概率. 解题思路:y = ...

  8. Java的内存泄漏和垃圾回收机制

    JAVA会产生内存泄露吗?首先,答案是肯定的. Java尽管有垃圾回收器,但依旧存在泄漏. Java内存泄漏跟C/C++内存泄漏的概念不一样:C/C++的内存泄漏是指Malloc了一些资源.最后没有f ...

  9. HDU 4998 Rotate

    题意: n次旋转  每次平面绕ai点旋转pi弧度  问  最后状态相当于初始状态绕A点旋转P弧度  A和P是多少 思路: 如果初始X点的最后状态为X'点  则圆心一定在X和X'连线的垂直平分线上  那 ...

  10. 怎样从Hadoop安全模式中进入正常模式

    问题: 在Hadoop中,新建一个文件夹,报错了,提示mkdir: org.apache.hadoop.hdfs.server.namenode.SafeModeException: Cannot c ...