目录
前言
零、效果
一、目标与总体架构设计
1.1、目标
1.2、核心架构
1.3、框架架构图
1.4、框架实现思路
二、数据库的链接(第一部分)
2.1 第一步:创建项目且根据设计先创建好所需要的核心类,以及需要用到的工具类。
2.2、第二步: 创建 Configuration类,用来保存配置信息。该部分主要是描述如何链接数据库
3.3、第三步: DBManager链接数据库。
3.4、 链接测试
三、读取指定数据库表结构信息(第二部分)
3.1、第一步:创建数据库表的实体对象,以及列对象。
3.2、第二步,查询数据库元信息,并创建Map记录目标库的所有表结构信息。
3.3、第三步,测试是否将所有的元信息导入到本地Map中。
四、一、二部分总结
大家好,我是人见人爱花见花开,一支梨花压海棠,宇宙超级无敌,人称霹雳世纪美少年的小李同学,同时也是一个即将拥有九块腹肌的立志成为一名全栈工程师的程序猿!
好了废话不多说!今天,本博主将带着大家码一遍ORM(Object Relational Mapping)框架的底层实现,并造出自己的第一个小轮子。此次框架将会结合JAVA反射,JAVAIO流,JAVAFile流,以及常见的几种设计模式进行设计!本篇博客仅是博主学习记录博。欢迎各位大佬指点指点!
PS:(六月的上海像一个蒸笼,搞得我像一只大闸蟹,极其焦灼!)
大概像这样
通过数据库表进行反向生成实体映射类。
本次系列我们将编写一款简单的,易用的,可以实现对象和SQL自动映射的框架(反向生成JAVAbean),砍掉不必要的功能。由于本博主,才疏学浅可能有写的不对的地方!也请各位海涵。
- 核心类
- Query接口:负责增删改查的基本功能(对外提供服务的核心类)
- QueryFactory类:负责根据配置信息创建query对象(此处将使用到工厂设计模式)
- TypeConvertor接口:负责将数据库与JAVA基本数据类型的转换
- TableContext类 :负责获取指定数据库中的所有表结构信息,并可以根据表结构生成类结构
- DBManager类:根据配置文件进行数据库的链接管理(后期会增加连接池功能)
2. 工具类
- JDBCUtils:数据库连接工具,封装常用的JDBC操作。
- StringUtils:字符串处理工具,将字符按照目标格式修改,例如驼峰,例如首字母大写。
- JAVAFileUtils:封装常用的io以及file操作。
- ReflectUtils:封装常用的反射操作。
本框架虽说是个迷你型框架但写起来也还是颇费时间,因此,我大概会分三到四篇博客将其实现。
- 第一部分:链接数据库。包括(DBMananger,configration配置类,properties文件)。
- 第二部分:读取指定数据库所有表信息,并使用Map将所有表结构存储到程序中。
- 第三部分:通过读取到的表信息,进行字符串拼接创建出表的映射类对象。
- 第四部分:增删改查的实现。
写的有点烦来张图开心下。
核心代码 PS:由于长度有限,构造函数以及getset方法我就不写了 。且博文后面也不会再进行特殊说明!
public class Configuration { /** * 驱动类 */ private String driver; /** * jdbc的地址 */ private String url; /** * 数据库用户名 */ private String user; /** * 数据库密码 */ private String password; /** * 使用的数据库 Mysql */ private String usingDB; /** * 生成包的地址 */ private String srcPath; /** * */ private String poPackage; }
核心代码:
/** * @ProjectName: SORM * @Package: com.sorm.core * @ClassName: DBManager * @Author: HAND_WEILI * @Description: 根据配置信息,维持链接对象的管理 * @Date: 2020/6/10 12:54 * @Version: 1.0 */ public class DBManager { // 管理全局的配置信息 private static Configuration conf; /** * 静态代码块用来加载链接池的信息。 */ static { // 加载制定的资源文件,或者用xml使用 Properties pros = new Properties(); try { // 当前线程下上下文类加载器调用获取资源方法 pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties")); } catch (IOException e) { e.printStackTrace(); } // 读取配置信息 conf = new Configuration(); conf.setDriver(pros.getProperty("driver")); conf.setUrl(pros.getProperty("url")); conf.setUser(pros.getProperty("user")); conf.setPassword(pros.getProperty("password")); conf.setUsingDB(pros.getProperty("usingDB")); conf.setSrcPath(pros.getProperty("srcPath")); conf.setPoPackage(pros.getProperty("poPackage")); // 维持链接对象 } /** * 通过配置文件类,获取数据库链接。 * @return */ public static Connection getConnection(){ try { Class.forName(conf.getDriver()); //目前直接建立链接,后面提供链接池 return DriverManager.getConnection(conf.getUrl(),conf.getUser(),conf.getPassword()); } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } catch (SQLException e) { e.printStackTrace(); return null; } }
忘记添加了MysqlJAR包...添加后再来测试~
TableInfo类:该类用于存储表结构信息。
public class TableInfo { /** * 表名 */ private String tname; /** * 所有字段的信息 */ private Map
columns; /** * 唯一主键(目前只支持一个主键的情况) */ private ColumnInfo onlyKey; /** * */ private List priKeys; }
ColumnInfo:该类用于存储字段结构信息。
public class ColumnInfo { /** * 字段名称 */ private String name; /** * 字段的数据类型 */ private String dataType; /** * 0,主键,1、普通键 3、外键 */ private int keyType; }
由于 DatabaseMetaData并不是很常用的类,所以我也不打算讲了,大家如果想知道可以参考该篇博文。
DatabaseMetaData基本介绍
public class TableContext {
// 获取数据库的元信息
/**
* 表名为key,表信息对象为value ,这个相当于将所有的表信息都存到了当前的Map中
*/
public static Map tables = new HashMap();
private TableContext() {
}
// 通过静态代码块调用的时候进行加载数据库的表信息
static {
try {
//初始化获得表的信息
Connection con = DBManager.getConnection();
// 获取数据库元信息
DatabaseMetaData dbmd = con.getMetaData();
// dbmd.getTables可以获取表信息,如果不指定 catalong参数则是链接的第一个数据库。后面是表名的筛选。String参数填TABLe代表是所有的表信息。
ResultSet tableRet = dbmd.getTables("testjdbc", "%", "%", new String[]{"TABLE"});
// 通过循环获取单个表的信息。类似于迭代器的循环。
while (tableRet.next()) {
String tableName = (String) tableRet.getObject("TABLE_NAME");
TableInfo ti = new TableInfo(tableName, new ArrayList()
, new HashMap());
tables.put(tableName, ti);
ResultSet set = dbmd.getColumns(null, "%", tableName, "%"); //查询表中的所有字段
while (set.next()) {
ColumnInfo ci = new ColumnInfo(set.getString("COLUMN_NAME"),
set.getString("TYPE_NAME"), 0);
ti.getColumns().put(set.getString("COLUMN_NAME"), ci);
}
ResultSet set2 = dbmd.getPrimaryKeys(null, "%", tableName); //查询t_user表中的主键
while (set2.next()) {
ColumnInfo ci2 = (ColumnInfo) ti.getColumns().get(set2.getObject("COLUMN_NAME"));
ci2.setKeyType(1); //设置为主键类型
ti.getPriKeys().add(ci2);
}
if (ti.getPriKeys().size() > 0) { //取唯一主键。。方便使用。如果是联合主键。则为空!
ti.setOnlyKey(ti.getPriKeys().get(0));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
//更新类结构
// updateJavaPOFile();
//加载po包下面所有的类,便于重用,提高效率!
//loadPOTables();
}
public static void main(String[] args) {
// 测试是否已经读取到所有的表信息
Map tables = TableContext.tables;
System.out.println(tables);
}
}
本篇博客,主要带着小伙伴们链接了数据库,以及读取了目标表的一些元数据。下篇博客将会根据这些元信息,进行一个实体类的映射操作~~
同时,我将自己写的一些源代码发布到了GITHUB上有兴趣的小伙伴可以下下了研究研究。可以重构重构~
git 克隆地址:https://github.com/WeiLi14/SORM.git
我是帅哥威,一个即将拥有九块腹肌的立志成为一名全栈工程师的匠人!写文章,超辛苦的~小伙伴们不给我点点赞?
By the way,最近有些迷茫。不过幸运的是身边有很多好的亲人,朋友,以及同事给予了我帮助。路漫漫其修远兮,吾将上下而求索!希望我的人生可以碌碌而不无为,求一个问心无愧。哦,对了!祝贺豪总找到新工作~
今天就这样,溜了~~~