关键是扩大自己的视野,因为有的我真的不知道可以这样写?
比如:
一:if test --可以去掉多余的and
<if test = "defaultQuery and sum == false"> AND (sysdate - T.CREATED) < 90 </if>
<if test = "limit30 and sum == false"> AND (sysdate - T.CREATED) < 30 </if>
test里面的表达式,limit30是model中的一个布尔变量,sum是统布尔计变量,
如果limit30 传 true ,sum 传 false,就是不统计,那么 test 表达式就为 true,那么就会走后面的语句(只查询近30天的记录),否则不走。
如果前端不传limit30,布尔默认为false,那么怎么都不会走下面的。也就是
要查90天就是 传 defaultQuery = true,要查30天 就传limit30 = true.
二:一个字段代表多层意思进行搜索
<!--按照 产品描述,物料号,内部型号,外部型号 进行搜索-->
<if test = "productName != null and productName != '' ">
AND ( T1.X_NAME like '%'||#{productName}||'%'
OR T1.PART_NUM like '%'||#{productName}||'%'
OR T2.ATTRIB_01 like '%'||#{productName}||'%'
OR T2.ATTRIB_02 like '%'||#{productName}||'%'
)
</if>
三:mybatis调用存储过程写法
<select id = "quote2agreement" statementType = "CALLABLE" parameterType="java.util.Map">
<![CDATA[
{
call QUOTE_TO_AGREE_COMMIT( #{AGREE_ID,mode=IN,jdbcType=VARCHAR} )
}
]]>
</select>
QUOTE_TO_AGREE_COMMIT 这个应该是 存储过程的名字。 ()这个应该存储过程要用到的参数
statementType = “CALLABLE” 这个应该是固定写法,如果是调用存储过程的话。
四:有的话,再写。到PLSQL去看了下 文件夹 Procedures(存储过程),看了很多 绿色P圆圈,可能就是Procedures的标志吧看了上面的 QUOTE_TO_AGREE_COMMIT 这个。所以看看别人是怎么写存储过程的。
create or replace procedure QUOTE_TO_AGREE_COMMIT(AGREE_ID in varchar2) is
AGREE_ID1 varchar2(50) := null ; -----合同Id
OPPTY_ID1 varchar2(50) := null ; -----商机Id
QUOTE_ID1 varchar2(50) := null ; -----报价Id
CHANNEL_ID varchar2(50) := null ; -----招投标结果,中标渠道Id
Standard_Payment varchar2(100) := null ; -----客户标准付款方式
Payment_Days varchar2(100) := null ; -----客户账期
Black_Type varchar2(100) := null ; -----黑名单类型
PR_ADDR_ID varchar2(50) := null ; -----客户地址Id
ATTRIB_07 varchar2(50) := null ; -----付款Id
ORDER_DATES varchar2(50) := null ; -----预期天数
LoginID varchar2(50) := null ; -----用户Id
begin
AGREE_ID1 := AGREE_ID;
/* select substr( AGREE_ID,0,instr(AGREE_ID,';') -1 ) tt into AGREE_ID1 from dual;
select substr( AGREE_ID,0,instr(AGREE_ID,';') +1,length(AGREE_ID) ) tt into LoginID from dual; */
/*根据合同Id,匹配其他逻辑需要的信息*/
select T.QUOTE_ID,T.OPTY_ID,T.CREATED_BY
into QUOTE_ID1,OPTY_ID1,LoginID
from siebel.s_doc_agree T
where T.ROW_ID = AGREE_ID1;
/* \*获取当前登录人的用户Id*\
select t2.row_id into LoginID from siebel.s_user T2 where T2.LOGIN in (select t.USERNAME from user_users T);
*/
--如果合同Id 和 商机Id 都不为空的情况下,将招投标结果客户 写到合同下单渠道
IF ( AGREE_ID1 IS NOT NULL AND OPPTY_ID1 IS NOT NULL) THEN
select T.CHANNEL_ID
into CHANNEL_ID
from sieble.CX_BIDDING_RE T
where T.OPTY_ID = OPPTY_ID1
and ROWNUM <= 1;
--如果招投标结果的中标渠道不为空,获取中标渠道客户的账期信息
if ( CHANNEL_ID is not null ) then
select T2.ATTRIB_47,
T2.ATTRIB_59,
T.X_BLACK_TYPE,
T.PR_ADDR_ID,
T2.ATTRIB_07
into Standard_Payment,
Payment_Days,
Black_Type,
PR_ADDR_ID,
ATTRIB_07
from siebel.s_org_ext T,
siebel.s_org_ext_x T2
where T.ROW_ID = CHANNEL_ID
and T.ROW_ID = T2.PAR_ROW_ID(+);
/*把中标渠道客户设置到生成的合同上,并同时更新账期信息*/
update siebel.s_Doc_Agree T
set T.X_ACCOUNT_ID = CHANNEL_ID,
T.BILL_TO_ADDR_ID = PR_ADDR_ID,
T.X_CONSIGNEE_ADD_ID =PR_ADDR_ID,
T.X_CONSIGNEE_ACC_ID =CHANNEL_ID,
T.X_CUS_PAY_ID =ATTRIB_07,
T.X_BLACK_TYPE =Black_Type,
T.X_ACCNT_DAYS =Payment_Days,
T.X_ACCNT_PAY_TYPE =Standard_Payment
where T.ROW_ID = AGREE_ID1;
commit;
end if; --判定招投标结果 尾
END IF; --判定合同ID 和商机Id 都不为空
/*将报价销售团队,复制到生成的合同中*/
siebel.quote_to_agree_add_position(AGREE_ID1,QUOTE_ID1); --这应该是个写好的方法吧。
/*回写报价下产品清单的请求数量*/
siebel.UPDATE_QUOTE_ITEM_NUM(QUOTE_ID1);
/*更新商机的销售阶段*/
siebel.Change_Oppty_Stage(OPPTY_ID1);
/*报价生成合同后回写标记*/
siebel.Update_Quote_Flag(QUOTE_ID1);
/*下单客户是否转交易 置为Y,并且通过ERP视图 获取下单客户的预期款天数*/
siebel.ORDER_ACCOUNT_CHECK(QUOTE_ID1,ORDER_DATES);
/*对生成的合同进行逻辑操作*/
siebel.UPDATE_AGREE(AGREE_ID1,LoginID);
/*检查合同行的意向单价与报价行是否一致,解决小数点问题*/
--siebel.QUOTE_TO_AGREE_FIXPRICE(AGREE_ID1,QUOTE_ID1);
end QUOTE_TO_AGREE_COMMIT;
五:创建表,创建索引
偶尔看到的,语法如下:
--create table创建表
create table S_DOC_AGREE
(
row_id varchar(15) not null,
created DATE default sysdate not null,
created_by varchar(15) not null,
last_upd DATE default sysdate not null,
dcking_num number(22,7) default 0,
active_id char(1) default 'N' not null,
agr_active_id char(1) default 'Y' not null,
name varchar2(50) not null,
rev_num number(22,7) not null,
eff_date DATE,
desc_text varchar2(255)
...
)
--表空间
tablespace SIEBELDATA
pctfree 10
initrans 1
maxtrans 255
storage ( intial 1M next 8K minextends 1 maxextends unlimited);
--create / recreate indexs 创建索引
create index S_DOC_AGREE_F52
on S_DOC_AGREE(FN_ACCNT_ID)
tablespace SIEBELINDEX
pctfree 10
initrans 2
maxtrans 255
storage ( initial 1M next 1M minextends 1 maxextends unlimited );
...
--grant/revoke object privileges 赋予/撤回 对象特权。
grant select ,insert,update ,delete on S_DOC_AGREE to IF_USER with grant option; //赋予增删改查权限?、
grant select ,insert,update ,delete on S_DOC_AGREE to SSE_ROLE;
六:今天看到了 一个新的标签,Mybatis中的sql。也可能是我之前忘记了,可能不常用吧,还是写下来。
<select id="getHomeFunctionList" resultMap="HomeFunctionMapperTwo" parameterType="com.xxxxx.model.setting.HomeFunctionModel" >
select t.* ,
case when t1.parentid is null and t.name != '公共办公' then 'N' else 'Y' end as ISCHILDREN
from t_home_function t
left join ( select distinct a.parentid from t_home_function a where a.parentid is not null) t1 on t.id=t1.parentid
where
<if test ="type != -1"> t.type = #{type}</if>
<choose> <!--我日,第一次在项目中看到。这个感觉和 if test 没区别吧-->
<when test="parentId != null and parentId != '' "> and t.parentid = #{parentId}</when>
<otherwise>and t.parentid is null </otherwise>
</choose>
order by idx
</select>
七:2019-3-25今天在SettingMapper中 又看到了一个新的sql,update标签的
应该是是修改密码。 T_CONFIG中的VALUE字段是 密码。具体可以看 另一篇文章:登陆接口补充
我去,后来我又看到了 好多啊。还有insert ,delete 里面都有这种写法。insert内有selectKey标签
<!--更新语句后,执行插入,在执行查询?可以这样写?、 插入语句,这样写 有问题吧? insert into 表 (字段) select ?????->
<sql id="insertLog">
insert into T_LOG (ID , opration,content,created,loginname)
select ( select max(id)+1 from (select id from T_LOG union all select 0 from dual) ) ,
'${opration}',
'${content}' ,
systimestamp,
#{loginname}
from dual ;
</sql>
<!--修改密码:编辑配置信息-->
<update id="editConfig" parameterType="com.xxxxx.commmon.model.ConfigModel">
begin
update T_CONFIG set VALUE = #{value} where KEY = #{rowId} ;
<include refid = "isnertLog">
<property name="opration" value="编辑配置信息" />
<property name="content" value="id = ${rowId} ,新值 = ${value}" />
</include>
end ;
</update>
<!--编辑关键字-->
<insert id="editKey" parameterType="com.xxxxx.model.setting.KeyModel">
begin
<!--这个表示在执行 insert 语句之前,首先执行 selectKey(不一定为主键字段)语句,并把得到的结果 赋值给 totalRecords.-->
<selectKey keyProperty="totalRecords" resultType="int" order="BEFORE">
select count(1) from T_PERMISSION_KEY where KEY = #{rowId}
</selectKey>
<if test="totalRecords != 0">
update T_PERMISSION_JEY
set (NAME,DESCRIPTION,TYPE) = (select #{name} , #{decription} ,#{type} from dual)
where KEY = #{rowId};
<include refid = "isnertLog">
<property name="opration" value="更新关键字" />
<property name="content" value="id = ${rowId} ,名称 => ${name}" />
</include>
</if>
<if test="totalRecords == 0">
insert into T_PERMISSION_KEY set (KEY,NAME,DESCRIPTION,TYPE) values (#{rowId},#{name} , #{decription} ,#{type}) ;
<include refid = "isnertLog">
<property name="opration" value="新增关键字" />
<property name="content" value="id = ${rowId} ,名称 => ${name}" />
</include>
</if>
end;
</insert>
<!--删除关键字-->
<delete id="delKey" parameterType="com.xxxx.model.setting.KeyModel" >
bein
delete from T_PERMISSION_KEY where KEY = #{rowId};
<include refid = "isnertLog">
<property name="opration" value="删除关键字" />
<property name="content" value="id = ${rowId}" />
</include>
end;
</delete>
其中涉及的KeyModel如下:
包:com.xxxxx.model.setting
KeyModel(埋点信息) extends BaseModel
name—名称 decription—描述 int type= -1;—类型
其实埋点是啥,我不是不清楚。不知道用的多不多。
八:2019-03-27:今天Siebel又提供我了一个sql,里面用到了一个关键字 EXISTS,可能我很久没写过了,都忘记怎么用了。今天就下下来回忆回忆.基本计数很少用count(*) ,都是用COUNT(1),我在mapper.xml中都没看到过COUNT() .
1可以删除 0不可以删除
SELECT COUNT(1)
FROM DUAL
WHERE (
EXISTS ( select 1 from SIEBEL.CX_UBID_APPLY T1 WHERE T1.ROW_ID = #{rowId} AND CREATED_BY = #{loginId} )
OR EXISTS ( select 1 from SIEBEL.S_LST_OF_VAL T2 WHERE T2.TYPE= 'DH_UNBID_MANAGER' AND T2.NAME = '非标管理员' AND T2.ACTIVE_FLG = 'Y' AND T2.LANG_ID = 'CHS' AND INSTR(T2.DESC_TEXT,#{loginName})>0 )
)
AND EXISTS( select 1 from SIEBEL.CX_UBID_APPLY T1 WHERE T1.ROW_ID = #{rowId} AND (T1.X_FCHECKSTATUS IS NULL OR T1.X_FCHECKSTATUS = '未启动') )
九:如果可以请使用 【between and】 或者【Exists】来代替 【in,not in】;
如果一个扩展虚拟表 被多次重复使用 请使用【with】语法。
sql优化的本质是:避免全表扫描,尽量使用索引。
比如:模糊搜索的时候尽量使用“a%”(走索引),不要使用“%a%”.(不走索引)
INSTR(T1.X_FTASKERS, #{loginName}) > 0
这个呢类似于
T1.X_FTASKERS like '%'||#{loginName}||'%'
十:Model中的get set方法
ContractModel
public String getMyAccountType(){
if("甲方".equals(this.getAccountType())){ return "甲方客户";}
if( "战略工程商".equals(this.getChannelAccountType()) || "核心工程商".equals(this.getChannelAccountType()) ||"普通工程商".equals(this.getChannelAccountType()) ||"中小工程商".equals(this.getChannelAccountType()) ){ return “工程商”;}
return "分销商";
}
十一:HTTP代码
400----BadRequest : 1前段提交的字段与后台尸体类型不一致。2后台需要json字符串类型,前段没有将对象转化为String类型。
404—路径错误
405—请求方法get,post使用错误
415—(media-Type)传输的数据格式错误
203—重定向
500—服务器错误,也就是内部代码有问题
304—查询的数据走的是本地缓存。