java map 持久化_重温Java持久化(一)持久化

09年和朋友,写了个仿SSH的框架例子,将其三块代码集成(仿structs、仿spring、仿hibernate),并做了个小网站(JSTL+JSP+(仿)SSH),采取这个框架,感觉挺好用的。

主要目的是为了提高对框架的认识,故没有真正的SSH复杂,意在道明其因由,个人认为,对于企业项目开发能够理解框架原理即可。

因仿hibernate的这块代码非本人所写的,不免的有点点遗憾,前些日子无聊,又看到另个朋友采用注解写了个小框架(针对android系统的),也想采用注解写个试试。

经过几天的折腾,也总算是出炉了。时间仓租,应该会有不少瑕疵,以后有时间,慢慢优化咯。

优点:

1. 以对象方式操作数据库,使用简单方便.

2. 所依赖的jar包少,仅需要数据库驱动的jar.

3. 以上两个优点,对于业务不复杂的小型系统来说,蛮方便的.

DMIS-JHibernate关键代码

DMIS-JHibernate.jar  DMIS-JHibernate_src.zip见附件

=====================================

先来看下注解的含义,见注释

/*

* 元注解@Target,@Retention,@Documented,@Inherited

*

* @Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:

*         ElemenetType.CONSTRUCTOR 构造器声明

*         ElemenetType.FIELD 域声明(包括 enum 实例)

*         ElemenetType.LOCAL_VARIABLE 局部变量声明

*         ElemenetType.METHOD 方法声明

*         ElemenetType.PACKAGE 包声明

*         ElemenetType.PARAMETER 参数声明

*         ElemenetType.TYPE 类,接口(包括注解类型)或enum声明

*

* @Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:

*         RetentionPolicy.SOURCE 注解将被编译器丢弃

*         RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃

*         RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

*

* @Documented 将此注解包含在 javadoc 中

*

* @Inherited 允许子类继承父类中的注解

*

* @author ypf

*/

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public @interface Table {

/**

* 表名

*

* @return

*/

public abstract String name();

}

=====================================

/**

* 注解表 标识是否为主键

* @author ypf

*/

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public abstract @interface Id {

}

=====================================

/**

* 注解表 标识所映射的数据库字段

*

* @author ypf

*/

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public abstract @interface Column {

/**

* 列名

* @return String

*/

public abstract String name();

/**

* 类型

* @return String

*/

public abstract String type() default "";

/**

* 类型

* @return int

*/

public abstract int length() default 0;

}

=====================================

/**

* 数据库辅助类

* @author ypf

*/

public class DBHelper {

Logger logger = Logger.getLogger(DBHelper.class.getName());

private String driver;

private String url;

private String dbname;

private String dbpass;

public DBHelper(String driver, String url, String dbname, String dbpass) {

super();

this.driver = driver;

this.url = url;

this.dbname = dbname;

this.dbpass = dbpass;

}

public Connection getConn() throws ClassNotFoundException, SQLException {

Class.forName(driver);

Connection conn = DriverManager.getConnection(url, dbname, dbpass);

return conn;

}

/**

* 释放资源

*

* @param conn-连接对象

* @param pstmt-预编译

* @param rs-结果集

*/

public void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {

if (rs != null) {

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (ps != null) {

try {

ps.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (conn != null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

/**

* 执行增、删、改

* @param sql-语句

* @param params-数组型参数

* @return int 受影响的行数

* @throws SQLException

* @throws ClassNotFoundException

*/

public int executeUpdate(String sql, Object... params) throws SQLException, ClassNotFoundException {

Connection connection = null;

PreparedStatement ps = null;

int num = 0;

// 处理SQL,执行SQL

try {

connection = getConn(); // 得到数据库连接

ps = connection.prepareStatement(sql); // 预处理SQL语句

buildPreparedStatement(ps, params);

logger.info("Oper: " + sql);

num = ps.executeUpdate(); // 执行SQL语句

}catch (SQLException e) {

throw e;

}catch (ClassNotFoundException e) {

throw e;

}finally {

closeAll(connection, ps, null);

}

return num;

}

/**

* 为PreparedStatement对象填充参数

* @param ps 预编译句子

* @param param 动态参数

* @throws SQLException

*/

public void buildPreparedStatement(PreparedStatement ps, Object... params) throws SQLException {

// 设置参数

for (int i = 0; i < params.length; i++) {

// 将Date转换成java.sql.Date

if (params[i] instanceof Date) {

Date d = (Date) params[i];

ps.setObject(i + 1, new Timestamp(d.getTime()));

} else {

ps.setObject(i + 1, params[i]);

}

}

}

/**

* 执行查询操作

* @param sql sql语句

* @param param 动态参数

* @return RowSet 结果集,可直接使用

*/

public RowSet executeQuery(String sql, Object... params) throws SQLException, ClassNotFoundException {

Connection connection = null;

PreparedStatement ps = null;

ResultSet rs = null;

RowSet rowset = null;

try {

connection = this.getConn();

ps = connection.prepareStatement(sql);

buildPreparedStatement(ps, params);

logger.info("Oper: " + sql);

rs = ps.executeQuery();

rowset = populate(rs);

} catch (SQLException e) {

throw e;

} catch (ClassNotFoundException e) {

throw e;

} finally {

closeAll(connection, ps, rs);

}

return rowset;

}

/**

* 将ResultSet转换为RowSet对象

* @param rs 数据集

* @return RowSet

*/

public RowSet populate(ResultSet rs) throws SQLException {

CachedRowSetImpl crs = new CachedRowSetImpl();

crs.populate(rs);

return crs;

}

/**

* 从RowSet中获取列头

* @param rs 数据集

* @return List

*/

public List getRowSetColName(RowSet rs) throws SQLException {

ArrayList collist = new ArrayList();

for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {

collist.add(rs.getMetaData().getColumnName(i + 1).toUpperCase());

}

return collist;

}

}

=====================================

/**

* 用于创建表的辅助类

*

* @author ypf

*/

public class TableHelper {

private Logger log = Logger.getLogger(TableHelper.class.getName());

private Session session;

public TableHelper(Session session) {

this.session = session;

}

/**

* 创建表

* @param

* @param clazz

*/

public void createTable(Class clazz) {

String tableName = "";

if (clazz.isAnnotationPresent(Table.class)) {

Table table = (Table) clazz.getAnnotation(Table.class);

tableName = table.name();

} else {

return;

}

StringBuilder sb = new StringBuilder();

// 用来判断表是否存在,如果存在则不执行改操作

sb.append("CREATE TABLE ").append(tableName).append(" (");

List allFields = ClassUtil.joinFields(clazz);

for (Field field : allFields) {

if (!field.isAnnotationPresent(Column.class)) {

continue;

}

Column column = (Column) field.getAnnotation(Column.class);

String columnType = "";

// 判断column的type字段是否为空,如果为空则根据字段的值将其转换为对应的数据库类型

if (column.type().equals(""))

columnType = getColumnType(field.getType());

else {

columnType = getColumnType(column.type());

}

sb.append(column.name() + " " + columnType);

if (column.length() != 0) {

sb.append("(" + column.length() + ")");

}

// 添加主键

if (field.isAnnotationPresent(Id.class)) {

sb.append(" PRIMARY KEY");

}

sb.append(", ");

}

sb.delete(sb.length() - 2, sb.length() - 1);

sb.append(")");

String sql = sb.toString();

String checkSql = "SELECT 1 FROM USER_TABLES WHERE TABLE_NAME=?";

String dropSql = "DROP TABLE " + tableName.toUpperCase();

try {

RowSet rs = session.executeQuery(checkSql, tableName.toUpperCase());

// 如果存在则先删除

if (rs.next()) {

log.info("表[" + tableName.toUpperCase() + "]已经存在!");

// session.executeUpdate(dropSql);

// session.executeUpdate(sql);

} else {

session.executeUpdate(sql);

log.info("表[" + tableName.toUpperCase() + "]创建成功!");

}

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

//根据字段类型返回数据库对应的列,以后需要扩展优化,一遍支持多中数据库,目前只支持oracle

private String getColumnType(Class> fieldType) {

if (String.class == fieldType) {

return "VARCHAR";

}

if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {

return "NUMBER";

}

if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {

return "LONG";

}

if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {

return "NUMBER";

}

if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {

return "NUMBER";

}

if (Blob.class == fieldType) {

return "BLOB";

}

if (Date.class == fieldType) {

return "DATE";

}

return "VARCHAR";

}

/**

* 根据传入的类型返回对应的数据库字段类型 如果找不到匹配的则直接用其本身作为数据库列类型(type不允许为空)

* 备注:这里以后会扩展(根据不用的数据库创建不用的字段)

* @param type

* @return String

*/

private String getColumnType(String type) {

if (ColumnType.INTEGER.equals(type)) {

return "NUMBER";

}

if (ColumnType.STRING.equals(type)) {

return "VARCHAR";

}

if (ColumnType.LONG.equals(type)) {

return "LONG";

}

return type;

}

}

=====================================

/**

* 对外公开的数据库访问类

*

* @author ypf

*/

public interface Session {

/**

* 类加载

*/

public abstract void loadContext(ClassLoad c);

/**

* 添加

*/

public abstract Serializable insert(Object entity) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException, Exception;

/**

* 删除

*/

public abstract Serializable delete(Object entity) throws SQLException, ClassNotFoundException;

/**

* 修改

*/

public abstract Serializable update(Object entity) throws SQLException, ClassNotFoundException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException;

/**

* 根据id获取对象

*/

public abstract Object getResource(Serializable id, Class clazz) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException;

/**

* 查询所有

*/

public abstract List query(Class clazz) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException;

/**

* 封装执行sql代码.

*/

public int executeUpdate(String sql, Object... params) throws SQLException, ClassNotFoundException;

/**

* 通过sql语句,进行查询操作

* @param sql sql预警

* @param params 参数

* @return RowSet

*/

public RowSet executeQuery(String sql, Object... params) throws SQLException, ClassNotFoundException;

/**

* 通过sql语句,进行增、删、改操作

* @param sql sql预警

* @param params 参数

* @return RowSet

*/

public Object executeQueryUnique(String sql, Object... params) throws SQLException, ClassNotFoundException;

//未完待续...

}

=====================================

/**

* 提供CRUD操作的实现类

* @author ypf

*/

public class SessionImpl implements Session {

private Logger log = Logger.getLogger(SessionImpl.class.getName());

DBHelper dbHelper; // 数据库访问类

Class clazz; // 当前处理对象

String tableName; // 表明

List allFields; // 所有字段

String keyName; // 主键

public void loadContext(ClassLoad c) {

c.execute();

}

/**

* 构建列信息,如:name,type

* @return String

*/

private String buildStrColumn() {

String step = "";

for (int i = 0; i < allFields.size(); i++) {

Column column = (Column) allFields.get(i).getAnnotation(Column.class);

step += column.name() + ",";

}

if (step.length() > 0)

step = step.substring(0, step.length() - 1);

}else {

step = "*";

}

return step;

}

/**

* 构建参数信息,如:?,?

* @return String

*/

private String buildValColumn() {

String step = "";

for (int i = 0; i < allFields.size(); i++) {

step += "?,";

}

if (step.length() > 0)

step = step.substring(0, step.length() - 1);

return step;

}

/**

* 初始化

*

* @param clazz

*/

private void initProperites(Class clazz) {

this.clazz = clazz;

if (this.clazz.isAnnotationPresent(Table.class)) {

Table table = (Table) clazz.getAnnotation(Table.class);

this.tableName = table.name();

}

this.allFields = ClassUtil.joinFields(clazz);

for (Field field : allFields) {

if (!field.isAnnotationPresent(Column.class)) {

continue;

}

Column column = (Column) field.getAnnotation(Column.class);

if (field.isAnnotationPresent(Id.class)) {

this.keyName = field.getName();

}

}

log.info("clazz:" + this.clazz + " tableName:" + this.tableName + " keyName:" + this.keyName);

}

public SessionImpl(DBHelper dbHelper) {

this.dbHelper = dbHelper;

}

@Override

public Serializable delete(Object entity) throws SQLException, ClassNotFoundException {

initProperites(entity.getClass());

Object keyValue = ClassUtil.getPropertie(entity, keyName);

String sql = "delete from {0} where {1}=?".replace("{0}", this.tableName).replace("{1}", keyName);

log.info("[delete]:" + sql);

log.info("[params]:" + keyValue);

return dbHelper.executeUpdate(sql, keyValue);

}

@Override

public Object getResource(Serializable id, Class clazz) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {

initProperites(clazz);

String cols = buildStrColumn();

String sql = ClassUtil.formartString("SELECT {0} FROM {1} where {2}=?", new String[] { cols, this.tableName, this.keyName });

log.info("[get]:" + sql);

log.info("[params]:" + id);

RowSet rs = dbHelper.executeQuery(sql, id);

List list = ClassUtil.buildEntities(rs, clazz, allFields);

if (list.size() > 0)

return list.get(0);

return null;

}

// 插入

@Override

public Serializable insert(Object entity) throws Exception {

initProperites(entity.getClass());

String cols = buildStrColumn();// 要查询的字段

String vs = buildValColumn();// 预编译参数

String sql = ClassUtil.formartString("insert into {0}({1}) values({2})", new String[] { this.tableName, cols, vs });

Object[] params = ClassUtil.buildParams(entity, allFields);

return dbHelper.executeUpdate(sql, params);

}

@Override

public Serializable update(Object entity) throws SQLException, ClassNotFoundException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {

initProperites(entity.getClass());

String cols = buildStrColumn();

String vs = buildValColumn();

String _cols = (cols + ",").replace(",", "=?,");

_cols = _cols.length() > 0 ? _cols.substring(0, _cols.length() - 1) : "*";

Object[] params = ClassUtil.buildParams(entity, allFields);

Object vKey = ClassUtil.buildParams(entity, keyName);

Object[] _params = new Object[params.length + 1];

for (int i = 0; i < params.length; i++) {

_params[i] = params[i];

}

_params[params.length] = vKey.toString();

String sql = ClassUtil.formartString("update {0} set {1} where {2}=? ", new String[] { this.tableName, _cols, this.keyName });

return dbHelper.executeUpdate(sql, _params);

}

@Override

public List query(Class clazz) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {

initProperites(clazz);

String cols = buildStrColumn();

String sql = ClassUtil.formartString("SELECT {0} FROM {1}", new String[] { cols, this.tableName });

RowSet rs = dbHelper.executeQuery(sql);

List list = ClassUtil.buildEntities(rs, clazz, allFields);

return list;

}

@Override

public int executeUpdate(String sql, Object... params) throws SQLException, ClassNotFoundException {

return dbHelper.executeUpdate(sql, params);

}

@Override

public RowSet executeQuery(String sql, Object... params) throws SQLException, ClassNotFoundException {

return dbHelper.executeQuery(sql, params);

}

@Override

public Object executeQueryUnique(String sql, Object... params) throws SQLException, ClassNotFoundException {

RowSet rs = dbHelper.executeQuery(sql, params);

if (rs.next())

return rs.getObject(1);

return null;

}

}

=====================================

/**

* 辅助类

* @author ypf

*/

public class ClassUtil {

/**

* 合并Field数组并去重,并实现过滤掉非Column字段,和实现Id放在首字段位置功能

* @param clazz

* @return 所以字段

*/

public static List joinFields(Class clazz) {

List cList = new ArrayList();

List fList = new ArrayList();

// 获取所有类

findAllClass(clazz, cList);

// 获取所有字段

for (Class c : cList) {

for (int i = 0; i < c.getDeclaredFields().length; i++) {

fList.add(c.getDeclaredFields()[i]);

}

}

Map map = new LinkedHashMap();

for (Field field : fList) {

// 过滤掉非Column定义的字段

if (!field.isAnnotationPresent(Column.class)) {

continue;

}

Column column = (Column) field.getAnnotation(Column.class);

map.put(column.name(), field);

}

List list = new ArrayList();

for (String key : map.keySet()) {

Field step = map.get(key);

// 如果是Id则放在首位置.

if (step.isAnnotationPresent(Id.class)) {

list.add(0, step);

} else {

list.add(step);

}

}

return list;

}

/**

* 查找所有类:自身及所有的父类(接口除外)

*

* @param clazz

* @param list

*/

private static void findAllClass(Class> clazz, List list) {

// 添加自身Class

if (list.size() == 0)

list.add(clazz);

Class> c = clazz.getSuperclass();

if (c != null) {

list.add(c);

findAllClass(c, list);

}

}

/**

* 创建类及封装属性

* @param clazz

* @param fileds

* @param values

* @return size

*/

public static Object buildProperties(Class clazz, List fileds, List values) throws InstantiationException, IllegalAccessException {

if (values.size() != fileds.size())

throw new RuntimeException("fileds的size和values的size不一致!");

Object obj = clazz.newInstance();

for (int i = 0; i < fileds.size(); i++) {

buildPropertie(obj, fileds.get(i), values.get(i));

}

return obj;

}

/**

* 给对象的某个字段封装数值

*/

public static void buildPropertie(Object obj, Field f, Object value) {

try {

String methodName = buildSetMethod(f.getName());

// 给某个字段封装数值,methodName方法名,obj.getClass().getMethod(buildGetMethod(f.getName())).getReturnType()返回类型

// invoke执行方法,obj要赋值的对象,value要赋的值

obj.getClass().getMethod(methodName, obj.getClass().getMethod(buildGetMethod(f.getName())).getReturnType()).invoke(obj, value);

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 构建get方法

* @param fieldName

* @return String

*/

public static String buildGetMethod(String fieldName) {

String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

return methodName;

}

/**

* 构建set方法

* @param fieldName

* @return String

*/

public static String buildSetMethod(String fieldName) {

String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

return methodName;

}

/**

* 根据字段名或对象对应的get方法值

* @param obj 对象

* @param fieldName字段名

* @return Object

*/

public static Object getPropertie(Object obj, String fieldName) {

Object val = "";

try {

String methodName = buildGetMethod(fieldName);

val = obj.getClass().getMethod(methodName).invoke(obj);

} catch (Exception e) {

e.printStackTrace();

}

return val;

}

/**

* 根据字段获取对应的值

* @param entity

* @param allFields

* @return Object[]

*/

public static Object[] buildParams(Object entity, List fields) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {

Object[] params = new Object[fields.size()];// 字段参数值

for (int i = 0; i < fields.size(); i++) {

Field f = fields.get(i);

String methodName = ClassUtil.buildGetMethod(f.getName());

Object v = entity.getClass().getMethod(methodName).invoke(entity);

if (v instanceof Enum) {

v = ((Enum) v).ordinal();

}

params[i] = v;

}

return params;

}

public static Object buildParams(Object entity, Field field) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {

String methodName = ClassUtil.buildGetMethod(field.getName());

Object v = entity.getClass().getMethod(methodName).invoke(entity);

return v;

}

public static Object buildParams(Object entity, String fieldName) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {

String methodName = ClassUtil.buildGetMethod(fieldName);

Object v = entity.getClass().getMethod(methodName).invoke(entity);

return v;

}

/**

* 格式化

* @param str

* @param params

* @return String

*/

public static String formartString(String str, Object... params) {

for (int i = 0; i < params.length; i++) {

Object obj = params[i];

if (obj != null)

str = str.replace("{" + i + "}", obj.toString());

}

return str;

}

public static List buildEntities(RowSet rs, Class clazz, List allFields) throws SQLException, InstantiationException, IllegalAccessException {

List listCols = getRowSetColName(rs);

List list = new ArrayList();

while (rs.next()) {

List values = new ArrayList();

for (String key : listCols) {

values.add(rs.getObject(key));

}

Object obj = ClassUtil.buildProperties(clazz, allFields, values);

list.add(obj);

}

return list;

}

public static List getRowSetColName(RowSet rs) throws SQLException {

List collist = new ArrayList();

for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {

collist.add(rs.getMetaData().getColumnName(i + 1).toUpperCase());

}

return collist;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值