美文网首页
mybaits中注入数据库名称

mybaits中注入数据库名称

作者: bin_lifecycle | 来源:发表于2020-03-31 22:33 被阅读0次

    有时我们需要在不同的数据中查询数据时,会在mybatis的xml文件中动态地注入表名

    • 1.因此我们需要在配置文件中先配置数据库名称:


      此处配置了数据库名称
    • 2.然后在代码中注入这个属性值:


      注入数据库名称
    • 3.修改mapper接口接收的参数:


      map中接收数据库名称这个参数
    • 4.在mybatis的xml文件中使用${nicsuser}取表名,用#{}正常取参数,
      由于表名或者数字类型不要自动加上单引号,所以用${}取值,其它参数由于需要在取出的值中自动加上单引号,所以用#{}取值

    延伸:预编译和非预编译

    • 预编译就是SQL提前编译好,在#{}的地方自动处理成?,然后再注入传递的参数即可,预编译由于会提前编译好SQL,所以会防止出现SQL注入的问题
     <!--采用预编译,使用${nicsuer}取动态注入的表名,
    此时取到的表名不会被加上单引号,使用#{}正产取得的参数值会自动加上单引号-->
     <select id="nicsNeSpecListForAll" parameterType="map" resultType="NeSpecMappingQueryVo">
            select nef.PRODUCTNAME nicsNeSpecName,
                    nef.VERSION nicsNeSpecVersion,
                    nef.factoryName factoryName,
                    nef.factoryId factoryId,
                    emp.name resourcesNeSpecName,
                    emp.restype restype,
                    emp.specMappingId
            from (select distinct ne.PRODUCTNAME,
                                    ne.VERSION,
                                    f.name         factoryName,
                                    f.id           factoryId
                  from ${nicsuser}.v_nics_ne ne,
                        t_pub_factory f,
                        t_nics_ems_mapping em
                  where ne.EMS = em.ems_name
                    and f.id = em.factory_id
                    and ne.DELETED = 0
                    and em.del_flag = 0) nef,
                  (select e.name,
                           mp.restype,
                           mp.nics_spec_name,
                           mp.id specMappingId
                    from t_spec_entity e,
                          t_nics_spec_mapping mp
                    where e.id = mp.spec_id
                    and mp.del_flag = 0) emp
            where nef.PRODUCTNAME = emp.nics_spec_name(+)
           <if test="factoryId !=null and factoryId !=''">
                and nef.factoryId = #{factoryId}
           </if>
           <if test="nicsNeSpecName !=null and nicsNeSpecName !=''">
                and nef.PRODUCTNAME like '%'|| #{nicsNeSpecName}||'%'
           </if>
        </select>
    
    这里就是预编译Preparing,他将分页参数的占位符编译成问号,然后等分页参数传递进来即可分页-1
     <!--映射板卡规格查询(查全部,包含未映射和已映射的)-->
        <select id="nicsCardSpecListForAll" parameterType="map" resultType="CardSpecMappingQueryVo" >
          select vcf.installedequipmentobjecttype nicsCardSpecName,
                  vcf.neportNumber nicsCardSpecPortCount,
                  vcf.installedversion nicsCardSpecVersion,
                  vcf.factoryName factoryName,
                  vcf.factoryId factoryId,
                  emp.nics_spec_name resourcesCardSpecName,
                  emp.logogram logogram,
                  emp.specEntityId,
                  emp.specMappingId
          from
    
        (select vc.installedequipmentobjecttype,
                 vc.installedversion,
           count(distinct vc.installedequipmentobjecttype || vc.installedversion ||
                 nep.PORTNO) neportNumber,
                f.name factoryName,
                f.id factoryId
            from ${nicsuser}.v_nics_card   vc,
                  ${nicsuser}.v_nics_neport nep,
                  t_pub_factory        f,
                  t_nics_ems_mapping   em
            where vc.id = nep.CARD_ID
              and vc.ems = em.ems_name
              and em.factory_id = f.id
              and vc.deleted = 0
            group by  vc.INSTALLEDEQUIPMENTOBJECTTYPE, vc.INSTALLEDVERSION,f.name,f.id
    
        union all
    
          select vc.installedequipmentobjecttype,
                  vc.installedversion,
                  0,
                  f.name factoryName,
                  f.id factoryId
            from ${nicsuser}.v_nics_card vc,
                  t_pub_factory f,
                  t_nics_ems_mapping em
            where vc.ems = em.ems_name
              and em.factory_id = f.id
              and vc.deleted = 0
              and vc.id not in (select nep.CARD_ID from ${nicsuser}.v_nics_neport nep)
          group by vc.INSTALLEDEQUIPMENTOBJECTTYPE, vc.INSTALLEDVERSION, f.name,f.id) vcf,
    
         (select e.name,
                  e.id specEntityId,
                  cp.logogram,
                  mp.restype,
                  mp.nics_spec_name,
                  mp.id specMappingId
                   from t_spec_entity e,
                        t_spec_cardprop cp,
                        t_nics_spec_mapping mp
                  where e.id = mp.spec_id
                    and e.specprop_id = cp.id
                    and mp.del_flag = 0) emp
          where vcf.installedequipmentobjecttype = emp.nics_spec_name(+)
            <if test="factoryId !=null and factoryId !=''">
                and vcf.factoryId = #{factoryId}
            </if>
            <if test="nicsCardSpecName !=null and nicsCardSpecName !=''">
                and vcf.installedequipmentobjecttype like '%'|| #{nicsCardSpecName}||'%'
            </if>
        </select>
    
    这里就是预编译Preparing,他将分页参数的占位符编译成问号,然后等分页参数传递进来即可分页-2

    -非预编译,就是说SQL不会提前编译,在执行的时候才把传递的参数传进来,这样的话就会有SQL注入的风险,比如在SQL执行的时候恶意传入一些误操作的例如drop table的SQL操作关键字等,由于SQL没有预编译而是直接拿着传递进来的参数执行SQL的,这样就有很高的风险,也容易报错

    <!--statementType="STATEMENT"参数,让SQL非预编译执行-->
    <!--映射网元规格查询(查询已经映射的)-->
        <select id="nicsNeSpecListForAll" parameterType="map" resultType="NeSpecMappingQueryVo" statementType="STATEMENT">
            select nef.PRODUCTNAME nicsNeSpecName,
                    nef.VERSION nicsNeSpecVersion,
                    nef.factoryName factoryName,
                    nef.factoryId factoryId,
                    emp.name resourcesNeSpecName,
                    emp.restype restype,
                    emp.specMappingId
            from (select distinct ne.PRODUCTNAME,
                                    ne.VERSION,
                                    f.name         factoryName,
                                    f.id           factoryId
                  from ${nicsuser}.v_nics_ne ne,
                        t_pub_factory f,
                        t_nics_ems_mapping em
                  where ne.EMS = em.ems_name
                    and f.id = em.factory_id
                    and ne.DELETED = 0
                    and em.del_flag = 0) nef,
                  (select e.name,
                           mp.restype,
                           mp.nics_spec_name,
                           mp.id specMappingId
                    from t_spec_entity e,
                          t_nics_spec_mapping mp
                    where e.id = mp.spec_id
                    and mp.del_flag = 0) emp
            where nef.PRODUCTNAME = emp.nics_spec_name(+)
           <if test="factoryId !=null and factoryId !=''">
                and nef.factoryId = #{factoryId}
           </if>
           <if test="nicsNeSpecName !=null and nicsNeSpecName !=''">
                and nef.PRODUCTNAME like '%'|| #{nicsNeSpecName}||'%'
           </if>
        </select>
    
    Executing,此时是非预编译,SQL直接执行,由于此时分页参数还没有准备好这样直接执行SQL 的结果就是出现并非所有变量都已绑定的错误 SQL报错了,分页的参数没有传进来的缘故,所以会报错

    遇到需要分页的这种情况一定不要用非预编译,不然分页参数没有传进来的时候就出现上面那种SQL错误,

    区别:

    • 预编译可以将?解析为占位符等待参数传入,然后执行SQL
    • 非预编译会直接执行SQL,然后会把?直接当成SQL中的参数来执行,所以在分页参数没有传进来替换?时,SQL直接执行就报错了

    相关文章

      网友评论

          本文标题:mybaits中注入数据库名称

          本文链接:https://www.haomeiwen.com/subject/lltnuhtx.html