提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文主要是记录一下以前搭建底层数据库的思路,错误难免,还请海涵。
底层数据库的原理思路即是sql语句的拼接,主要用到的几个技术为自定义注解、反射机制、泛型。
这里简单介绍一下这三种机制:
泛型即“参数化类型”,发生在定义阶段,当你执行代码时一定是确定了类型。
参数化类型:就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式,泛型只在编译阶段有效。
反射:
不知道具体类的属性和方法时,通过获取类的Class<?>对象来获取该对象所定义的属性和方法。
自定义注解:
其本质是一种能通过程序来获取到具体信息的注释。
一、项目的基本架构
这里是基于springBoot,故而项目架构主要分为最基础的自定义注解包,工具类,sql语句拼接工具类等。
二、自定义注解
主要的是表注解和列注解,简单代码如下
表注解:
@Target(ElementType.TYPE) //注解在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Table {
String prefix() default "" ; //表名前缀
String tableName(); //表名
String suffix() default "";//表名后缀
String pks() default ""; //主键
}
列注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
String name();
boolean autoIncrease() default false;
boolean primaryKey() default false;
}
其余还有一些用于表字段的特殊注解如id,持久化的可以自主的加上。
三、sql构造器
主要是进行sql语句的拼接完成最底层的SQL语句。
这里是利用了泛型,反射等知识。
几个主要成员变量为
/**
* where条件集合
*/
private List<String> criteria = null;
/**
* 字段集合
*/
protected Map<String, String> columnMapping = new HashMap<String, String>();
/**
* 实体类属性集合
*/
protected Map<String, String> propertyMapping = new HashMap<String, String>();
主要的几个关键方法:
动态初始化字段:
private void initColumns(){
Field[] allFields = getAllFields(this.cls);
for (Field field:allFields
) {
Column annotation = field.getAnnotation(Column.class);
if (null != annotation) {
String columnName = annotation.name();
String propertyName = field.getName();
columnMapping.put(columnName, propertyName);
propertyMapping.put(propertyName, columnName);
}
Id idAnnotation = field.getAnnotation(Id.class);
if (null != idAnnotation) {
setIdName(field.getName());
}
}
}
设置参数:
/**
* 设置参数
* @param obj
* @return
* @author phx
*/
@Override
public SqlBuilder addParams(Object obj) {
Class<?> objClass= obj.getClass();
Field[] allFields = getAllFields(cls);
for (Field field: allFields
) {
String name = field.getName();
String strGet = "get" + name.substring(0, 1).toUpperCase() + name.substring(1, name.length());
Method methodGet;
try {
//调用get方法
methodGet = objClass.getDeclaredMethod(strGet);
Object object = methodGet.invoke(obj);
String colName = getColumnNameByPropertyName(name);
if (!colName.equals(name)) {
params.put(name, object);
}
params.put(colName, object);
} catch (Exception e) {
e.printStackTrace();
}
}
return this;
}
其余的查询方法类似,用反射机制动态拼接sql语句。
四、sql语句执行器
这里用的是jdbcTemplate 或者 NamedParameterJdbcTemplate
需要在springboot的配置文件中配置对应的datasource
通过ApplicationContextAware来获取spring容器中的datasource。并创建对应的jdbcTemplate对象来执行底层sql语句。
当然,如果只用最基础的basedao的话,不太方便,可以再包一层新的接口来为前后端的交互提供便利。