这几天都在学习springJPA对单表的操作,感觉非常方便,只用实现基本的接口就能对所有的类增、删、查、改进行操作基本不用写任何的代码,这样是不是能简化项目的开发时间,运用反射和泛型可以实现基于jdbc的BaseDao抽象类,实现增、删、查、改。只用继承这个类就能实现对所有的类进行操作了。
首先我们要先连接数据库:
public class DBHelper {
private static String dbUrl="jdbc:mysql://localhost:3306/sushe";
private static String dbUser="root";
private static String dbPassword="123456";
private static String jdbcName="com.mysql.jdbc.Driver";
/**
* DBHelper的单例
*/
private static DBHelper instance = null;
private DBHelper() {}
/**
* 获取DBHelper的单例
* @return
*/
public static DBHelper getInstance() {
if (instance == null) {
synchronized (DBHelper.class) {
if (instance == null) {
instance = new DBHelper();
}
}
}
return instance;
}
static {
try {
//加载数据库驱动
Class.forName(jdbcName);
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
public Connection getConnection() throws SQLException {
//获取数据库连接
return DriverManager.getConnection(dbUrl, dbUser, dbPassword);
}
/**
* 释放资源
* @param rs
* @param st
* @param conn
*/
public void free(ResultSet rs, Statement st, Connection conn) {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (st != null)
st.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws SQLException {
}
}
由于要使用fastjson 把从数据库中查询的数据解析成对象所以我们需要一个工具类实现数据解析。
/**
* 工具类解析ResultSet
* @author xiaoyu_pc
*/
public class GetType {
@SuppressWarnings("unused")
public void getType(ResultSet rs, ResultSetMetaData rsmd, JSONObject obj)
throws SQLException {
int total_rows = rsmd.getColumnCount();
for (int i = 0; i < total_rows; i++) {
String columnName = rsmd.getColumnLabel(i + 1);
// if (obj.has(columnName)) {
// columnName += "1";
// }
try {
switch (rsmd.getColumnType(i + 1)) {
case java.sql.Types.ARRAY:
obj.put(columnName, !StringUtils.isEmpty(rs.getArray(columnName))?rs.getArray(columnName):"");
break;
case java.sql.Types.BIGINT:
obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
break;
case java.sql.Types.BOOLEAN:
obj.put(columnName, !StringUtils.isEmpty(rs.getBoolean(columnName))?rs.getBoolean(columnName):"");
break;
case java.sql.Types.BLOB:
obj.put(columnName, !StringUtils.isEmpty(rs.getBlob(columnName))?rs.getBlob(columnName):"");
break;
case java.sql.Types.DOUBLE:
obj.put(columnName, !StringUtils.isEmpty(rs.getDouble(columnName))?rs.getDouble(columnName):"");
break;
case java.sql.Types.FLOAT:
obj.put(columnName, !StringUtils.isEmpty(rs.getFloat(columnName))?rs.getFloat(columnName):"");
break;
case java.sql.Types.INTEGER:
obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
break;
case java.sql.Types.NVARCHAR:
obj.put(columnName, !StringUtils.isEmpty(rs.getNString(columnName))?rs.getNString(columnName):"");
break;
case java.sql.Types.VARCHAR:
obj.put(columnName, !StringUtils.isEmpty(rs.getString(columnName))?rs.getString(columnName):"");
break;
case java.sql.Types.TINYINT:
obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
break;
case java.sql.Types.SMALLINT:
obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
break;
case java.sql.Types.DATE:
obj.put(columnName, !StringUtils.isEmpty(rs.getDate(columnName))?rs.getDate(columnName):"");
break;
case java.sql.Types.TIMESTAMP:
obj.put(columnName, !StringUtils.isEmpty(rs.getTimestamp(columnName))?rs.getTimestamp(columnName):"");
break;
default:
obj.put(columnName, !StringUtils.isEmpty(rs.getObject(columnName))?rs.getObject(columnName):"");
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
然后我们来实现BaseDao的实现由于代码太多我只介绍实现新增和查询方法:
@Component
@Repository
public abstract class BaseDao<T>{
public Class entityclass;
public BaseDao (Class entityclass){
this.entityclass = entityclass;
}
/**
* 新增
* @param entityclass
* @return
* @throws NoSuchMethodException
* @throws Exception
* 目前只支持Interger 和 String 类型的字段
*/
public boolean add(Object entityclass) throws NoSuchMethodException, Exception {
Statement stat = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
DBHelper instance = DBHelper.getInstance();
Connection conn = instance.getConnection();
// Connection conn = new DBHelper().getConn();
try {
String values = "";
//获取传入的实体类的类名
String className = entityclass.getClass().getSimpleName();
Field[] declaredFields = entityclass.getClass().getDeclaredFields();
for(int j=0;jif(!declaredFields[j].getName().equals("serialVersionUID")){
if(j != declaredFields.length-1){
//自动拼接sql
values += "?"+",";
}else{
values += "?";
}
}
}
//原型是 insert into "+className+" values(?,?,?,?....)
String sql = "insert into "+className+" values("+values+")" ;
//执行sql语句
pstmt = (PreparedStatement) conn.prepareStatement(sql);
for(int i=0;iif(i > 0){
//如果类型是Integer
if (declaredFields[i].getGenericType().toString().equals("class java.lang.Integer")) {
Method m = (Method) entityclass.getClass().getMethod(
"get" + getMethodName(declaredFields[i].getName()));
Integer val = (Integer) m.invoke(entityclass);
pstmt.setString(i,(val != null?Integer.toString(val):null));
}
//如果类型是String
if (declaredFields[i].getGenericType().toString().equals("class java.lang.String")) {
Method m = entityclass.getClass().getMethod("get"+ getMethodName(declaredFields[i].getName()));
String parmeter = (String) m.invoke(entityclass);
pstmt.setString(i,!StringUtils.isEmpty(parmeter)?parmeter:null);
}
}
}
int issuccess = pstmt.executeUpdate();
return issuccess > 0? true : false;
} catch (SQLException e) {
e.printStackTrace();
}finally{
instance.free(rs, stat, conn);
}
return false;
}
/**
* 查询所有
* @param strwhere
* @param strorder
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
* @throws SQLException
*/
@SuppressWarnings("unchecked")
public List findByAll(String strwhere,String strorder) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
try {
String className = entityclass.getSimpleName();
String sql="select * from "+className+"";
if(!StringUtils.isEmpty(strwhere))
{
sql+=" where "+strwhere;
}
if(!StringUtils.isEmpty(strorder))
{
sql+=" order by "+strorder;
}
Statement stat = null;
ResultSet rs = null;
DBHelper instance = DBHelper.getInstance();
Connection conn = instance.getConnection();
// Connection conn = new DBHelper().getConn();
List list= new ArrayList();
try{
GetType getType = new GetType();
stat = conn.createStatement();
rs = stat.executeQuery(sql);
JSONArray array = new JSONArray();
while(rs.next()){
JSONObject obj = new JSONObject();
ResultSetMetaData metaData = rs.getMetaData();
//传result和JsonObject
getType.getType(rs, metaData, obj);
array.add(obj); //把jsonobject添加到jsonArray中
}
Class> clazz = Class.forName(entityclass.getCanonicalName());
list = (List) JSON.parseArray(array.toJSONString(),clazz);
System.out.println(""+list);
} catch (SQLException e) {
e.printStackTrace();
} finally {
instance.free(rs, stat, conn);
}
return list;
} catch (SecurityException e1) {
e1.printStackTrace();
}
return null;
}
/**
* 把头字母是小写替换成大写
* @param fildeName
* @return
* @throws Exception
*/
private static String getMethodName(String fildeName) throws Exception{
char[] charArray = fildeName.toCharArray();
int asiiValue=(int) charArray[0];
if(asiiValue >=97 && asiiValue<=122){
byte[] items = fildeName.getBytes();
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}else{
return fildeName;
}
}
}
然后我们需要的是继承这个实体类
用户登录接口AdminService
@Repository
public interface AdminService {
/**
* 用户管理接口
* 如果要添加新的方法
* 比如: Admin findByName(String name);
*/
}
用户登录类 AdminServiceImpl
@Component
@Service
public class AdminServiceImpl extends BaseDao<Admin> implements AdminService {
public AdminServiceImpl(Class<Admin> entityclass) {
super(entityclass);
}
}
我们需要一个Controller来测试这个类是否能用:
@Controller
public class AdminController {
private AdminServiceImpl adminserviceimpl = new AdminServiceImpl(Admin.class);
@ResponseBody
@RequestMapping(value="/findAll")
public List findAll() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
List list;
try {
list = adminserviceimpl.findByAll(null,null);
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@ResponseBody
@RequestMapping(value="/add")
public boolean add() throws NoSuchMethodException, Exception{
Admin admin = new Admin();
admin.setAdmin_ID(5);
admin.setAdmin_Name("张三");
admin.setAdmin_Username("zhangsan");
admin.setAdmin_Password("123");
admin.setAdmin_Tel("");
admin.setAdmin_Sex("");
boolean isSuccess = adminserviceimpl.add(admin);
System.out.println(isSuccess);
return true;
}