官网地址:http://ibeetl.com/guide/#beetlsql
Beetlsql是一个orm框架,个人在自己的项目中有应用到,这个框架的优点就是md文件编写sql,如果用mybatis的xml文件,有很多时候不是很直观,下面列个本人实际应用中的例子:
findAll
===
select @pageTag(){
r.*, t.name typeName
@}
from product r join product_type t on(r.type_id=t.id)
where shop_id=#shopId#
@if(!isEmpty(name)){
and r.name like #name#
@}
@if(typeId!=null && typeId > 0) {
and r.type_id = #typeId#
@}
@pageIgnoreTag(){
order by regtime desc
@}
上面的例子的意思是:查询product表,关联分类表,并且分页,并且只检索某个店家的。
如果有传入name属性(商品名称),则按商品名称模糊检索,如果分类id不为空,只检索一个
分类下的所有商品,其中的order by regtime desc要加一个 pageIgnoretag
(2.8版本以后也提供了标签函数 pageIgnoreTag,可以用在翻页查询里,当查询用作统计总数的时候,会忽略标签体内容)
本人会使用这个框架的很大一部分原因是,md文件相比xml文件简洁,而且该框架的源码不是太复杂,比较容易掌握,源码地址:http://git.oschina.net/xiandafu/beetlsql/
下面我们来接着看些框架中一些有用的特性,比如@Columnignore标签,如果你要修改一个商品信息,一般来说,商品所属的店家id是不会变更的,因此你可以这么子写,这样子,在执行SqlManager.update(id),其中sqlmanager是beetlsql的数据库操作对象,会直接忽略掉shopId属性,这个特性可以直接查看一下官网文档中7.3章节
@ColumnIgnore(insert = false, update = true)
public Integer getShopId() {
return shopId;
}
框架的另外一个特性,自动在sqlManager(数据库操作对象)就已经提供了insert,update,delete方法,自动生成insert,update,delete等语句,并且框架还提供了一个org.beetl.sql.core.mapper.BaseMapper对象,关于basemapper你可以自行查询源码看下提供了哪些方法(源码上对每个模板方法都做了一些说明),不过个人一般只建议使用BaseMapper的insert,update,delete,insertReturnKey(插入并返回主键)
方法,有关查询的方法(偶尔可以用用BaseMapper的all()方法)全部自己写(一般查询我们都是会写在mybatis的xml文件,至于如果是beetlsql,则写在md文件里面)
下面我们再来看看它里面的分页查询(常用)要怎么写。
//继承baseMapper的话,就可以自动生成insert等方法了。
public interface ProductMapper extends BaseMapper<Product>
//一般建议这么写,返回void,有关 //org.beetl.sql.core.engine.PageQuery可以查看相关源码的一些属
//性说明和文档说明,这里就不介绍这么多了
public void findAll(PageQuery<Product> pager);
如果我们在自己的mapper中写了这样一个方法,那么beetlsql就会在
Classpath/sql(这个目录可以配置)下找到Product.md,然后我们的方法名是findAll,就会在product.md下找到findAll这个模板语句(findAll语句可以参照上文),下面,我们来看看怎么调用这个ProductMapper
SqlManager sqlManger = ...;
ProductMapper productMapper = sqlManager.getMapper(ProductMapper.class);
Product p = new Product();
p.setShopId(1); //设置店家ID
p.setTypeId(1); //按分类id过滤
//p.setname(xxx); //名称我们这里就不过滤了
//第一个参数是页数,第二个是查询条件
PageQuery<Product> pageQuery = new PageQuery<>(1, p);
pageQuery.setPageSize(10);
productMapper.findAll(pageQuery);
//执行完findAll之后,就可以拿下面的参数了
println(pageQuery.totalPage)
println(pageQuery.list)
当然,还有更高端大气接地气的特性,一般我们Product类的设计里面,只有一个int typeId这样的属性,如果你需要偶尔进行关联查询,把typeName给查询出来,那么我建议你使用下面一种写法:
public class Product extends TailBean
然后,在模板中使用下面的关联查询
Select r.*, t.name typeName
from product r join product_type t on(r.type_id=t.id)
请注意:我们的Product类中是没有typename这个属性的呢,但是我们的Product类,继承了org.beetl.sql.core.TailBean,那么,beetlsql就会把typename(注意在beetlsql中,它会把所有的列名都转换为小写)这个属性,放在父类的tails属性(这个属性是个map)里面,那么你在页面端或者java端就可以使用${product.tails.typename}获取到typename属性(好吧,你会不会觉得,多表查询,这个世界美妙了!!!)
当然,还有一些更微妙的特性,比如,动态表名:
countByUsername
===
select count(1) from #text(type)# where username=#username#
然后在mapper中这样调用(其中type代表动态表名)
public long countByUsername(
@Param("type") String type, @Param("username") String username);
记住,mapper中的param注解是一定要写的
使用这个框架,基本需要理解的是以下几个类:
- org.beetl.sql.core.NameConversion(表名到属性名的映射,其中UnderlinedNameConversion)是应用的相对比较多,beetlsql会自动将user_name映射成类中的userName。如果你的查询别名有大写,自动先转成小写。
- org.beetl.sql.core.TailBean(多表关联需要,这个类在前面已经有说明了,相当方便)
- org.beetl.sql.core.SQLManager(相当于jdbcTemplate,有时候mapper并不能满足你的全部需求,请直接使用这个)
- org.beetl.sql.core.mapper.BaseMapper<User>(请让你的所有mapper都继承这个baseMapper,比如userMapper,并且自己的UserMapper里的方法,和md文件相对应,一般来说,mybatis中的mapper也是和xml中的对应的),举个例子球:
countByUsername
===
select count(1) from #text(type)# where username=#username#
updatePassword
===
update #text(type)# set password=#password# where username=#username#
比如我的user.md有这两个操作,那么我的userMapper就这么写:
public interface UserMapper extends BaseMapper<User> {
public long countByUsername(
@Param("type") String type, @Param("username") String username);
public int updatePassword(@Param("type") String type,
@Param("username") String username, @Param("password") String password);
}
- org.beetl.sql.core.mapper.MapperJavaProxy.MapperJavaProxy
这个类也很重要,beetlsql会使用这个类,动态生成mapper(比如userMaper)的实现类
未完待续。。。