# beetlsql **Repository Path**: vertx/beetlsql ## Basic Information - **Project Name**: beetlsql - **Description**: 使用beetl 来完成mybatis功能 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 497 - **Created**: 2015-12-25 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Beetlsql * 作者: 闲大赋,Gavin.King,Sue * 开发时间:2015-07 * 论坛 http://ibeetl.com * qq群 219324263 * 当前版本 1.5.0 (120K), 另外还需要beetl 包 # beetlsql 特点 BeetSql是一个全功能DAO工具, 同时具有Hibernate 优点 & Mybatis优点功能,适用于承认以SQL为中心,同时又需求工具能自动能生成大量常用的SQL的应用。 * 无需注解,自动使用大量内置SQL,轻易完成增删改查功能,节省50%的开发工作量 * 数据模型支持Pojo,也支持Map/List这种快速模型,也支持混合模型 * SQL 以更简洁的方式,Markdown方式集中管理,同时方便程序开发和数据库SQL调试。 * SQL 模板基于Beetl实现,更容易写和调试,以及扩展 * 简单支持关系映射而不引入复杂的OR Mapping概念和技术。 * 具备Interceptor功能,可以调试,性能诊断SQL,以及扩展其他功能 * 首个内置支持主从数据库支持的开源工具,通过扩展,可以支持更复杂的分库分表逻辑 * 支持跨数据库平台,开发者所需工作减少到最小 * 可以针对单个表代码生成pojo类和sql模版,甚至是整个数据库。能减少代码编写工作量 # 5 分钟例子 ## 准备工作 为了快速尝试BeetlSQL,需要准备一个Mysql数据库,然后执行如下sql脚本 CREATE TABLE `user` ( `id` int(11) NOT NULL, `name` varchar(64) DEFAULT NULL, `age` int(4) DEFAULT NULL, `userName` varchar(64) DEFAULT NULL COMMENT '用户名称', `roleId` int(11) DEFAULT NULL COMMENT '用户角色', PRIMARY KEY (`id`), KEY `user_age_index` (`age`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 编写一个Pojo类,与数据库表对应(或者可以通过beetlsql生成此类,参考一下节) public class user { private Integer roleId ; private String name ; private Integer id ; private String userName ; private Integer age ; // getter,setter方法 忽略 } ## 代码例子 写一个java的Main方法,内容如下 // 创建一个简单的ConnectionSource,只有一个master ConnectionSource source = ConnectionSourceHelper.simple(driver,url,userName,password); // 采用mysql 习俗 DBStyle mysql = new MysqlStyle(); // sql语句放在classpagth的/sql 目录下 SQLLoader loader = new ClasspathLoader("/sql"); // 数据库命名跟java命名一样,所以采用DefaultNameConversion NameConversion nc = new DefaultNameConversion(); // 最后,创建一个SQLManager,DebugInterceptor 不是必须的,但可以通过它查看sql执行情况 SqlManager sqlManager = new SqlManager(source,mysql,loader,nc,new Interceptor[]{new DebugInterceptor()}); //使用内置的生成的sql 新增用户 User user = new User(); user.setAge(19); user.setName("xiandafu"); sqlManager.insert(user); //使用内置sql查询用户 int id = 1; user = sqlManager.unique(User.class,id); //使用user.md 文件里的select语句,参考下一节。实际上,此处可以用template 方法而不需要写sql,下面三行代码仅仅是演示如何操作sql模板语句 User query = new User(); query.setName("xiandafu"); List list = sqlManager.select("user.select",User.class,query) ## SQL例子 为了能执行user.select,需要在classpath里建立一个sql目录(ClasspathLoader 配置成sql目录,参考上一节ClasspathLoader初始化的代码)以及下面的user.md 文件,内容如下 select === select * from user where 1=1 @if(!isEmpty(age)){ and age = #age# @} @if(!isEmpty(name)){ and name = #name# @} 关于如何写sql模板,会稍后章节说明,如下是一些简单说明。 * 采用md格式,===上面是sql语句在本文件里的唯一标示,下面则是sql语句。 * @ 和回车符号是定界符号,可以在里面写beetl语句。 * "#" 是站位符号,生成sql语句得时候,将输出?,如果你想输出表达式值,需要用text函数,或者任何以db开头的函数,引擎则认为是直接输出文本。 * isEmpty是beetl的一个函数,用来判断变量是否为空或者是否不存在. sql模板采用beetl原因是因为beetl 语法类似js,且对模板渲染做了特定优化,相比于mybatis,更加容易掌握和功能强大,可读性更好,也容易在java和数据库之间迁移sql语句 ## 代码&sql生成 User类并非需要自己写,好的实践是可以在项目中专门写个类用来辅助生成pojo和sql片段,代码如下 public static void main(String[] args){ SqlManager sqlManager = ...... sqlManager.genPojoCodeToConsole("user"); sqlManager.genSQLTemplateToConsole("user"); } genPojoCodeToConsole 方法可以根据数据库表生成相应的Pojo代码,输出到控制台,开发者可以根据这些代码创建相应的类,如上例子,控制台将输出 package com.test; import java.math.*; import java.sql.*; /* * * gen by beetsql 2015-12-21 */ public class user { //用户角色 private Integer roleId ; private String name ; private Integer id ; //用户名称 private String userName ; private Integer age ; } 上述生成的代码有些瑕疵,比如包名总是com.test,类名是小写开头(因为用了DefaultNameConversion),你需要修改成你要的包名和正常的类名,pojo类也没有生成getter,setter方法,你需要用ide自带的工具再次生成一下。 一旦有了User 类,如果你需要些sql语句,那么genSQLTemplateToConsole 将是个很好的辅助方法,可以输出一系列sql语句片段,你同样可以赋值粘贴到代码或者sql模板文件里(user.md),如上例所述,当调用genSQLTemplateToConsole的时候,生成如下 sample === * 注释 select #use("cols")# from user where #use("condition")# cols === roleId,name,id,userName,age updateSample === `roleId`=#roleId#,`name`=#name#,`id`=#id#,`userName`=#userName#,`age`=#age# condition === 1 = 1 @if(!isEmpty(roleId)){ and `roleId`=#roleId# @} @if(!isEmpty(name)){ and `name`=#name# @} 省略其他条件 beetlsql生成了用于查询,更新,条件的sql片段和一个简单例子。你可以按照你的需要copy到sql模板文件里.实际上,如果你熟悉gen方法,你可以直接gen代码和sql到你的工程里,甚至是整个数据库都可以调用genAll来一次生成 # BeetlSQL 说明 ## 获得SQLManager SQLManager 是系统的核心,他提供了所有的dao方法。获得SQLManager,可以直接构造SQLManager.并通过过单例获取如: ConnectionSource source = ConnectionSourceHelper.simple(driver,url,userName,password); // 采用mysql 习俗 DBStyle mysql = new MysqlStyle(); // sql语句放在classpagth的/sql 目录下 SQLLoader loader = new ClasspathLoader("/sql"); // 数据库命名跟java命名采用驼峰转化 NameConversion nc = new DefaultNameConversion(); // 最后,创建一个SQLManager SqlManager sqlManager = new SQLManager(mysql,loader,source,nc, new Interceptor[]{new DebugInterceptor()}); 更常见的是,已经有了DataSource,创建ConnectionSource 可以采用如下代码 ConnectionSource source = ConnectionSourceHelper.single(datasource); 如果是主从Datasource ConnectionSource source = ConnectionSourceHelper.getMasterSlave(master,slaves) ### Spring集成 * cs: 指定ConnectionSource,可以用系统提供的DefaultConnectionSource,支持按照CRUD决定主从。例子里只有一个master库 * dbStyle: 数据库类型,目前只支持org.beetl.sql.core.db.MySqlStyle,以及OralceSytle,PostgresStyle,SQLiteStyle * sqlLoader: sql语句加载来源 * nc: 命名转化,有默认的DefaultNameConversion,数据库跟类名一致,还有有数据库下划线的UnderlinedNameConversion。 * interceptors:DebugInterceptor 用来打印sql语句,参数和执行时间 注意: 任何使用了Transactional 注解的,将统一使用Master数据源,例外的是@Transactional(readOnly=true),这将让Beetsql选择从数据库。 public class MyServiceImpl implements MyService { @Autowired SpringBeetlSql beetlsql ; @Override @Transactional() public int total(User user) { SQLManager dao = beetlsql.getSQLMananger(); List list = dao.all(User.class); int total = list .size(); dao.deleteById(User.class, 3); User u =new User(); u.id = 3; u.name="hello"; u.age = 12; dao.insert(User.class, u); return total; } } 可以参考demo https://git.oschina.net/xiandafu/springbeetlsql ### JFinal集成 在configPlugin 里配置BeetlSql JFinalBeetlSql.init(); 默认会采用c3p0 作为数据源,其配置来源于jfinal 配置,如果你自己提供数据源或者主从,可以如下 JFinalBeetlSql.init(master,slaves); 由于使用了Beetlsql,因此你无需再配置 **数据库连接池插件,和ActiveRecordPlugin**,可以删除相关配置。 在controller里,可以通过JFinalBeetlSql.dao 方法获取到SQLManager SQLManager dao = JFinalBeetlSql.dao(); BigBlog blog = getModel(BigBlog.class); dao.insert(BigBlog.class, blog); 如果想控制事物,还需要注册Trans public void configInterceptor(Interceptors me) { me.addGlobalActionInterceptor(new Trans()); } 然后业务方法使用 @Before(Trans.class) public void doXXX(){....+ 这样,方法执行完毕才会提交事物,任何RuntimeException将回滚,如果想手工控制回滚.也可以通过 Trans.commit() Trans.rollback() 如果习惯了JFinal Record模式,建议用户创建一个BaseBean,封装SQLManager CRUD 方法即可。然后其他模型继承此BaseBean 可以参考demo https://git.oschina.net/xiandafu/jfinal_beet_beetsql_btjson ## SQLManager API ### 查询API **模板类查询(自动生成sql)** * public List all(Class clazz) 查询出所有结果集 * public List all(Class clazz, int start, int size) 翻页 * public int allCount(Class clazz) 总数 * public List template(T t) 根据模板查询,返回所有符合这个模板的数据库 * public List template(T t,RowMapper mapper) 同上,mapper可以提供额外的映射,如处理一对多,一对一 * public List template(T t,int start,int size) 同上,可以翻页 * public List template(T t,RowMapper mapper,int start,int size) 翻页,并增加额外的映射 * public long templateCount(T t) 获取符合条件的个数 翻页的start,系统默认位从1开始,为了兼容各个数据库系统,会自动翻译成数据库习俗,比如start为1,会认为mysql,postgres从0开始(从start-1开始),oralce从1开始(start-0)开始。 然而,如果你只用特定数据库,可以按照特定数据库习俗来,比如,你只用mysql,start为0代表起始纪录,需要配置 OFFSET_START_ZERO = true 这样,翻页参数start传入0即可。 注意:根据模板查询并不包含时间字段 **通过sqlid查询**,sql语句在md文件里 * public List select(String sqlId, Class clazz, Map paras) 根据sqlid来查询,参数是个map * public List select(String sqlId, Class clazz, Object paras) 根据sqlid来查询,参数是个pojo * public List select(String sqlId, Class clazz, Map paras, int start, int size), 增加翻页 * public List select(String sqlId, Class clazz, Object paras, int start, int size) ,增加翻页 * public T selectSingle(String id,Object paras, Class target) 根据sqlid查询,将对应的唯一值映射成指定的taget对象,RowMapper mapper 也随着这些api提供,不在此列出了 * public T selectSingle(String id,Map paras, Class target) 同上,参数是map * public Integer intValue(String id,Object paras) 查询结果映射成Integer,输入是objct * public Integer intValue(String id,Map paras) 查询结果映射成Integer,输入是map,其他还有 longValue,bigDecimalValue ### 更新API **自动生成sql** * public void insert(Class clazz,Object paras) 插入paras到paras关联的表 * public void insert(Class clazz,Object paras,KeyHolder holder),插入paras到paras关联的表,如果需要主键,可以通过holder的getKey来获取 * public int updateById(Object obj) 根据主键更新,主键通过annotation表示,如果没有,则认为属性id是主键,所有值参与更新 * public int updateTemplateById(Object obj) 根据主键更新,组件通过annotation表示,如果没有,则认为属性id是主键,属性为null的不会更新 * public int updateTemplateById(Class clazz,Map paras) 根据主键更新,组件通过clazz的annotation表示,如果没有,则认为属性id是主键,属性为null的不会更新。 * public int[] updateByIdBatch(List list) 批量更新 **通过sqlid更新** * public int update(String sqlId, Object obj) 根据sqlid更新 * public int update(String sqlId, Map paras) 根据sqlid更新,输出参数是map * public int[] updateBatch(String sqlId,List list) 批量更新 * public int[] updateBatch(String sqlId,Map[] maps) 批量更新,参数是个数组,元素类型是map ### 直接执行SQL **直接执行sql模板语句** * public List execute(String sql,Class clazz, Object paras) * public List execute(String sql,Class clazz, Map paras) * public int executeUpdate(String sql,Object paras) 返回成功执行条数 * public int executeUpdate(String sql,Map paras) 返回成功执行条数 **直接执行JDBC sql语句** * public List execute(SQLReady p,Class clazz) SQLReady包含了需要执行的sql语句和参数,clazz是查询结果,如 sqlManager.execute(new SQLReady("select * from user where name=? and age = ?","xiandafu",18),User.class);) * public int executeUpdate(SQLReady p) SQLReady包含了需要执行的sql语句和参数,返回更新结果 * ### 其他 **强制使用主或者从** * public void useMaster(DBRunner f) DBRunner里的beetlsql调用将使用主数据库库 * public void useSlave(DBRunner f) DBRunner里的beetlsql调用将使用从数据库库 **生成Pojo代码和SQ片段** * genPojoCodeToConsole(String table), 根据表名生成pojo类,输出到控制台. * genSQLTemplateToConsole(String table),生成查询,条件,更新sql模板,输出到控制台。 * genPojoCode(String table,String pkg,String srcPath,GenConfig config) 根据表名,包名,生成路径,还有配置,生成pojo代码 * genPojoCode(String table,String pkg,GenConfig config) 同上,生成路径自动是项目src路径,或者src/main/java (如果是maven工程) * genPojoCode(String table,String pkg),同上,采用默认的生成配置 * genSQLFile(String table), 同上,但输出到工程,成为一个sql模版,sql模版文件的位置在src目录下,或者src/main/resources(如果是maven)工程. * genALL(String pkg,GenConfig config,GenFilter filter) 生成所有的pojo代码和sql模版,**必须当心覆盖你掉你原来写好的类和方法** sql.genAll("com.test", new GenConfig(), new GenFilter(){ public boolean accept(String tableName){ if(tableName.equalsIgnoreCase("user")){ return true; }else{ return false; } } }); 第一个参数是pojo类包名,GenConfig是生成pojo的配置,GenFilter 是过滤,返回true的才会生成。如果GenFilter为null,则数据库所有表都要生成 ## BeetlSQL Annotation 对于自动生成的sql,默认不需要任何annotaton,类名对应于表名(通过NameConverstion类),getter方法的属性名对应于列明(也是通过NameConverstion类),但有些情况还是需要anntation。 * 标签@Table(name="xxxx") 告诉beetlsql,此类对应xxxx表。比如数据库有User表,User类对应于User表,也可以创建一个UserQuery对象,也对应于User表 @Table(name="user") public class QueryUser .. * @AutoID,作用于getter方法,告诉beetlsql,这是自增主键 * @AssignID,作用于getter方法,告诉beetlsql,这是主键,且由代码设定主键 * @SeqID(name="xx_seq",作用于getter方法,告诉beetlsql,这是序列主键。 对于属性名为id的自增主键,不需要加annotation,beetlsql默认就是@AutoID (注,如果想要获取自增主键或者序列主键,需要在SQLManager.insert中传入一个KeyHolder) ## BeetlSQL 数据模型 BeetlSQL是一个全功能DAO工具,支持的模型也很全面,包括 * Pojo, 也就是面向对象Java Objec。Beetlsql操作将选取Pojoe属性和sql列的交集。额外属性和额外列将忽略t * Map/List, 对于一些敏捷开发,可以直接使用Map/List 作为输入输出参数 * 混合模型,推荐使用混合模型。兼具灵活性和更好的维护性。Pojo可以实现Tail(尾巴的意思),或者继承TailBean,这样查询出的ResultSet 除了按照pojo进行映射外,无法映射的值将按照列表/值保存。如下一个混合模型: /*混合模型*/ public User extends TailBean{ private int id ; pirvate String name; private int roleId; /*以下是getter和setter 方法*/ } 对于sql语句: selectUser === select u.*,r.name r_name from user u left join role r on u.roleId=r.id ..... 执行查询的时候 List list = sqlManager.select("user.selectUser",User.class,paras); for(User user:list){ System.out.println(user.getId()); System.out.println(user.get("rName")); } 程序可以通过get方法获取到未被映射到pojo的值,也可以在模板里直接 ${user.rName} 显示(对于大多数模板引擎都支持) ## Markdown方式管理 --- BeetlSQL集中管理SQL语句,SQL 可以按照业务逻辑放到一个文件里,文件名的扩展名是md或者sql。如User对象放到user.md 或者 user.sql里,文件可以按照模块逻辑放到一个目录下。文件格式抛弃了XML格式,采用了Markdown,原因是 * XML格式过于复杂,书写不方便 * XML 格式有保留符号,写SQL的时候也不方便,如常用的< 符号 必须转义 * MD 格式本身就是一个文档格式,也容易通过浏览器阅读和维护 目前SQL文件格式非常简单,仅仅是sqlId 和sql语句本身,如下 文件一些说明,放在头部可有可无,如果有说明,可以是任意文字 SQL标示 === 以*开头的注释 SQL语句 SQL标示2 === SQL语句 2 所有SQL文件建议放到一个sql目录,sql目录有多个子目录,表示数据库类型,这是公共SQL语句放到sql目录下,特定数据库的sql语句放到各自自目录下 当程序获取SQL语句得时候,先会根据数据库找特定数据库下的sql语句,如果未找到,会寻找sql下的。如下代码 List list = sqlManager.select("user.select",User.class); SqlManager 会根据当前使用的数据库,先找sql/mysql/user.md 文件,确认是否有select语句,如果没有,则会寻找sql/user.md (注:默认的ClasspathLoader采用了这种方法,你可以实现SQLLoader来实现自己的格式和sql存储方式,如数据库存储) 注释是以* 开头,注释语句不作为sql语句 ## SQL 注释 对于采用Markdown方式,可以采用多种方式对sql注释。 * 采用sql 自己的注释符号,"-- " ,优点是适合java和数据库sql之间互相迁移,如 select * from user where -- status 代表状态 statu = 1 * 采用beetl注释 select * from user where @ /* 这些sql语句被注释掉 statu = 1 @ */ * 在sqlId 的=== 紧挨着的下一行 后面连续使用“*”作为sql整个语句注释 selectByUser == * 这个sql语句用来查询用户的 * status =1 表示查找有效用户 select * from user where status = 1 ## 开发模式和产品模式 beetlsql默认是开发模式,因此修改md的sql文件,不需要重启。但建议线上不要使用开发模式,因为此模式会每次sql调用都会检测md文件是否变化。可以通过修改/btsql-ext.properties ,修改如下属性改为产品模式 PRODUCT_MODE = true ## SQL 模板基于Beetl实现,更容易写和调试,以及扩展 SQL语句可以动态生成,基于Beetl语言,这是因为 * beetl执行效率高效 ,因此对于基于模板的动态sql语句,采用beetl非常合适 * beetl 语法简单易用,可以通过半猜半式的方式实现,杜绝myBatis这样难懂难记得语法。BeetlSql学习曲线几乎没有 * 利用beetl可以定制定界符号,完全可以将sql模板定界符好定义为数据库sql注释符号,这样容易在数据库中测试,如下也是sql模板(定义定界符为"--" 和 "null",null是回车意思); selectByCond === select * form user where 1=1 --if(age!=null) age=#age# --} * beetl 错误提示非常友好,减少写SQL脚本编写维护时间 * beetl 能容易与本地类交互(直接访问Java类),能执行一些具体的业务逻辑 ,也可以直接在sql模板中写入模型常量,即使sql重构,也会提前解析报错 * beetl语句易于扩展,提供各种函数,比如分表逻辑函数,跨数据库的公共函数等 如果不了解beetl,可先自己尝试按照js语法来写sql模板,如果还有疑问,可以查阅官网 http://ibeetl.com ## Beetl 入门 Beetl 语法类似js,java,如下做简要说明,使用可以参考 http://ibeetl.com,或者在线体验 http://ibeetl.com:8080/beetlonline/ ### 定界符号 默认的定界符号是@ 和 回车。 里面可以放控制语句,表达式等语,,站位符号是##,站位符号默认是输出?,并在执行sql的传入对应的值。如果想在占位符号输出变量值,则需要使用text函数 @if(isEmpty(name)){ and name = #name# } 如果想修改定界符,可以增加一个/btsql-ext.properties. 设置如下属性 DELIMITER_PLACEHOLDER_START=# DELIMITER_PLACEHOLDER_END=# DELIMITER_STATEMENT_START=@ DELIMITER_STATEMENT_END= beetlsql 的其他属性也可以在此文件里设置 ### 变量 通过程序传入的变量叫全局变量,可以在sql模板里使用,也可以定义变量,如 @var count = 3; @var status = {"a":1} //json变量 ### 算数表达式 同js,如a+1-b%30, i++ 等 select * from user where name like #'%'+name+'%'# ### 逻辑表达式 有“&&” “||” ,还有 “!”,分别表示与,或,非, beetl也支持三元表达式 #user.gender=1?'女':'男'## ### 控制语句 * if else 这个同java,c,js。 * for,循环语句,如for(id:ids){} select * from user where status in ( @for(id in ids){ #id# #idLP.isLast?"":","# @} 注意:变量名+LP 是一个内置变量,包含了循环状态,具体请参考beetl文档 * while 循环语句 ,如while(i paras; private boolean isUpdate = false ; private Object result ; private Map env = null; } ## 内置支持主从数据库 BeetlSql管理数据源,如果只提供一个数据源,则认为读写均操作此数据源,如果提供多个,则默认第一个为写库,其他为读库。用户在开发代码的时候,无需关心操作的是哪个数据库,因为调用sqlScrip 的 select相关api的时候,总是去读取从库,add/update/delete 的时候,总是读取主库。 sqlManager.insert(User.class,user) // 操作主库,如果只配置了一个数据源,则无所谓主从 sqlManager.unique(id,User.class) //读取从库 主从库的逻辑是由ConnectionSource来决定的,如下DefaultConnectionSource 的逻辑 @Override public Connection getConn(String sqlId,boolean isUpdate,String sql,List paras){ if(this.slaves==null||this.slaves.length==0) return this.getWriteConn(sqlId,sql,paras); if(isUpdate) return this.getWriteConn(sqlId,sql,paras); int status = forceStatus.get(); if(status ==0||status==1){ return this.getReadConn(sqlId, sql, paras); }else{ return this.getWriteConn(sqlId,sql,paras); } } * forceStatus 可以强制SQLManager 使用主或者从数据库。参考api SQLManager.useMaster(DBRunner f) ,SQLManager.useSlave(DBRunner f) 对于于不同的ConnectionSource 完成逻辑不一样,对于spring,jfinal这样的框架,如果sqlManager在事务环境里,总是操作主数据库,如果是只读事务环境 则操作从数据库。如果没有事务环境,则根据sql是查询还是更新来决定。 如下是SpringConnectionSource 提供的主从逻辑 public Connection getConn(String sqlId,boolean isUpdate,String sql,List paras){ //只有一个数据源 if(this.slaves==null||this.slaves.length==0) return this.getWriteConn(sqlId,sql,paras); //如果是更新语句,也得走master if(isUpdate) return this.getWriteConn(sqlId,sql,paras); //如果api强制使用 int status = forceStatus.get(); if(status==1){ return this.getReadConn(sqlId, sql, paras); }else if(status ==2){ return this.getWriteConn(sqlId,sql,paras); } //在事物里都用master,除了readonly事物 boolean inTrans = TransactionSynchronizationManager.isActualTransactionActive(); if(inTrans){ boolean isReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); if(!isReadOnly){ return this.getWriteConn(sqlId,sql,paras); } } return this.getReadConn(sqlId, sql, paras); } 注意,对于使用者来说,无需关心本节说的内容,仅仅供要定制主从逻辑的架构师。 ## 可以支持更复杂的分库分表逻辑 开发者也可以通过在Sql 模板里完成分表逻辑而对使用者透明,如下sql语句 insert into #text("log_"+ getMonth(date())# values () ... 注:text函数直接输出表达式到sql语句,而不是输出?。 log表示按照一定规则分表,table可以根据输入的时间去确定是哪个表 select * from #text("log"+log.date)# where 注:text函数直接输出表达式到sql语句,而不是输出?。 同样,根据输入条件决定去哪个表,或者查询所有表 @ var tables = getLogTables(); @ for(table in tables){ select * from #text(table)# @ if(!tableLP.isLast) print("union"); @} where name = #name# ##跨数据库平台 如前所述,BeetlSql 可以通过sql文件的管理和搜索来支持跨数据库开发,如前所述,先搜索特定数据库,然后再查找common。另外BeetlSql也提供了一些夸数据库解决方案 * DbStyle 描述了数据库特性,注入insert语句,翻页语句都通过其子类完成,用户无需操心 * 提供一些默认的函数扩展,代替各个数据库的函数,如时间和时间操作函数date等 * MySqlStyle mysql 数据库支持 * OracleStyle oralce支持 * PostgresStyle postgres数据库支持 ## 代码生成 beetsql支持调用SQLManager.gen... 方法生成表对应的pojo类,如: SQLManager sqlManager = new SQLManager(style,loader,cs,new DefaultNameConversion(), new Interceptor[]{new DebugInterceptor()}); //sql.genPojoCodeToConsole("userRole"); 快速生成,显示到控制台 // 或者直接生成java文件 GenConfig config = new GenConfig(); config.preferBigDecimal(true); config.setBaseClass("com.test.User"); sqlManager.genPojoCode("UserRole","com.test",config); config 类用来配置生成喜爱,目前支持生成pojo是否继承某个基类, 是否用BigDecimal代替Double,是否是直接输出到控制台而不是文件等 生成的代码如下: package com.test; import java.math.*; import java.sql.*; public class UserRole extends com.test.User{ private Integer id; /* 数据库注释 */ private String userName; } 也可以自己设定输出模版,通过GenConfig.initTemplate(String classPath),指定模版文件在classpath 的路径,或者直接设置一个字符串模版 GenConfig.initStringTemplate. 系统默认的模版如下: package ${package}; ${imports} /* * ${comment} * gen by beetsql ${date(),"yyyy-MM-dd"} */ public class ${className} ${!isEmpty(ext)?"extends "+ext} { @for(attr in attrs){ @ if(!isEmpty(attr.comment)){ //${attr.comment} @ } private ${attr.type} ${attr.name} ; @} } ##直接使用SQLResult 有时候,也许你只需要SQL及其参数列表,然后传给你自己的dao工具类,这时候你需要SQLResult,它包含了你需要的sql,和sql参数。 SQLManager 有如下方法,你需要传入sqlid,和参数即可 public SQLResult getSQLResult(String id, Map paras) paras 是一个map,如果你只有一个pojo作为参数,你可以使用“_root” 作为key,这样sql模版找不到名称对应的属性值的时候,会寻找_root 对象,如果存在,则取其同名属性。 SQLResult 如下: public class SQLResult { public String jdbcSql; public List jdbcPara; } jdbcSql是渲染过后的sql,jdbcPara 是对应的参数值 ## 开发人员帅照 ###闲大赋 ![xiandfu](http://ibeetl.com/guide/xiandafu.jpg) ###Gavin·King ![Gavin](http://ibeetl.com/guide/GV2.png) ### Sue ![Sue](http://ibeetl.com/guide/SUE.jpg)