sqlobject源码分析

sqlobject是一个orm框架

基本组成

SQLObject:数据类通过继承该类获取orm能力,用户层代码主要基于这个类的api操作数据库

SelectResult:查询结果的抽象,以懒加载的形式处理查询结果

DBConnection:数据库连接的抽象

大致可以分为三层:API层、中间层(构建sql等)、数据库交互层

查询执行过程

以查询18岁的学生为例

class StudentDao(SQLObject):
    class sqlmeta:
        table = 'student'
    name = StringCol()
    age = IntCol()
  1. StudentDao.selectBy(age=18)

  2. 根据查询条件拼接sql

    DBAPI._SO_columnClause

  3. 构造SelectResult实例,作为懒加载的查询结果返回

    初始化过程会对排序、范围查询

  4. 用户代码遍历SelectResult结果获取数据时才会触发向数据库发起查询

    SelectResult.__iter__=>SelectResult.lazyIter
    1. 获取数据库连接

    2. 构造dbconnection.Iteration,该迭代器负责真正的查询数据迭代过程

      执行查询获取cursor,并通过cursor查出一条条记录

    3. 通过dbconnection.Iteration获取所有查询结果,放到list中

    4. 将包含查询结果的list重新包装成一个迭代器,用户代码每遍历一次则从list中获取一条记录

整体来看,SQLObject的查询过程为:

SQLObject=>SelectResult=>DBAPI=>dbconnection.Iteration=>DBAPI._executeRetry

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用Druid实现SQL解析血缘关系的Java代码示例: ``` import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.parser.SQLParserUtils; import com.alibaba.druid.sql.parser.SQLStatementParser; import com.alibaba.druid.stat.TableStat; import com.alibaba.druid.stat.TableStat.Column; import com.alibaba.druid.stat.TableStat.Name; import java.util.*; public class SqlLineageParser { private Map<String, List<String>> tableMap = new HashMap<>(); private Map<String, List<String>> columnMap = new HashMap<>(); public void parseSqlLineage(String sql) { List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, "mysql"); for (SQLStatement stmt : stmtList) { if (stmt instanceof SQLSelectStatement) { SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) selectStmt.getSelect().getQuery(); // 解析表血缘关系 List<SQLTableSource> fromList = queryBlock.getFrom(); for (SQLTableSource tableSource : fromList) { if (tableSource instanceof SQLExprTableSource) { SQLExprTableSource exprTableSource = (SQLExprTableSource) tableSource; String tableName = getTableName(exprTableSource.getExpr()); if (tableName != null) { addTableDependency(tableName); } } else if (tableSource instanceof SQLJoinTableSource) { SQLJoinTableSource joinTableSource = (SQLJoinTableSource) tableSource; SQLTableSource left = joinTableSource.getLeft(); SQLTableSource right = joinTableSource.getRight(); if (left instanceof SQLExprTableSource) { SQLExprTableSource exprTableSource = (SQLExprTableSource) left; String tableName = getTableName(exprTableSource.getExpr()); if (tableName != null) { addTableDependency(tableName); } } if (right instanceof SQLExprTableSource) { SQLExprTableSource exprTableSource = (SQLExprTableSource) right; String tableName = getTableName(exprTableSource.getExpr()); if (tableName != null) { addTableDependency(tableName); } } } } // 解析字段血缘关系 List<SQLSelectItem> selectList = queryBlock.getSelectList(); for (SQLSelectItem selectItem : selectList) { SQLExpr expr = selectItem.getExpr(); if (expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr; String columnName = identifierExpr.getName(); String tableName = getColumnTableName(identifierExpr); if (tableName != null) { addColumnDependency(tableName, columnName); } } } } } } private String getTableName(SQLExpr expr) { if (expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr; return identifierExpr.getName(); } else if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr; SQLExpr owner = propertyExpr.getOwner(); String tableName = getTableName(owner); if (tableName != null) { return tableName + "." + propertyExpr.getName(); } } return null; } private String getColumnTableName(SQLIdentifierExpr identifierExpr) { String columnName = identifierExpr.getName(); Name name = identifierExpr.name(); Map<Name, Column> columns = TableStat.getColumns(); for (Map.Entry<Name, Column> entry : columns.entrySet()) { Column column = entry.getValue(); if (column.getName().equals(columnName)) { Name tableName = entry.getKey().getParent(); return tableName.getName(); } } return null; } private void addTableDependency(String tableName) { if (!tableMap.containsKey(tableName)) { tableMap.put(tableName, new ArrayList<>()); } } private void addColumnDependency(String tableName, String columnName) { if (!columnMap.containsKey(columnName)) { columnMap.put(columnName, new ArrayList<>()); } List<String> tableList = tableMap.get(tableName); if (tableList != null) { for (String table : tableList) { String column = table + "." + columnName; if (!columnMap.containsKey(column)) { columnMap.put(column, new ArrayList<>()); } columnMap.get(column).add(tableName); } } } public Map<String, List<String>> getTableMap() { return tableMap; } public Map<String, List<String>> getColumnMap() { return columnMap; } public static void main(String[] args) { String sql = "select t1.id, t2.name from table1 t1 join table2 t2 on t1.id = t2.id where t1.age > 18"; SqlLineageParser parser = new SqlLineageParser(); parser.parseSqlLineage(sql); System.out.println("Table Map: " + parser.getTableMap()); System.out.println("Column Map: " + parser.getColumnMap()); } } ``` 在以上代码中,我们通过Druid提供的SQL解析工具解析SQL语句,并通过解析结果获取表和字段的元数据信息。通过分析SQL语句中的表和字段引用关系,我们可以构建出表和字段的血缘关系。最后,我们可以通过getTableMap()和getColumnMap()方法获取解析结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值