自己实现简单对象关系库之缓存类SQLField,SQLClass,SQLCache
来源:互联网 发布:软件服务外包方案 编辑:程序博客网 时间:2024/05/01 03:52
上文已经谈到对象关系库需要对操作中间产生的数据进行缓存以提升性能
我们需要对通过反射获取的属性进行缓存
我们需要对属性拼装成的SQL语句进行缓存
综上,我们可以设计出SQLClass作为Class的缓存类保存反射的结果,SQLField作为Field的缓存类保存反射的结果
对于Person类有一个
SQLClass<Person> sqlClass=new SQLClass(Person.class)
作为其缓存类,缓存类中包含Person所有数据库相关的属性值
public class SQLField{ private Field field; private Column column; //省略getter //返回SQLField对应的数据库列名称 public String getName(){ //如果Column额外设置了名字,则返回设置的名字,否则返回field变量的名字 if(column.name().length()>0)return column.name(); return field.getName(); } //遍历类所有的SQLField public static void mapSQLField(Class clazz,SQLConsumer<SQLField> consumer){ if (!clazz.getSuperclass().equals(Object.class)) { mapSQLField(clazz.getSuperclass(), mapper);//先访问父类的属性 } Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); if (field.isAnnotationPresent(Column.class)) { Column column = field.getAnnotation(Column.class); mapper.accept(new SQLField<T>(field, column)); } } }}
public class SQLClass<T>{ private Class<T> clazz; private List<SQLField> fields=new LinkedList<>();//保存此类所有Field缓存 private SQLField primaryKey; private String tableName; private SQLClass(Class<T> clazz){this.clazz=clazz;} public static <T> SQLClass<T> build(Clazz<T> clazz)throws SQLException{ SQLClass<T> sqlClass=new SQLClass(clazz); sqlClass.init(); return sqlClass(); } //初始化缓存类 private void init() throws SQLException{ //获取数据库表名 if(!clazz.isAnnotationPresent(Table.class)) throw new SQLException(clazz+"类没有配置表名"); Table table=clazz.getAnnotation(Table.class); this.tableName=table.value(); //获取数据库对应的所有属性值字段 SQLField.mapSQLField(clazz,sqlField->{ fields.add(sqlField); if(sqlField.getColumn().isPrimaryKey()){ primaryKey=sqlField; } }); if(primaryKey==null)throw new SQLException(clazz+"类没有配置主键"); } private String selectSQL;//查询SQL语句的缓存 private Object selectLock=new Object(); //返回查询的SQL语句 public String selectSQL(){ if(selectSQL==null) synchronized(selectLock){ if(selectSQL==null){ selectSQL=initSelectSQL(); } } } return selectSQL; } //初始化查询的SQL语句 private String initSelectSQL(){ //将每个字段的名字拼接到一起 StringJoiner joiner=new StringJoiner(","); for(SQLField sqlField:fields){ joiner.add(sqlField.getName()); } StringBuilder builder=new StringBuilder(); builder.append("SELECT ") .append(joiner.toString()) .append(" FROM ") .append(tableName) .append(";"); return builder.toString(); } //上面我已经演示了如何获取查询的SQL语句,后面的增加,删除,更改的SQL语句限于篇幅已经省略 //把一行ResultSet转化成一个对象实例 public void toBean(ResultSet rs){ T t=t.newInstance(); for(SQLField sqlField:fields){ sqlField.set(t,rs.get(sqlField.getName()); } return t; }}
现在我们已经知道了如何构建SQLClass作为反射结果和SQL语句的缓存,现在我们还需要一个类作为SQLClass的缓存
public class SQLCache{ //用来缓存SQLClass的容器 private ConcurrentHashMap<Class, SQLClass> map = new ConcurrentHashMap<>(); //获取clazz对应的SQLClass public <T> SQLClass<T> getSQLClass(Class<T> clazz) throws SQLException { SQLClass<T> sqlClass = map.get(clazz); if (sqlClass == null) { SQLClass<T> tempSqlClass = SQLClass.build(clazz); map.putIfAbsent(clazz, tempSqlClass); sqlClass = map.get(clazz); } return sqlClass; }}
既然我们已经了缓存类,我们的简单对象关系库已经实现了大半部分。
接下来我们考虑的如何使用这些缓存类实现对象关系库
0 0
- 自己实现简单对象关系库之缓存类SQLField,SQLClass,SQLCache
- 自己实现简单对象关系库之Database的实现
- 自己实现简单对象关系库之反射和注解
- 自己实现简单对象关系库之更多功能
- 自己动手实现简单对象关系库之概述
- 对象缓存 类实现
- 开发应用程序时候创建数据库处理类SQLClass
- Java 实现简单的内存对象LRU缓存
- 自己动手实现简单对象关系库谈到异常的处理与抛出
- Hibernate,JPA 对象关系映射之简单映射策略
- JPA 对象关系映射之简单映射策略
- 简单的java缓存类实现
- nilcms file类 简单文件缓存实现
- ibatis 对象关系实现
- ibatis 对象关系实现
- ibatis对象关系实现
- ibatis 对象关系实现
- ibatis对象关系实现
- XML--Java中的四种常见解析方式--dom
- 深入理解Java虚拟机笔记
- XML--Java中的四种常见解析方式--jdom与dom4j
- XML--Java中的四种常见解析的区别
- matplotlib绘图进行数据分析
- 自己实现简单对象关系库之缓存类SQLField,SQLClass,SQLCache
- 如何判断两个jq对象是同一个对象
- SpringBoot全局异常处理
- XMLHTTP中setRequestHeader参数问题
- C++中文件的写入与写出
- vrf路由泄露原理和简单示例
- 深入理解JavaScript执行上下文、函数堆栈、提升的概念
- Log4j配置详解
- 项目重构总结 1