BeetlSql中的Mapper

Stella981
• 阅读 671

本文转载自CSDN博主「象在舞」的博文BeetlSql中的Mapper

BeetlSql中的Mapper

本文参考BeetlSql官方网站,官网网站请点击这里~

一、使用Mapper

BeetlSql支持Mapper,它可以将sql文件映射到一个interface接口。接口的方法名与sql文件的sqlid一一对应。接口必须实现BaseMapper接口(后面可以自定义一个Base接口),它提供内置的CRUD方法,如insert,unique,template,templateOne,updateById等。BaseMapper 具备数据库常见的操作,接口只需要定义额外的方法与sqlid同名即可。例如:

public interface UserDao extends BaseMapper<User> {
   
   
   
    List<User> select(String name);
}

上例中的select方法将会对应下面的md文件:

select
===
select * from user where name = #name#

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

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

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

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

​ Mapper 对应的sql文件默认根据实体来确定,如实体是UserInfo对象,则对应的sql文件是userInfo.md(sql),可以通过@SqlResource 注解来指定Mapper对应的sql文件。例如:

@SqlResource("core.user")
public interface UserCoreDao extends BaseMapper<User> {
   
   
   
    List<User> select(String name);
}
@SqlResource("console.user")
public interface UserConsoleDao extends BaseMapper<User> {
   
   
   
    List<User> select(String name);
}

​ 这样,这俩个mapper分别访问sql/core/user.md 和 sql/console/user.md

二、内置的CRUD

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

public interface BaseMapper<T> {
   
   
   
/**
 * 通用插入,插入一个实体对象到数据库,所有字段将参与操作,除非使用ColumnIgnore注解
 * @param entity
 */
void insert(T entity);
/**
 * (数据库表有自增主键调用此方法)如果实体对应的有自增主键,插入一个实体到数据库,设置assignKey为true的时候,将会获取此主键
 * @param entity
 * @param autDbAssignKey 是否获取自增主键
 */
void insert(T entity, boolean autDbAssignKey);
/**
 * 插入实体到数据库,对于null值不做处理
 * @param entity
 */
void insertTemplate(T entity);
/**
 * 如果实体对应的有自增主键,插入实体到数据库,对于null值不做处理,设置assignKey为true的时候,将会获取此主键
 * @param entity
 * @param autDbAssignKey
 */
void insertTemplate(T entity,boolean autDbAssignKey);
/**
 * 批量插入实体。此方法不会获取自增主键的值,如果需要,建议不适用批量插入,适用
 * <pre>
 * insert(T entity,true);
 * </pre>
 * @param list
 */
void insertBatch(List<T> list);
/**
 * (数据库表有自增主键调用此方法)如果实体对应的有自增主键,插入实体到数据库,自增主键值放到keyHolder里处理
 * @param entity
 * @return
 */
KeyHolder insertReturnKey(T entity);
 
/**
 * 根据主键更新对象,所以属性都参与更新。也可以使用主键ColumnIgnore来控制更新的时候忽略此字段
 * @param entity
 * @return
 */
int updateById(T entity);
/**
 * 根据主键更新对象,只有不为null的属性参与更新
 * @param entity
 * @return
 */
int updateTemplateById(T entity);
 
/**
 * 根据主键删除对象,如果对象是复合主键,传入对象本生即可
 * @param key
 * @return
 */
int deleteById(Object key);
 
/**
 * 根据主键获取对象,如果对象不存在,则会抛出一个Runtime异常
 * @param key
 * @return
 */
T unique(Object key);
/**
 * 根据主键获取对象,如果对象不存在,返回null
 * @param key
 * @return
 */
T single(Object key);
    /**
 * 根据主键获取对象,如果在事物中执行会添加数据库行级锁(select * from table where id = ? for update),如果对象不存在,返回null
 * @param key
 * @return
 */
T lock(Object key);
 
/**
 * 返回实体对应的所有数据库记录
 * @return
 */
List<T> all();
/**
 * 返回实体对应的一个范围的记录
 * @param start
 * @param size
 * @return
 */
List<T> all(int start,int size);
/**
 * 返回实体在数据库里的总数
 * @return
 */
long allCount();
 
/**
 * 模板查询,返回符合模板得所有结果。beetlsql将取出非null值(日期类型排除在外),从数据库找出完全匹配的结果集
 * @param entity
 * @return
 */
List<T> template(T entity);
    /**
 * 模板查询,返回一条结果,如果没有,返回null
 * @param entity
 * @return
 */
<T> T templateOne(T entity);
 
List<T> template(T entity,int start,int size);
/**
 * 符合模板得个数
 * @param entity
 * @return
 */
long templateCount(T entity);
 
/**
 * 单表的基于模板查询的翻页
 * @param query
 * @return
 */
void templatePage(PageQuery<T> query);
 
/**
 * 执行一个jdbc sql模板查询
 * @param sql
 * @param args
 * @return
 */
List<T> execute(String sql,Object... args);
/**
 * 执行一个更新的jdbc sql
 * @param sql
 * @param args
 * @return
 */
int executeUpdate(String sql,Object... args );
SQLManager getSQLManager();
/**
 * 返回一个Query对象
 * @return
 */
Query<T> createQuery();
 
 /**
 * 返回一个LambdaQuery对象
 * @return
 */
LambdaQuery<T> createLambdaQuery();

}
三、sqlid查询

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

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

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

public List query(User template);
public List query2(@Param("_root") User template)

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

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

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

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

四、PageQuery查询

PageQuery查询需要提供PageQuery参数以让Mapper理解为PageQuery查询,如下俩个是等价的:

public void queryByCondtion(PageQuery query);
public PageQuery queryByCondtion(PageQuery query)

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

public void queryByCondtion(PageQuery query,Date maxTime);
这类似如下SQLManager调用:

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

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

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

五、更新语句

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

public int updaetUser(int id,String name);
public int updateUser(User user);
public int[] updateAll(List<User> list);

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

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

六、插入语句

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

public KeyHolder insertSql(User user);

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

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

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

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

七、Mapper中的注解

上面已经了解了@Param注解,用于申明参数名字,如果使用jdk8,且打开了编译选项parameters,则可以去掉@Param注解。@RowStart和 @RowSize,用于查询中的范围查询。 @Sql 注解则用于在java中构造一个简短的jdbc sql语句。@SqlStatment注解可以对接口参数进一步说明,他有如下属性:

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

selectUsers
===
#use("otherSelect")# and status=1;

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

2、params ,可以不用在接口参数上使用@Param,而直接使用params属性,如下是等价的:

@SqlStatement(params="name,age,_st,_sz")
public List<User> queryUser( String name, Integer age,int start, int size);

public List<User> queryUser( @Param(name) String name, @Param(age) @RowStart Integer age,int start, @RowSize int size);

​ _st,_sz 同@RowStart和@RowSize。

八、使用接口默认方法

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

public interface SysResourceDao extends BaseMapper<SysResource> {
   
   
   
 
    void page(PageQuery<SysResource> query);
 
    default List<SysResource> listChildren(Integer resourceId) {
   
   
   
        return createLambdaQuery()
                .andNotEq(SysResource::getStatus, 1)
                .andEq(SysResource::getPid, resourceId)
                .select();
    }
}

参考资料

本文同步分享在 博客“雪域迷影”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这