当前位置:编程学习 > JAVA >>

jdbc封装(实现对实体的增删改查[分页]),可辅助学习Hibernate

JdbcUtils:

package com.weibo.gaollg.dao;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * JDBC连接类
 * @author <a href="mailto:gaollg@sina.com">Gaollg</a>
 */
public class JdbcUtils {

private static String className = "sun.jdbc.odbc.JdbcOdbcDriver";
private static String url = "jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=D:\\student.mdb";
private static String user = "";
private static String password = "";

static{
try {
Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e.getMessage());
}
}

/**
 * 禁止实例化
 */
private JdbcUtils() {}

/**
 * 取得连接
 * @return
 * @throws SQLException 取得连接失败时抛出异常
 */
public static Connection getConnection(){
Connection conn = null;
try {
Properties prop = new Properties();  
prop.put("charSet", "gb2312");
prop.put("user", user);
prop.put("password", password);
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
return conn;
}

/**
 * 关闭连接,释放资源
 * @param rs
 * @param stmt
 * @param conn
 */
public static void free(ResultSet rs, Statement stmt, Connection conn) {
try { // 捕捉异常
try {
if (rs!=null) { // 当ResultSet对象的实例rs不为空时
rs.close(); // 关闭ResultSet对象
}
} finally {
try {
if (stmt!=null) { // 当Statement对象的实例stmt不为空时
stmt.close(); // 关闭Statement对象
}
}catch (Exception e) {
e.printStackTrace();

finally {
if (conn!=null) { // 当Connection对象的实例conn不为空时
conn.close(); // 关闭Connection对象
}
}
}
} catch (Exception e) {
e.printStackTrace(); // 输出异常信息
}
}

/**
 * 给PreparedStatement赋值
 * @param pstmt
 * @param values
 * @throws SQLException
 */
private static void setPstmtValues(PreparedStatement pstmt, Object... values)
throws SQLException {
if(pstmt!=null&values!=null){
for (int i = 0; i < values.length; i++) {
pstmt.setObject(i+1, values[i]);
}
}
}

/**
 * 执行SQL语句(insert,update,delete)
 * @param callBack 回调函数中rs可获取[由于执行此 Statement 对象]而创建的所有自动生成的键
 * @param sql sql语句
 * @param values 对就占位符的值
 * @return 返回影响的行数
 */
public static int execute(JdbcUtils.CallBack callBack, String sql,Object... values){
int retVal = 0;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
pstmt = conn.prepareStatement(sql);
setPstmtValues(pstmt, values);
retVal = pstmt.executeUpdate();
if(callBack!=null){
rs = pstmt.getGeneratedKeys();
callBack.callback(rs);//回调
}
}catch (Exception e) {
throw new RuntimeException(e.getMessage());
}finally{
JdbcUtils.free(rs, pstmt, conn);
}
return retVal;
}

/**
 * 执行SQL语句(insert,update,delete)
 * @param sql sql语句
 * @param values 对就占位符的值
 * @return 返回影响的行数
 */
public static int execute(String sql,Object... values){
return execute(null, sql, values);
}

/**
 * 回调一次 未经过任何处理的ResultSet
 * @param callBack
 * @param sql
 * @param values
 * @see JdbcUtils.query()
 */
public static void query(JdbcUtils.CallBack callBack, String sql, Object... values){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
pstmt = conn.prepareStatement(sql);
setPstmtValues(pstmt, values);
rs = pstmt.executeQuery();
callBack.callback(rs);
}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally{
JdbcUtils.free(rs, pstmt, conn);
}
}

/**
 * JdbcUtils回调接口
 * 2011-11-3 下午08:29:15
 * @author <a href="mailto:gaollg@sina.com">Gaollg</a>
 *
 */
public static interface CallBack{
/**
 * 回调方法
 * @throws SQLException 
 */
public void callback(ResultSet rs) throws SQLException;
}

/**
 * 查询出相同名字的Field并返回
 * @param <T>
 * @param clazz 实体类
 * @param dateColumns 数据库中对应的列
 * @return
 */
public static <T> List<Field> getEntityField(final Class<T> clazz,
List<String> dateColumns){
/** 与实体对应的列  */
List<Field> fields = new ArrayList<Field>();
for(Field f : clazz.getDeclaredFields()){//遍历field
f.setAccessible(true);
int mod = f.getModifiers();
if ((mod&Modifier.FINAL)==0){//没有final
if ((mod&Modifier.STATIC)==0){//没有static
for(String c:dateColumns){
if(c.equalsIgnoreCase(f.getName())){
fields.add(f);
}
}
}
}
}
return fields;
}

/**
 * 查询实体列表
 * @param <T> 
 * @param clazz
 * @param sql
 * @param values
 * @return
 */
public static <T> List<T> queryList(final Class<T> clazz, String sql, Object... values){
final List<T> list = new ArrayList<T>();
JdbcUtils.query(new JdbcUtils.CallBack() {
@Override
public void callback(ResultSet rs) throws SQLException {
//取得列名
ResultSetMetaData data = rs.getMetaData();
/** 数据库中的列  */
List<String> dateColumns = new ArrayList<String>();
for(int i=0;i<data.getColumnCount();i++){
dateColumns.add(data.getColumnName(i+1));
}
List<Field> fields = JdbcUtils.getEntityField(clazz, dateColumns);
//循环并注入
while(rs.next()){
try {
T t = (T)clazz.newInstance();
JdbcUtils.injectByRs(rs, fields, t);//往t中注入值
list.add(t);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}

}, sql, values);
return list;
}

/**
 * 查询实体
 * @param <T>
 * @param clazz
 * @param sql
 * @param values
 * @return
 */
public static <T> T queryEntity(final Class<T> clazz, String sql, Object... values){
List<T> list = queryList(clazz, sql, values);
if(list.size()==0){
return null;
}
return list.get(0);
}

/**
 * 根据rs在对象t中注入fields的值
 * @param <T>
 * @param rs
 * @param fields
 * @param t
 * @throws SQLException
 * @throws IllegalAccessException
 */
private static <T> void injectByRs(ResultSet rs, List<Field> fields, T t)
throws SQLException, IllegalAccessException {
for(Field f : fields){
Object value = null;
if(f.getType().toString().equals("byte") || f.getType()==Byte.class){
value = rs.getByte(f.getName());

else if(f.getType().toString().equals("boolean") || f.getType()==Boolean.class){
value = rs.getBoolean(f.getName());

else if(f.getType().toString().equals("double") || f.getType()==Double.class){
value = rs.getDouble(f.getName());

else if(f.getType().toString().equals("float") || f.getType()==Float.class){
value = rs.getFloat(f.getName());

else if(f.getType().toString().equals("int") || f.getType()==Integer.class){
value = rs.getInt(f.getName());

else if(f.getType().toString().equals("long") || f.getType()==Long.class){
value = rs.getInt(f.getName());

else if(f.getType().toString().equals("short") || f.getType()==Short.class){
value = rs.getInt(f.getName());
} // 除  char 8种基本数据类型判断完毕
else if(f.getType()==Timestamp.class){
value = rs.getTimestamp(f.getName());
}
else if(f.getType()==Date.class){
value = rs.getDate(f.getName());
}
else if(f.getType()==Time.class){
value = rs.getTime(f.getName());
}
else {
value = rs.getObject(f.getName());
}
f.set(t,value);
}
}

}



更多,请移步下载:http://download.csdn.net/detail/gaollg/4054610

--------------------编程问答-------------------- JdbcCRUDUtils:


package com.weibo.gaollg.dao;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.weibo.gaollg.domain.PageView;
import com.weibo.gaollg.domain.QueryResult;

/**
 * JDBC实现对实体增删改查的封装类
 * @author <a href="mailto:gaollg@sina.com">Gaollg</a>
 */
public class JdbcCRUDUtils {

/**
 * @param obj 保存的实体
 * @return 影响的行数
 */
public static int insert(Object obj){
Class<?> clazz = obj.getClass();
StringBuffer sbSql = new StringBuffer();//就是字符频繁累加的高效率的一个类
sbSql.append("insert into ").append(clazz.getSimpleName()).append("(");
Field[] fields = clazz.getDeclaredFields();
StringBuffer param = new StringBuffer();
for(Field f : fields){
String o = getSqlFields(f, obj);//取得对就字段的值
if(o!=null){//不插入null值
sbSql.append(f.getName()).append(",");
param.append(o).append(",");
}
}
sbSql.deleteCharAt(sbSql.length()-1);//删除最后一个逗号
param.deleteCharAt(param.length()-1);//删除最后一个逗号
sbSql.append(") values(");
sbSql.append(param);
sbSql.append(")");
System.out.println("sql=="+sbSql.toString());
return JdbcUtils.execute(sbSql.toString());
}

/**
 * 更新,约定主健字段均为id
 * @param obj 要保存的实体
 * @param isSavaNull true表示保存 [参数entity] 中的null值,false不保存null值(如自动时间).
 * @return 影响的行数
 */
public static int update(Object obj, boolean isSavaNull) {
Class<?> clazz = obj.getClass();
StringBuffer sbSql = new StringBuffer();
String idSql = "";//更新主键
sbSql.append("update ").append(clazz.getSimpleName()).append(" set ");
Field[] fields = clazz.getDeclaredFields();

for(Field f : fields){
String o = getSqlFields(f, obj);//取得对就字段的值
if(f.getName().equalsIgnoreCase("id")){
//主键
if(o==null){
throw new RuntimeException("主键不能为空!");
}
idSql = " where id="+o;
}
else{
//不是主键
if(isSavaNull || o!=null){//保存null值 || 保存非null值
sbSql.append(f.getName()).append("=").append(o).append(",");
}
}
}
sbSql.deleteCharAt(sbSql.length()-1);//删除最后一个逗号

sbSql.append(idSql);
System.out.println("sql=="+sbSql.toString());
return JdbcUtils.execute(sbSql.toString());
}

/**
 * 删除
 * @param clazz 删除实体的类,方法内部根据此类来获取删除的表
 * @param entityIds 删除的id
 * @return 影响的行数
 */
public static <T> int delete(T... objs) {
if(objs.length==0){//不作任何处理
return 0;
}
Class<? extends Object> clazz = objs[0].getClass(); 
Field idFileld = null;//主键
try {
idFileld = clazz.getDeclaredField("id");
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}

StringBuffer sbSql = new StringBuffer();
//access 必须加 from
sbSql.append("delete from ").append(clazz.getSimpleName()).append(" where id in(");
for (int i = 0; i < objs.length; i++) {
String o = getSqlFields(idFileld, objs[i]);//取得对就字段的值
sbSql.append(o).append(",");
}
sbSql.deleteCharAt(sbSql.length()-1);
sbSql.append(")");
System.out.println("sql=="+sbSql.toString());
return JdbcUtils.execute(sbSql.toString());
}

/**
 * 取得记录个数
 * @param clazz 
 * @param where
 * @param params
 * @return
 */
public static long getCount(Class<? extends Object> clazz, String where, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append("select count(*) from ").append(clazz.getSimpleName()).append(" ");
if(where!=null && !where.equals("")) {
sb.append(" where ").append(where).append(" ");
}
final List<Integer> list = new ArrayList<Integer>();
JdbcUtils.query(new JdbcUtils.CallBack() {
@Override
public void callback(ResultSet rs) throws SQLException {
if(rs.next()){
list.add(rs.getInt(1));
}
}
}, sb.toString(), params);
return list.get(0);
}

/**
 * 取得记录个数
 * @param clazz
 * @return
 */
public static long getCount(Class<? extends Object> clazz){
return getCount(clazz,null);
}

/**
 * 查询记录
 * @param firstResult 起始位置 小于等于0表示从0开始
 * @param maxResult 最大个数 负数和0 表示查询所有
 * @param orderBy 排序 LinkedHashMap<String, Boolean>:Key为排序属性,Value控制升降序,为true时,表示升序(asc),反之为降序(desc)
 * @param where 查询条件
 * @param params 参数 access失效
 * @return
 */
public static <T> QueryResult<T> getScrollData(Class<T> clazz, int firstResult, int maxResult,
LinkedHashMap<String, Boolean> orderBy,
String where, Object... params) {
//"select top 10 * from Student where id not in(" +
//"select top 15 id from Student where 1=2" +
//")"
firstResult = firstResult>0?firstResult:Integer.MAX_VALUE;
maxResult = maxResult>0?maxResult:Integer.MAX_VALUE;//最大显示数,如果小于等于0则显示全部

StringBuffer sbSql = new StringBuffer();
sbSql.append("select top ").append(maxResult).append(" * from ").append(clazz.getSimpleName()).append(" ");
sbSql.append("where id not in (select top "+firstResult+" id from ").append(clazz.getSimpleName()).append(" ");
if(where!=null && !where.equals("")) {
sbSql.append("where ").append(where).append(" ");
if(firstResult==Integer.MAX_VALUE){
sbSql.append("and 1=2 ");
}
}
sbSql.append(buildOrderBy(orderBy));
sbSql.append(") ");
sbSql.append(buildOrderBy(orderBy));
System.out.println(sbSql.toString());
List<T> list = JdbcUtils.queryList(clazz, sbSql.toString());
QueryResult<T> qr = new QueryResult<T>();
qr.setResultlist(list);
qr.setRecordtotal(getCount(clazz, where, params));
return qr;
}

/**
 * asc 升序 desc 降序
 * @param orderBy LinkedHashMap<String, Boolean> Key为属性,Value为true时,表示升序(asc),反之为降序(desc)
 * @return
 */
private static String buildOrderBy(LinkedHashMap<String, Boolean> orderBy){
StringBuilder sb = new StringBuilder();
if(orderBy!=null && !orderBy.isEmpty()){
sb.append(" order by ");
for(Map.Entry<String, Boolean> entry : orderBy.entrySet()){
sb.append(entry.getKey());
if(entry.getValue()){
//升序  可以省略
sb.append(" asc");
}else{
//降序
sb.append(" desc");
}
sb.append(",");
}
sb.deleteCharAt(sb.length()-1);
}
return sb.toString();
}

/**
 * 提供重载
 * @param <T>
 * @param clazz
 * @return
 */

public static <T> QueryResult<T> getScrollData(Class<T> clazz) {
return getScrollData(clazz, -1,-1,(LinkedHashMap<String, Boolean>)null,(String)null);
}
public static <T> QueryResult<T> getScrollData(Class<T> clazz,LinkedHashMap<String, Boolean> orderBy) {
return getScrollData(clazz,-1,-1,orderBy,(String)null);
}
public static <T> QueryResult<T> getScrollData(Class<T> clazz,int firstResult, int maxResult) {
return getScrollData(clazz,firstResult,maxResult,(LinkedHashMap<String, Boolean>)null,(String)null);
}
public static <T> QueryResult<T> getScrollData(Class<T> clazz,int firstResult, int maxResult,
LinkedHashMap<String, Boolean> orderBy) {
return getScrollData(clazz,firstResult,maxResult,orderBy,(String)null);
}
public static <T> QueryResult<T> getScrollData(Class<T> clazz,int firstResult, int maxResult,
String where, Object... params) {
return getScrollData(clazz,firstResult,maxResult,(LinkedHashMap<String, Boolean>)null,where,params);
}
public static <T> QueryResult<T> getScrollData(Class<T> clazz,LinkedHashMap<String, Boolean> orderBy, String where, Object... params) {
return getScrollData(clazz,-1,-1,orderBy,where,params);
}

/**
 * 
 * @param <T>
 * @param clazz 显示类
 * @param maxresult 每页显示数
 * @param currentpage 当前页
 * @param orderBy 排序
 * @param where 条件
 * @param params 参数 access失效
 * @return
 */
public static <T> PageView<T> getPageData(Class<T> clazz,int maxresult, int currentpage,
LinkedHashMap<String, Boolean> orderBy,
String where, Object... params){
PageView<T> pageView = new PageView<T>(maxresult, currentpage);
pageView.setQueryResult(getScrollData(clazz, pageView.getFirstResult(), pageView.getMaxresult(), orderBy, where, params));
return pageView;
}

public static <T> PageView<T> getPageData(Class<T> clazz,int maxresult, int currentpage,
LinkedHashMap<String, Boolean> orderBy){
return getPageData(clazz, maxresult, currentpage, orderBy,null);
}

public static <T> PageView<T> getPageData(Class<T> clazz,int maxresult, int currentpage,
String where, Object... params){
return getPageData(clazz, maxresult, currentpage, (LinkedHashMap<String, Boolean>)null, where, params);
}

/**
 * 生成sql对应的值 如 '字符串','2012-01-01 00:00::00',数字
 * @param f 字段
 * @param obj 取值的对象
 * @return
 */
@SuppressWarnings("deprecation")
public static String getSqlFields(Field f,Object obj){
f.setAccessible(true);
String retVal = null;
try{
Object o = f.get(obj);//取得对就字段的值
if(o==null){//不理会  null值
return null;
}
if(f.getType()==String.class){
//字符串,两边加单引号,还要解决SQL注入,就是内容是一个单引号替换为两个单引号
retVal = (String) o;
retVal = "'"+retVal.replace("'", "''")+"'";
}
else if(f.getType()==Date.class){
//日期,转换为'2012-01-01 00:00::00' 的形式
Date date = (Date) o;
retVal = "'"+date.toLocaleString()+"'";//SimpleDateFormat
}else{
//其它如int float等,直接写就OK
retVal = o + "";
}
return retVal;
}catch (Exception e) {
e.printStackTrace();
}
return null;
}

}



更多,请移步下载:http://download.csdn.net/detail/gaollg/4054610
--------------------编程问答-------------------- --------------------编程问答-------------------- 底层封装学习了。

自己也应该学习如何封装jdbc了、 --------------------编程问答-------------------- 楼主好人 --------------------编程问答-------------------- 真是个疯子,贴这么多代码。 --------------------编程问答-------------------- 蛋疼的人 --------------------编程问答-------------------- 你上传一张你的设计图,远比贴代码要好。 疯子。 --------------------编程问答--------------------
引用 7 楼 chenliuyang 的回复:
你上传一张你的设计图,远比贴代码要好。 疯子。


第一次分享,感觉重要的代码给列出来,下不为例! --------------------编程问答--------------------
引用 8 楼 gaollg 的回复:
引用 7 楼 chenliuyang 的回复:

你上传一张你的设计图,远比贴代码要好。 疯子。


第一次分享,感觉重要的代码给列出来,下不为例!

贴你的类图就够了,大家都是程序员能看懂UML --------------------编程问答-------------------- 人家不贴代码出来     尼玛你能看懂个锤子!      --------------------编程问答-------------------- 贴出代码是有必要的,因为论坛还有新手 --------------------编程问答-------------------- 所有方法和字段都是静态的,那就先说说静态与实例的区别:
● 线程安全
静态方法是共享代码段,静态变量是共享数据段。既然是“共享”就有并发(Concurrence)的问题。
非静态方法是针对确定的一个对象的,所以不会存在线程安全的问题。
● 生命周期(Lifecycle):
静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭。
非静态方法(Non-Static Method)又叫实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例来引用。不会常驻内存,当实例对象被JVM 回收之后,也跟着消失。
●  总计
如果静态方法在系统中定义太多,会占用大量的资源,最后造成内存溢出,所以静态方法不能滥用。如果从线程安全、性能、兼容性上来看,选用实例化方法为宜。
以上观点是网上找来的,

Class.forName(className);
conn = DriverManager.getConnection(url, user, password);
看得出楼主用的是最原始的jdbc驱动注册,这种方式如果是给几个人用,倒也无妨。如果人多,访问量大,建议使用DataSource



--------------------编程问答-------------------- 看到还有拼接单引号就不用看了。 --------------------编程问答-------------------- Mark之,膜拜楼主...过段时间项目里面需要抽取表结构并根据表结构获取表数据,这个还是有参考价值的 --------------------编程问答-------------------- 建议参考下DBUtils这个玩意,可以丰富你的代码
补充:Java ,  Java EE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,