1024创新实验室-卓大
别点我 (●'◡'●)
卓大主页
文章列表
SmartDb
开源项目
关于我
博客源码
卓大
关注产业互联网,供应链软件,CTO,网络货运,技术顾问,教育培训,开源技术
公众号:1024创新实验室
公众号:六边形工程师
微信号:zhuoda1024
邮箱:zhuoluodada@qq.com
毕业于:山东大学 SDU.CS
地点:洛阳 (偶尔北京 / 郑州)
职位:技术总监 / CTO
管理:敏捷开发 / OKR
后端:Java, Linux, BD, BC
前端:JS, TS, Nodejs
一、初识和创建SmartDb
发表于 2020-04-25 19:33:50
|
分类于
SmartDb
SmartDb
|
smartdb
orm
java
前言:
简介SmartDb理念和思想,以及对SmartDb的主要几个类的分析,如何创建smartdb对象(预计阅读1分钟)
### 1 安装 如果是maven项目可以直接添加依赖如下 ```
net.1024lab
smartdb
1.2.0
``` ------------ ### 2 创建SmartDb对象 #### 2.1 SmartDb的创建依赖于 数据源 SmartDb的使用建议依赖于数据源DataSource(当然不使用数据源也是可以的,但是每次操作db都去创建昂贵的connection是件很奢侈的事情)具体实现可以为druid,hikaricp,c3p0等等,所以 : ##### 官方建议: 在使用SmartDb的时候优先使用数据源,比如DruidDataSource, C3p0DataSource,HikariDataSource等等 #### 2.2 使用SmartDbBuilder类和 数据源 创建SmartDb 创建一个Mysql的SmartDb的代码如下: ```java SmartDb smartDb = SmartDbBuilder.create() //设置 写库 数据源 (必要) .setMasterDataSource(writeDruidDataSource) //设置 两个读库 数据源(非必要) .setSlaveDataSource(readDruidDataSource1,readDruidDataSource2) // 打印 info 级别sql .setShowSql(true) //设置数据库类型(必要) .setSupportDatabaseType(SupportDatabaseType.MYSQL) //设置支持spring (非必要,如果使用SmartDb作为Spring的默认ORM框架需要配置,如果不是默认ORM,一定不要配置) .setSmartDbExtEnum(SmartDbExtEnum.SPRING5) //表名与类名转换,将Class类名转为 数据库表 名字,假设数据库表名以 t_ 开头,小写下划线分隔,eg: t_order_item .setTableNameConverter(cls -> "t_" + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, cls.getSimpleName())) //列名字 转换 ,eg: 将 列名login_time 转为javabean字段 loginTime(必要) .setColumnNameConverter(new CaseFormatColumnNameConverter(CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_UNDERSCORE)) //添加 Sql执行时间 Filter拦截器 (非必要) .addSmartDbFilter(new SqlExecutorTimeFilter()) .build(); ``` 具体方法解释: - SmartDbBuilder.setMasterDataSource 方法表示 设置 主数据库,只能为一个; - SmartDbBuilder.setSlaveDataSource 方法表示 设置 多个从数据库,可以为 0 到 N 个。0表示没有从库 - SmartDbBuilder.setTableNameConverter 方法表示 将Class类名转为 数据库表 名字,假设数据库表名以 t_ 开头,小写下划线分隔,eg: `t_order_item`, 类名 `OrderItem` - SmartDbBuilder.setColumnNameConverter 方法表示 数据库表 列名 与 Class的 属性名的 转换,这里推荐使用 guava的 CaseFormat进行配置,内部提供 `CaseFormatColumnNameConverter`类支持 - addSmartDbFilter 方法表示 添加过滤器Filter,所有的Filter必须实现SmartDbFilter接口 #### 2.3 使用SmartDbBuilder类和 jdbc参数 创建SmartDb(极不推荐) ```java SmartDb smartDb = SmartDbBuilder.create() .setUrl("jdbc:mysql://127.0.0.1:3306/smartdb?useSSL=false&allowPublicKeyRetrieval=true") .setDriverClassName("com.mysql.jdbc.Driver") .setUsername("root") .setPassword("root") // 打印 info 级别sql .setShowSql(true) //设置数据库类型 .setSupportDatabaseType(SupportDatabaseType.MYSQL) //设置支持spring .setSmartDbExtEnum(SmartDbExtEnum.SPRING5) //表名与类名转换,将Class类名转为 数据库表 名字,假设数据库表名以 t_ 开头,小写下划线分隔,eg: t_order_item .setTableNameConverter(cls -> "t_" + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, cls.getSimpleName())) //列名字 转换 .setColumnNameConverter(new CaseFormatColumnNameConverter(CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_UNDERSCORE)) //添加 Sql执行时间 Filter拦截器 .addSmartDbFilter(new SqlExecutorTimeFilter()) .build(); ``` **极其不推荐以上方式来创建SmartDb,因为没有使用 连接池,每次操作都需要创建和关闭连接 是一个非常非常浪费和奢侈的事情。** ------------ ### 3 SmartDb类的用途和思想 SmartDb是为了更方便操作数据库,方便的支持读写分离,所以一个SmartDb对象表示着 **一个数据库集群** !!! >你没有看错,SmartDb的一个对象表示一个集群,集群里至少有 一个写库、大于等于0的读库。 SmartDb中含有多个SmartDbNode对象,源码如下: ``` class SmartDbImpl implements SmartDb { // 随机获取slave库的索引 private AtomicInteger roundIndex = new AtomicInteger(-1); // 主库 ( 写 库 ) private SmartDbNode master; // 从库 ( 读 库 ) private List
slaves; // smartdb 配置信息 private SmartDbConfig smartDbConfig; // 是否存在 从库( 读 库 ) private boolean existSlave; ``` 因为SmartDb表示一个集群,所以默认有如下操作 : - **对数据库进行 update, delete, insert, replace等 修改的操作都是 默认操作 !写 !库**。 - **对数据库进行 select查询的操作都是 默认操作 !读 !库**。 #### 3.1 默认对 **写** 库进行操作 所有的修改数据库操作都是在写(主)库上进行的,如下 ``` smartDb.execute("update t_user set pwd = '123' where id = 1"); smartDb.insertSqlBuilder()... smartDb.updateSqlBuilder()... smartDb.deleteSqlBuilder()... smartDb.replaceSqlBuilder()... ``` 原理:源码如下, 可以清晰得看到,execute(增删改)调用的是master,即主库(写库)。 ``` @Override public int execute(String sql) { return this.master.execute(sql); } @Override public int execute(DeleteSqlBuilder deleteSqlBuilder) { return this.master.execute(deleteSqlBuilder); } ``` #### 3.2 是默认对 **读** 库进行操作 所有的查询都是在读库进行的,而且是轮询查询读库 ``` smartDb.queryList("selecct * from t_user",User.class); ``` 原理:每次query的时候都先调用```getSmartDbNode4Query()```方法,轮询获取读库(从库)。 ``` public
T queryFirst(Class
cls, SelectSqlBuilder selectSqlBuilder) { return this.getSmartDbNode4Query().queryFirst(cls, selectSqlBuilder); } public SmartDbNode getSmartDbNode4Query() { if (this.existSlave) { int round = this.roundIndex.incrementAndGet(); return this.slaves.get(Math.abs(round % this.slaves.size())); } else { return this.master; } } ``` ##### 如果想从写库 读取数据该怎么办呢?? 直接调用getMaster()即可,是不是很方便呢~ ```java List
userVOList = smartDb.getMaster().queryList("select * from t_user", User.class); ``` **切记:默认查询操作都是从读库操作的!!,当然如果没有从库,则所有操作都是在主库上进行操作的 !** ### 3 SmartDb类的介绍 SmartDb为最顶层的类,是一个接口,负责所有的入口操作,也是最最核心、使用频率最高的一个类,所有的操作都是以SmartDb以开始的,这样设计对使用者也是最方便的。 因为SmartDb为最顶层的接口,拥有所有操作数据库的方法,比如 增删查改、读写分离、ORM、等等。具体方法有: >| 方法名 | 方法作用 | | ------------ | ------------ | | execute | 执行Sql | | batch / batchInsert / batchInsertSelective | 批量操作 | | query | 查询 | | paginate | 分页查询 | | getTransaction | 获取带事务的SmartDb | | getMaster | 获取 写 数据库 | | getSlaves | 获取 所有的 从(读) 数据库 | | getSlave | 获取 某个指定的 从(读) 数据库 | | runTransaction | 执行一个事务操作 | | getRowConverter | 表中的行数据转换器 | | selectSqlBuilder | 获取一个select查询语句构器 | | insertSqlBuilder | 获取一个插入insert语句构造器 | | updateSqlBuilder | 获取一个更新update语句的构造器 | | deleteSqlBuilder | 获取一个删除delete语句的构造器 | | insert / insertSelective | ORM插入对象 | | update / updateSelective | ORM更新一个对象 | | delete | 根据ORM对象的 primary 删除对象 | | 其他需要自己查看 | -- | > 代码示例: ```java //构建SmartDb对象 SmartDb smartDb = build(); //以下所有的操作都是以SmartDb对象为开始 // ---------- ORM操作 ---------- //插入 smartDb.insert(userEntity); smartDb.insertSelective(userEntity); // 非空字段插入 smartDb.batchInsert(userList);//批量插入 // 更新 smartDb.update(userEntity); smartDb.updateSelective(userEntity); // 非空字段更新 // 删除 smartDb.delete(userEntity);//根据主键删除 // ---------- sql操作 ---------- smartDb.execute("update t_user set status = 1"); smartDb.queryList("select * from t_user ", UserVO.class); // ---------- SmartDb 读写分离操作 ---------- //获取写库 SmartDb writeSmartDb = smartDb.getWriteSmartDb(); //将数据写入主库 writeSmartDb.insert(userEntity); //进行主库其他操作 writeSmartDb.delete(userEntity); writeSmartDb.updateSelective(userEntity); // ---------- SmartDb UpdateSqlBuilder举例 ---------- smartDb.updateSqlBuilder() .table("t_user") .updateColumn("name = ?","smart") .updateColumn(" login_time = now()") .whereAnd("id = 1") .execute(); //等等其他各类都是以SmartDb对象开始的 ``` 看了以上操作,有没有发现SmartDb操作起来还是非常简单的。
阅读 (4131)
喜欢 (
1
)
评论 (2)
走起吐槽