代码拉取完成,页面将自动刷新
同步操作将从 sagframe/sagacity-sqltoy 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
sqltoy-orm是比hibernate+myBatis(plus)更加贴合项目的orm框架(依赖spring),具有jpa式的对象CRUD的同时具有比myBatis(plus)更直观简洁性能强大的查询功能。 支持以下数据库:
StaffInfoVO staffInfo = new StaffInfoVO();
//保存
sqlToyLazyDao.save(staffInfo);
//删除
sqlToyLazyDao.delete(new StaffInfoVO("S2007"));
//public Long update(Serializable entity, String... forceUpdateProps);
// 这里对photo 属性进行强制修改,其他为null自动会跳过
sqlToyLazyDao.update(staffInfo, "photo");
//深度修改,不管是否null全部字段修改
sqlToyLazyDao.updateDeeply(staffInfo);
List<StaffInfoVO> staffList = new ArrayList<StaffInfoVO>();
StaffInfoVO staffInfo = new StaffInfoVO();
StaffInfoVO staffInfo1 = new StaffInfoVO();
staffList.add(staffInfo);
staffList.add(staffInfo1);
//批量保存或修改
sqlToyLazyDao.saveOrUpdateAll(staffList);
//批量保存
sqlToyLazyDao.saveAll(staffList);
...............
sqlToyLazyDao.loadByIds(StaffInfoVO.class,"S2007")
//唯一性验证
sqlToyLazyDao.isUnique(staffInfo, "staffCode");
/**
* @todo 通过对象传参数,简化paramName[],paramValue[] 模式传参
* @param <T>
* @param sqlOrNamedSql 可以是具体sql也可以是对应xml中的sqlId
* @param entity 通过对象传参数,并按对象类型返回结果
*/
public <T extends Serializable> List<T> findBySql(final String sqlOrNamedSql, final T entity);
public Page<StaffInfoVO> findStaff(Page<StaffInfoVO> pageModel, StaffInfoVO staffInfoVO) {
// sql可以直接在代码中编写,复杂sql建议在xml中定义
// 单表entity查询场景下sql字段可以写成java类的属性名称
return findPageEntity(pageModel, StaffInfoVO.class, EntityQuery.create()
.where("#[staffName like :staffName]#[and createTime>=:beginDate]#[and createTime<=:endDate]")
.values(staffInfoVO)
// 字典缓存必须要设置cacheType
// 单表对象查询需设置keyColumn构成select keyColumn as column模式
.translates(new Translate("dictKeyName").setColumn("sexTypeName").setCacheType("SEX_TYPE")
.setKeyColumn("sexType"))
.translates(new Translate("organIdName").setColumn("organName").setKeyColumn("organId")));
}
//演示代码中非直接sql模式设置条件模式进行记录修改
public Long updateByQuery() {
return sqlToyLazyDao.updateByQuery(StaffInfoVO.class,
EntityUpdate.create().set("createBy", "S0001")
.where("staffName like ?").values("张"));
}
//代码中非直接sql模式设置条件模式进行记录删除
sqlToyLazyDao.deleteByQuery(StaffInfoVO.class, EntityQuery.create().where("status=?").values(0));
//1、 条件值处理跟具体sql分离
//2、 将条件值前置通过filters 定义的通用方法加工规整(大多数是不需要额外处理的)
<sql id="show_case">
<filters>
<!-- 参数statusAry只要包含-1(代表全部)则将statusAry设置为null不参与条件检索 -->
<eq params="statusAry" value="-1" />
</filters>
<value><![CDATA[
select *
from sqltoy_device_order_info t
where #[t.status in (:statusAry)]
#[and t.ORDER_ID=:orderId]
#[and t.ORGAN_ID in (:authedOrganIds)]
#[and t.STAFF_ID in (:staffIds)]
#[and t.TRANS_DATE>=:beginDate]
#[and t.TRANS_DATE<:endDate]
]]></value>
</sql>
select *
from sqltoy_device_order_info t
where #[t.ORGAN_ID in (:authedOrganIds)]
#[and t.TRANS_DATE>=:beginDate]
#[and t.TRANS_DATE<:endDate]
sqlToyLazyDao.findBySql(sql, MapKit.keys("authedOrganIds","beginDate", "endDate").values(authedOrganIdAry,beginDate,null),
DeviceOrderInfoVO.class);
select *
from sqltoy_device_order_info t
where t.ORDER_ID=?
and t.ORGAN_ID in (?,?,?)
and t.TRANS_DATE>=?
<!-- 快速分页和分页优化演示 -->
<sql id="sqltoy_fastPage">
<!-- 分页优化器,通过缓存实现查询条件一致的情况下在一定时间周期内缓存总记录数量,从而无需每次查询总记录数量 -->
<!-- parallel:是否并行查询总记录数和单页数据,当alive-max=1 时关闭缓存优化 -->
<!-- alive-max:最大存放多少个不同查询条件的总记录量; alive-seconds:查询条件记录量存活时长(比如120秒,超过阀值则重新查询) -->
<page-optimize parallel="true" alive-max="100" alive-seconds="120" />
<value>
<![CDATA[
select t1.*,t2.ORGAN_NAME
-- @fast() 实现先分页取10条(具体数量由pageSize确定),然后再关联
from @fast(select t.*
from sqltoy_staff_info t
where t.STATUS=1
#[and t.STAFF_NAME like :staffName]
order by t.ENTRY_DATE desc
) t1
left join sqltoy_organ_info t2 on t1.organ_id=t2.ORGAN_ID
]]>
</value>
<!-- 这里为极特殊情况下提供了自定义count-sql来实现极致性能优化 -->
<!-- <count-sql></count-sql> -->
</sql>
/**
* 基于对象传参数模式
*/
public void findPageByEntity() {
StaffInfoVO staffVO = new StaffInfoVO();
// 作为查询条件传参数
staffVO.setStaffName("陈");
// 使用了分页优化器
// 第一次调用:执行count 和 取记录两次查询
// 第二次调用:在特定时效范围内count将从缓存获取,只会执行取单页记录查询
Page result = sqlToyLazyDao.findPageBySql(new Page(), "sqltoy_fastPage", staffVO);
}
//支持对象属性注解模式进行缓存翻译
@Translate(cacheName = "dictKeyName", cacheType = "DEVICE_TYPE", keyField = "deviceType")
private String deviceTypeName;
@Translate(cacheName = "staffIdName", keyField = "staffId")
private String staffName;
<sql id="sqltoy_order_search">
<!-- 缓存翻译设备类型
cache:具体的缓存定义的名称,
cache-type:一般针对数据字典,提供一个分类条件过滤
columns:sql中的查询字段名称,可以逗号分隔对多个字段进行翻译
cache-indexs:缓存数据名称对应的列,不填则默认为第二列(从0开始,1则表示第二列),
例如缓存的数据结构是:key、name、fullName,则第三列表示全称
-->
<translate cache="dictKeyName" cache-type="DEVICE_TYPE" columns="deviceTypeName" cache-indexs="1"/>
<!-- 员工名称翻译,如果同一个缓存则可以同时对几个字段进行翻译 -->
<translate cache="staffIdName" columns="staffName,createName" />
<filters>
<!-- 反向利用缓存通过名称匹配出id用于精确查询 -->
<cache-arg cache-name="staffIdNameCache" param="staffName" alias-name="staffIds"/>
</filters>
<value>
<![CDATA[
select ORDER_ID,
DEVICE_TYPE,
DEVICE_TYPE deviceTypeName,-- 设备分类名称
STAFF_ID,
STAFF_ID staffName, -- 员工姓名
ORGAN_ID,
CREATE_BY,
CREATE_BY createName -- 创建人名称
from sqltoy_device_order_info t
where #[t.ORDER_ID=:orderId]
#[and t.STAFF_ID in (:staffIds)]
]]>
</value>
</sql>
// parallQuery 面向查询(不要用于事务操作过程中),sqltoy提供强大的方法,但是否恰当使用需要使用者做合理的判断
/**
* @TODO 并行查询并返回一维List,有几个查询List中就包含几个结果对象,paramNames和paramValues是全部sql的条件参数的合集
* @param parallQueryList
* @param paramNames
* @param paramValues
*/
public <T> List<QueryResult<T>> parallQuery(List<ParallQuery> parallQueryList, String[] paramNames,
Object[] paramValues);
//定义参数
String[] paramNames = new String[] { "userId", "defaultRoles", "deployId", "authObjType" };
Object[] paramValues = new Object[] { userId, defaultRoles, GlobalConstants.DEPLOY_ID,
SagacityConstants.TempAuthObjType.GROUP };
// 使用并行查询同时执行2个sql,条件参数是2个查询的合集
List<QueryResult<TreeModel>> list = super.parallQuery(
Arrays.asList(
ParallQuery.create().sql("webframe_searchAllModuleMenus").resultType(TreeModel.class),
ParallQuery.create().sql("webframe_searchAllUserReports").resultType(TreeModel.class)),
paramNames, paramValues);
<!-- 跨数据库函数自动替换(非必须项),适用于跨数据库软件产品,如mysql开发,oracle部署 -->
<property name="functionConverts" value="default">
<!-- 也可以这样自行根据需要进行定义和扩展
<property name="functionConverts">
<list>
<value>org.sagacity.sqltoy.plugins.function.Nvl</value>
<value>org.sagacity.sqltoy.plugins.function.SubStr</value>
<value>org.sagacity.sqltoy.plugins.function.Now</value>
<value>org.sagacity.sqltoy.plugins.function.Length</value>
</list>
</property> -->
<sql id="sqltoy_showcase">
<value>
<![CDATA[
select * from sqltoy_user_log t
where t.user_id=:userId
]]>
</value>
</sql>
<!-- sqlId_数据库方言(小写) -->
<sql id="sqltoy_showcase_mysql">
<value>
<![CDATA[
select * from sqltoy_user_log t
where t.user_id=:userId
]]>
</value>
</sql>
品类 | 销售月份 | 销售笔数 | 销售数量(吨) | 销售金额(万元) |
---|---|---|---|---|
苹果 | 2019年5月 | 12 | 2000 | 2400 |
苹果 | 2019年4月 | 11 | 1900 | 2600 |
苹果 | 2019年3月 | 13 | 2000 | 2500 |
香蕉 | 2019年5月 | 10 | 2000 | 2000 |
香蕉 | 2019年4月 | 12 | 2400 | 2700 |
香蕉 | 2019年3月 | 13 | 2300 | 2700 |
<!-- 行转列 -->
<sql id="pivot_case">
<value>
<![CDATA[
select t.fruit_name,t.order_month,t.sale_count,t.sale_quantity,t.total_amt
from sqltoy_fruit_order t
order by t.fruit_name ,t.order_month
]]>
</value>
<!-- 行转列,将order_month作为分类横向标题,从sale_count列到total_amt 三个指标旋转成行 -->
<pivot start-column="sale_count" end-column="total_amt" group-columns="fruit_name" category-columns="order_month" />
</sql>
品类 | 2019年3月 | 2019年4月 | 2019年5月 | ||||||
---|---|---|---|---|---|---|---|---|---|
笔数 | 数量 | 总金额 | 笔数 | 数量 | 总金额 | 笔数 | 数量 | 总金额 | |
香蕉 | 13 | 2300 | 2700 | 12 | 2400 | 2700 | 10 | 2000 | 2000 |
苹果 | 13 | 2000 | 2500 | 11 | 1900 | 2600 | 12 | 2000 | 2400 |
<sql id="group_summary_case">
<value>
<![CDATA[
select t.fruit_name,t.order_month,t.sale_count,t.sale_quantity,t.total_amt
from sqltoy_fruit_order t
order by t.fruit_name ,t.order_month
]]>
</value>
<!-- reverse 是否反向 -->
<summary columns="sale_count,sale_quantity,total_amt" reverse="true">
<!-- 层级顺序保持从高到低 -->
<global sum-label="总计" label-column="fruit_name" />
<group group-column="fruit_name" sum-label="小计" label-column="fruit_name" />
</summary>
</sql>
品类 | 销售月份 | 销售笔数 | 销售数量(吨) | 销售金额(万元) |
---|---|---|---|---|
总计 | 71 | 12600 | 14900 | |
小计 | 36 | 5900 | 7500 | |
苹果 | 2019年5月 | 12 | 2000 | 2400 |
苹果 | 2019年4月 | 11 | 1900 | 2600 |
苹果 | 2019年3月 | 13 | 2000 | 2500 |
小计 | 35 | 6700 | 7400 | |
香蕉 | 2019年5月 | 10 | 2000 | 2000 |
香蕉 | 2019年4月 | 12 | 2400 | 2700 |
香蕉 | 2019年3月 | 13 | 2300 | 2700 |
<!-- 列与列环比演示 -->
<sql id="cols_relative_case">
<value>
<![CDATA[
select t.fruit_name,t.order_month,t.sale_count,t.sale_amt,t.total_amt
from sqltoy_fruit_order t
order by t.fruit_name ,t.order_month
]]>
</value>
<!-- 数据旋转,行转列,将order_month 按列显示,每个月份下面有三个指标 -->
<pivot start-column="sale_count" end-column="total_amt" group-columns="fruit_name" category-columns="order_month" />
<!-- 列与列之间进行环比计算 -->
<cols-chain-relative group-size="3" relative-indexs="1,2" start-column="1" format="#.00%" />
</sql>
品类 | 2019年3月 | 2019年4月 | 2019年5月 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
笔数 | 数量 | 比上月 | 总金额 | 比上月 | 笔数 | 数量 | 比上月 | 总金额 | 比上月 | 笔数 | 数量 | 比上月 | 总金额 | 比上月 | |
香蕉 | 13 | 2300 | 2700 | 12 | 2400 | 4.30% | 2700 | 0.00% | 10 | 2000 | -16.70% | 2000 | -26.00% | ||
苹果 | 13 | 2000 | 2500 | 11 | 1900 | -5.10% | 2600 | 4.00% | 12 | 2000 | 5.20% | 2400 | -7.70% |
sql参见quickstart项目:com/sqltoy/quickstart/sqltoy-quickstart.sql.xml 文件
<!-- 演示分库 -->
<sql id="qstart_db_sharding_case">
<sharding-datasource strategy="hashDataSource"
params="userId" />
<value>
<![CDATA[
select * from sqltoy_user_log t
-- userId 作为分库关键字段属于必备条件
where t.user_id=:userId
#[and t.log_date>=:beginDate]
#[and t.log_date<=:endDate]
]]>
</value>
</sql>
<!-- 演示分表 -->
<sql id="qstart_sharding_table_case">
<sharding-table tables="sqltoy_trans_info_15d"
strategy="realHisTable" params="beginDate" />
<value>
<![CDATA[
select * from sqltoy_trans_info_15d t
where t.trans_date>=:beginDate
#[and t.trans_date<=:endDate]
]]>
</value>
</sql>
@Sharding 在对象上通过注解来实现分库分表的策略配置
参见:com.sqltoy.quickstart.ShardingSearchTest 进行演示
package com.sqltoy.showcase.vo;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.sagacity.sqltoy.config.annotation.Sharding;
import org.sagacity.sqltoy.config.annotation.SqlToyEntity;
import org.sagacity.sqltoy.config.annotation.Strategy;
import com.sagframe.sqltoy.showcase.vo.base.AbstractUserLogVO;
/*
* db则是分库策略配置,table 则是分表策略配置,可以同时配置也可以独立配置
* 策略name要跟spring中的bean定义name一致,fields表示要以对象的哪几个字段值作为判断依据,可以一个或多个字段
* maxConcurrents:可选配置,表示最大并行数 maxWaitSeconds:可选配置,表示最大等待秒数
*/
@Sharding(db = @Strategy(name = "hashBalanceDBSharding", fields = { "userId" }),
// table = @Strategy(name = "hashBalanceSharding", fields = {"userId" }),
maxConcurrents = 10, maxWaitSeconds = 1800)
@SqlToyEntity
public class UserLogVO extends AbstractUserLogVO {
private static final long serialVersionUID = 1296922598783858512L;
/** default constructor */
public UserLogVO() {
super();
}
}
根据对象属性值,产生规则有序的ID,比如:订单类型为采购:P 销售:S,贸易类型:I内贸;O 外贸; 订单号生成规则为:1位订单类型+1位贸易类型+yyMMdd+3位流水(超过3位自动扩展) 最终会生成单号为:SI191120001
package com.sqltoy.quickstart;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
*
* @project sqltoy-quickstart
* @description quickstart 主程序入口
* @author zhongxuchen
* @version v1.0, Date:2020年7月17日
* @modify 2020年7月17日,修改说明
*/
@SpringBootApplication
@ComponentScan(basePackages = { "com.sqltoy.config", "com.sqltoy.quickstart" })
@EnableTransactionManagement
public class SqlToyApplication {
/**
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(SqlToyApplication.class, args);
}
}
# sqltoy config
spring.sqltoy.sqlResourcesDir=classpath:com/sqltoy/quickstart
spring.sqltoy.translateConfig=classpath:sqltoy-translate.xml
spring.sqltoy.debug=true
#spring.sqltoy.reservedWords=status,sex_type
#dataSourceSelector: org.sagacity.sqltoy.plugins.datasource.impl.DefaultDataSourceSelector
#spring.sqltoy.defaultDataSource=dataSource
# 提供统一公共字段赋值(源码参见quickstart)
spring.sqltoy.unifyFieldsHandler=com.sqltoy.plugins.SqlToyUnifyFieldsHandler
#spring.sqltoy.printSqlTimeoutMillis=200000
<?xml version="1.0" encoding="UTF-8"?>
<sagacity
xmlns="http://www.sagframe.com/schema/sqltoy-translate"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sagframe.com/schema/sqltoy-translate http://www.sagframe.com/schema/sqltoy/sqltoy-translate.xsd">
<!-- 缓存有默认失效时间,默认为1小时,因此只有较为频繁的缓存才需要及时检测 -->
<cache-translates>
<!-- 基于sql直接查询的方式获取缓存 -->
<sql-translate cache="dictKeyName"
datasource="dataSource">
<sql>
<![CDATA[
select t.DICT_KEY,t.DICT_NAME,t.STATUS
from SQLTOY_DICT_DETAIL t
where t.DICT_TYPE=:dictType
order by t.SHOW_INDEX
]]>
</sql>
</sql-translate>
<!-- 员工ID和姓名的缓存 -->
<sql-translate cache="staffIdName"
datasource="dataSource">
<sql>
<![CDATA[
select STAFF_ID,STAFF_NAME,STATUS
from SQLTOY_STAFF_INFO
]]>
</sql>
</sql-translate>
<!-- 机构号和机构名称的缓存 -->
<sql-translate cache="organIdName"
datasource="dataSource">
<sql>
<![CDATA[
select ORGAN_ID,ORGAN_NAME from SQLTOY_ORGAN_INFO order by SHOW_INDEX
]]>
</sql>
</sql-translate>
</cache-translates>
<!-- 缓存刷新检测,可以提供多个基于sql、service、rest服务检测 -->
<cache-update-checkers>
<!-- 基于sql的缓存更新检测 -->
<sql-increment-checker cache="organIdName"
check-frequency="60" datasource="dataSource">
<sql><![CDATA[
--#not_debug#--
select ORGAN_ID,ORGAN_NAME
from SQLTOY_ORGAN_INFO
where UPDATE_TIME >=:lastUpdateTime
]]></sql>
</sql-increment-checker>
<!-- 增量更新,检测到变化直接更新缓存 -->
<sql-increment-checker cache="staffIdName"
check-frequency="30" datasource="dataSource">
<sql><![CDATA[
--#not_debug#--
select STAFF_ID,STAFF_NAME,STATUS
from SQLTOY_STAFF_INFO
where UPDATE_TIME >=:lastUpdateTime
]]></sql>
</sql-increment-checker>
<!-- 增量更新,带有内部分类的查询结果第一列是分类 -->
<sql-increment-checker cache="dictKeyName"
check-frequency="15" has-inside-group="true" datasource="dataSource">
<sql><![CDATA[
--#not_debug#--
select t.DICT_TYPE,t.DICT_KEY,t.DICT_NAME,t.STATUS
from SQLTOY_DICT_DETAIL t
where t.UPDATE_TIME >=:lastUpdateTime
]]></sql>
</sql-increment-checker>
</cache-update-checkers>
</sagacity>
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SqlToyApplication.class)
public class CrudCaseServiceTest {
@Autowired
private SqlToyCRUDService sqlToyCRUDService;
/**
* 创建一条员工记录
*/
@Test
public void saveStaffInfo() {
StaffInfoVO staffInfo = new StaffInfoVO();
staffInfo.setStaffId("S190715005");
staffInfo.setStaffCode("S190715005");
staffInfo.setStaffName("测试员工4");
staffInfo.setSexType("M");
staffInfo.setEmail("test3@aliyun.com");
staffInfo.setEntryDate(LocalDate.now());
staffInfo.setStatus(1);
staffInfo.setOrganId("C0001");
staffInfo.setPhoto(FileUtil.readAsBytes("classpath:/mock/staff_photo.jpg"));
staffInfo.setCountry("86");
sqlToyCRUDService.save(staffInfo);
}
}
<sql id="show_case">
<!-- 通过filters里面的逻辑将查询条件转为null,部分逻辑则对参数进行二次转换
默认条件参数为空白、空集合、空数组都转为null
parmas 表示可以用逗号写多个参数,param 表示只支持单个参数
-->
<filters>
<!-- 等于,如机构类别前端传负一就转为null不参与条件过滤 -->
<eq params="organType" value="-1" />
<!-- 条件值在某个区间则转为null -->
<between params="" start-value="0" end-value="9999" />
<!-- 将参数条件值转换为日期格式,format可以是yyyy-MM-dd这种自定义格式也可以是:
first_of_day:月的第一天;last_of_day:月的最后一天,first_of_year:年的第一天,last_of_year年的最后一天,increment-unit默认为days -->
<to-date params="" format="yyyyMMdd" increment-time="1" increment-unit="days"/>
<!-- 将参数转为数字 -->
<to-number params="" data-type="decimal" />
<!-- 将前端传过来的字符串切割成数组 -->
<split data-type="string" params="staffAuthOrgs" split-sign=","/>
<!-- 小于等于 -->
<lte params="" value="" />
<!-- 小于 -->
<lt params="" value="" />
<!-- 大于等于 -->
<gte params="" value="" />
<!-- 大于 -->
<gt params="" value="" />
<!-- 字符替换,默认根据正则表达进行全部替换,is-first为true时只替换首个 -->
<replace params="" regex="" value="" is-first="false" />
<!-- 首要参数,即当某个参数不为null时,excludes是指被排除之外的参数全部为null -->
<primary param="orderId" excludes="organIds" />
<!-- 排他性参数,当某个参数是xxx值时,将其他参数设置为特定值 -->
<exclusive param="" compare-type="eq" compare-values=""
set-params="" set-value="" />
<!-- 通过缓存进行文字模糊匹配获取精确的代码值参与精确查询 -->
<cache-arg cache-name="" cache-type="" param="" cache-mapping-indexes="" alias-name=""/>
<!-- 将数组转化成in 的参数条件并增加单引号 -->
<to-in-arg params=""/>
</filters>
<!-- 缓存翻译,可以多个,uncached-template 是针对未能匹配时显示的补充,${value} 表示显示key值,可以key=[${value}未定义 这种写法 -->
<translate cache="dictKeyName" cache-type="POST_TYPE" columns="POST_TYPE"
cache-indexs="1" uncached-template=""/>
<!-- 安全掩码:tel\姓名\地址\卡号 -->
<!--最简单用法: <secure-mask columns="" type="tel"/> -->
<secure-mask columns="" type="name" head-size="3" tail-size="4"
mask-code="*****" mask-rate="50" />
<!-- 分库策略 -->
<sharding-datasource strategy="" />
<!-- 分表策略 -->
<sharding-table tables="" strategy="" params="" />
<!-- 分页优化,缓存相同查询条件的分页总记录数量, alive-max:表示相同的一个sql保留100个不同条件查询 alive-seconds:相同的查询条件分页总记录数保留时长(单位秒) -->
<page-optimize alive-max="100" alive-seconds="600" />
<!-- 日期格式化 -->
<date-format columns="" format="yyyy-MM-dd HH:mm:ss"/>
<!-- 数字格式 -->
<number-format columns="" format=""/>
<value>
<![CDATA[
select t1.*,t2.ORGAN_NAME from
@fast(select * from sys_staff_info t
where #[t.sexType=:sexType]
#[and t.JOIN_DATE>:beginDate]
#[and t.STAFF_NAME like :staffName]
-- 是否虚拟员工@if()做逻辑判断
#[@if(:isVirtual==true||:isVirtual==0) and t.IS_VIRTUAL=1]
) t1,sys_organ_info t2
where t1.ORGAN_ID=t2.ORGAN_ID
]]>
</value>
<!-- 为极致分页提供自定义写sql -->
<count-sql><![CDATA[]]></count-sql>
<!-- 汇总和求平均,通过算法实现复杂的sql,同时可以变成数据库无关 -->
<summary columns="" radix-size="2" reverse="false" sum-site="left">
<global sum-label="" label-column="" />
<group sum-label="" label-column="" group-column="" />
</summary>
<!-- 拼接某列,mysql中等同于group_concat\oracle 中的WMSYS.WM_CONCAT功能 -->
<link sign="," column="" />
<!-- 行转列 (跟unpivot互斥),算法实现数据库无关 -->
<pivot category-columns="" group-columns="" start-column="" end-column=""
default-value="0" />
<!-- 列转行 -->
<unpivot columns="" values-as-column="" />
</sql>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。