接口必须实现BaseMapper接口(后面可以自定义一个Base接口),它提供内置的CRUID方法,如insert,unique,template,templateOne ,updateById等

    BaseMapper 具备数据库常见的操作,接口只需要定义额外的方法与sqlId同名即可。

    如上select将会对应如下md文件

    1. select
    2. ===
    3. select * from user where name = #name#

    如果你使用JDK8,不必为参数提供名称,自动对应。但必须保证java编译的时候开启-parameters选项。如果使用JDK8以下的版本,则可以使用@Param注解()

    1. List<User> select(@Param("name") String name);

    BeetlSql的mapper方法总会根据调用方法名字,返回值,以及参数映射到SQLManager相应的查询接口,比如返回类型是List,意味着发起SQLManager.select 查询,如果返回是一个Map或者Pojo,则发起一次selectSingle查询,如果返回定义为List,则表示查询实体,如果定义为List ,则对应的查询结果映射为Long

    定义好接口后,可以通过SQLManager.getMapper 来获取一个Dao真正的实现

    1. UserDao dao = sqlManager.getMapper(UserDao.class);

    如果你使用Spring或者SpringBoot,可以参考Spring集成一章,了解如何自动注入Mapper

    1. @SqlResource("core.user")
    2. public interface UserCoreDao extends BaseMapper<User> {
    3. List<User> select(String name);
    4. }
    5. @SqlResource("console.user")
    6. public interface UserConsoleDao extends BaseMapper<User> {
    7. List<User> select(String name);
    8. }

    6.1. 内置CRUD

    BaseMapper包含了内置的常用查询,如下

    1. public interface BaseMapper<T> {
    2. /**
    3. * 通用插入,插入一个实体对象到数据库,所以字段将参与操作,除非你使用ColumnIgnore注解
    4. * @param entity
    5. */
    6. void insert(T entity);
    7. /**
    8. * (数据库表有自增主键调用此方法)如果实体对应的有自增主键,插入一个实体到数据库,设置assignKey为true的时候,将会获取此主键
    9. * @param entity
    10. * @param autDbAssignKey 是否获取自增主键
    11. */
    12. void insert(T entity,boolean autDbAssignKey);
    13. /**
    14. * 插入实体到数据库,对于null值不做处理
    15. * @param entity
    16. */
    17. void insertTemplate(T entity);
    18. /**
    19. * 如果实体对应的有自增主键,插入实体到数据库,对于null值不做处理,设置assignKey为true的时候,将会获取此主键
    20. * @param entity
    21. * @param autDbAssignKey
    22. */
    23. void insertTemplate(T entity,boolean autDbAssignKey);
    24. /**
    25. * 批量插入实体。此方法不会获取自增主键的值,如果需要,建议不适用批量插入,适用
    26. * <pre>
    27. * insert(T entity,true);
    28. * </pre>
    29. * @param list
    30. */
    31. void insertBatch(List<T> list);
    32. /**
    33. * (数据库表有自增主键调用此方法)如果实体对应的有自增主键,插入实体到数据库,自增主键值放到keyHolder里处理
    34. * @param entity
    35. * @return
    36. */
    37. KeyHolder insertReturnKey(T entity);
    38. /**
    39. * 根据主键更新对象,所以属性都参与更新。也可以使用主键ColumnIgnore来控制更新的时候忽略此字段
    40. * @param entity
    41. * @return
    42. */
    43. int updateById(T entity);
    44. /**
    45. * 根据主键更新对象,只有不为null的属性参与更新
    46. * @param entity
    47. * @return
    48. int updateTemplateById(T entity);
    49. /**
    50. * 根据主键删除对象,如果对象是复合主键,传入对象本生即可
    51. * @return
    52. */
    53. int deleteById(Object key);
    54. /**
    55. * 根据主键获取对象,如果对象不存在,则会抛出一个Runtime异常
    56. * @param key
    57. * @return
    58. */
    59. T unique(Object key);
    60. /**
    61. * 根据主键获取对象,如果对象不存在,返回null
    62. * @param key
    63. * @return
    64. */
    65. T single(Object key);
    66. /**
    67. * 根据主键获取对象,如果在事物中执行会添加数据库行级锁(select * from table where id = ? for update),如果对象不存在,返回null
    68. * @param key
    69. * @return
    70. */
    71. T lock(Object key);
    72. /**
    73. * 返回实体对应的所有数据库记录
    74. * @return
    75. */
    76. List<T> all();
    77. /**
    78. * 返回实体对应的一个范围的记录
    79. * @param start
    80. * @param size
    81. * @return
    82. */
    83. List<T> all(int start,int size);
    84. /**
    85. * 返回实体在数据库里的总数
    86. * @return
    87. */
    88. long allCount();
    89. /**
    90. * 模板查询,返回符合模板得所有结果。beetlsql将取出非null值(日期类型排除在外),从数据库找出完全匹配的结果集
    91. * @param entity
    92. * @return
    93. */
    94. List<T> template(T entity);
    95. /**
    96. * 模板查询,返回一条结果,如果没有,返回null
    97. * @param entity
    98. * @return
    99. */
    100. <T> T templateOne(T entity);
    101. List<T> template(T entity,int start,int size);
    102. /**
    103. * 符合模板得个数
    104. * @param entity
    105. * @return
    106. */
    107. long templateCount(T entity);
    108. /**
    109. * 单表的基于模板查询的翻页
    110. * @param query
    111. void templatePage(PageQuery<T> query);
    112. /**
    113. * 执行一个jdbc sql模板查询
    114. * @param sql
    115. * @param args
    116. * @return
    117. */
    118. List<T> execute(String sql,Object... args);
    119. /**
    120. * 执行一个更新的jdbc sql
    121. * @param sql
    122. * @param args
    123. * @return
    124. */
    125. int executeUpdate(String sql,Object... args );
    126. SQLManager getSQLManager();
    127. /**
    128. * 返回一个Query对象
    129. * @return
    130. */
    131. Query<T> createQuery();
    132. /**
    133. * 返回一个LambdaQuery对象
    134. * @return
    135. */
    136. LambdaQuery<T> createLambdaQuery();
    137. }

    6.2. sqlId查询

    对于sqlId 是查询语句,返回值可以是任何类型,Mapper将视图将查询结果映射到定义的类型上,如下是一些常见例子

    1. public interface UserDao extends BaseMapper<User> {
    2. // 使用"user.getCount"语句,无参数
    3. public int getCount();
    4. //使用"user.findById"语句,参数是id,返回User对象
    5. public User findById(@Param("id") Integer id);
    6. //使用"user.findById"语句,参数是id,返回User对象
    7. public List<User> findByName(@Param("name") String name);
    8. //使用user.findTop10OfIds语句, 查询结果映射为Long,比如“select id from user limit 10
    9. public List<Long> findTop10OfIds();
    10. //返回一个Map,不建议这么做,最好返回一个实体,或者实体+Map的混合模型(参考BeetlSql模型)
    11. public List<Map<String,Object> findUsers(@Param("name") String name,@Param("departmentId") departmentId)
    12. }

    Mapper 查询有一个例外,如果第一个参数是一个JavaBean(即非java内置对象),则默认为是_root对象,因此如下俩个接口定义是等价的

    这俩个查询方法都将template视为一个_root对象,sql语句可以直接使用引用其属性。同样第一参数类型是Map的,BeetlSql也视为_root对象。

    如果需要查询指定范围内的结果集,可以使用@RowStart,@RowSize , 将指示Mapper发起一次范围查询(参考3.2.3)

    1. pulic List<User> selectRange(User data,Date maxTime,@RowStart int start@RowSize int size)

    如上查询语句,类似这样调用了SQLManager

    1. Map paras = new HashMap();
    2. paras.put("_root",data);
    3. paras.put("maxTime",maxTime);
    4. List<User> list = sqlManager.select("user.selectRanage",User.class,paras,start,size);

    6.3. PageQuery 查询

    PageQuery查询类似上一节的sqlId查询,不同的是,需要提供PageQuery参数以让Mapper理解为PageQuery查询,如下俩个是等价的

    1. public void queryByCondtion(PageQuery query);
    2. public PageQuery queryByCondtion(PageQuery query);

    可以添加额外参数,但PageQuery 必须是第一个参数,如

    1. public void queryByCondtion(PageQuery query,Date maxTime);

    这类似如下SQLManager调用

    1. query.setPara("maxTime",maxTime);
    2. sqlManager.pageQuery("user.queryByCondtion",User.class,query)

    也可以在方法中提供翻页参数来实现翻页查询,这时候返回值必须是PageQuery,如下

    1. public PageQuery queryByCondtion(int pageNumber,int pageSize,String name);

    6.4. 更新语句

    更新语句返回的结果可以是void,或者int,如果是批量更新,则可以返回int[]

    BeetlSql 通常根据返回值是int或者int[] 来判断是否是更新还是批量更新,如果没有返回值,会进一步判断第一个参数是否是集合或者数组,比如

    1. public void updateAllByUser(List<User> list);
    2. public void updateAllByIds(List<Integer> list);

    Beetl会假设前者是批量更新,而后者只是普通更新。建议还是不要使用void,而使用int或者int[]来帮助区分

    6.5. 插入语句

    插入语句同更新语句,唯一不同的是插入语句有时候需要获取自增序列值,这时候使用KeyHolder作为返回参数

    1. public KeyHolder insertSql(User user);

    6.6. 使用JDBC SQL可以通过@Sql注解直接在java中使用较为简单的sql语句,如下

    1. @Sql(value=" update user set age = ? where id = ? ")
    2. public void updateAge(int age,int id);
    3. @Sql(value="select id from user where create_time<?")
    4. public List<Long> selectIds(Date date)

    此时方法参数与"?" 一一对应也可以使用@Sql翻页,这要求方法参数前俩个必须是int或者long,返回结果使用PageQuery定义

    1. @Sql(value="select * from user where create_time<?")
    2. public PageQuery selectUser(int pageNumber,int pageSize,Date date)

    6.7. Mapper中的注解

    从上面我们已经了解了@Param注解,用于申明参数名字,如果使用jdk8,且打开了编译选项parameters,则可以去掉@Param注解@RowStart和 @RowSize,用于查询中的范围查询。@Sql 注解则用于在java中构造一个简短的jdbc sql语句。

    @SqlStatment 注解可以对接口参数进一步说明,他有如下属性

    • type,用于说明sqlId是何种类型的语句,默认为auto,BeetlSql将会根据sqlId对应的Sql语句判断是否是查询,还是修改语句等,通常是根据sql语句的第一个词来判断,如果是select,表示查询,如果是insert,表示新增,如果update,drop,则是更新。如果Sql模板语句第一个词不包含这些,则需要用type做说明。如下是一个需要用到type的情况
    1. selectUsers
    2. ===
    3. use("otherSelect") and status=1;

    因为beetlsql无法根据第一个单词确定操作类型,因此必须使用type=SqlStatementType.SELECT,来说明。

    • params ,可以不用在接口参数上使用@Param,而直接使用params 属性,如下是等价的
    1. @SqlStatement(params="name,age,_st,_sz")
    2. public List<User> queryUser( String name, Integer age,int start, int size);

    _st,_sz 同@RowStart和@RowSize

    6.8 使用接口默认方法

    如果你使用JDK8,则可以在mapper中添加默认方法,有利于重用