哎呀,父老乡亲们,好久不见啊,最近在赶新项目,好久没给大家做分享了,今天闲下来了,整理下最近写的代码,总结总结,然后今天准备给大家出两篇文章,一篇讲关于Mybatis.xml中的标签分析和接下来将要分享的在代码中真实解决掉redis带来的缓存击穿和缓存穿透问题;希望大家给我点赞转发和收藏,给我动力,让我今天把这两个知识点给大家分享完呀。好了,废话少说,现在开始干,干就完了、、、接下来开始!
1、先给大家来一个Mapper.xml的模板哈,然后一点一点的增加其新标签。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iprobeinfo.servicemanger.mapper.ArcgisServiceRegistInfoMapper">
</mapper>
这个是所有的mapper.xml文件的都是此种格式模板,唯一变的就是这个namespace的属性值,namespace的属性值设置为:包名+sql的映射文件名
2、select查询标签,这个占比会比较偏重些,因为sql语句中,用的到更多的是查询嘛,里面会有where标签、if标签和foreach标签等等。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iprobeinfo.servicemanger.mapper.ArcgisServiceRegistInfoMapper">
<select id="selectArcgisServiceRegistInfos"
parameterType="com.iprobeinfo.servicemanger.entity.ServiceRegistInfoDto"
resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo">
select *
from TBL_SERVICE_REGIST_INFO
where id=#{userId}
</select>
</mapper>
2.1:select标签:这个标签代表的就是标签内部编写的将是select查询语句。
2.2:id属性:这里是其唯一值,与mapper接口中的抽象方法一一对应,千万不能重复,mapper接口的抽象方法如下图所示:
2.3:parameterType属性:表示的是mapper接口中抽象方法传过来的值是什么类型,可以是基本类型,也可以是基本类型的包装类,也可以是实体;如果传过来的是list集合的话,那么只需要写list集合中的类型就行,例如传过来的值是List类型,那么我们只需要写成
parameterType="parameterType"
。
简言就是:parameterType属性指明查询时使用的参数类型。
2.4:resultType属性:表示SQL语句查询出来返回值的类型。例如:resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo"
那么表示的含义就是以ServiceRegistInfo类的对象进行返回。
2.5:id=#{userId},这个#{userId}意思就是接收传递过来的参数,如果只是一个值的话,只需要直接写这个值的名称,下面给大家用截图解释下mapper接口传过来的单个参数
补充一个小知识点:我这里无论是返回值类型还是接收参数类型,写的都市全路径类名,但是大家也可以只写个类名,只是需要在yml文件中进行配置下,配置代码如下所示:
如果就像刚才传过来的是实体,那么我们可以直接用实体的属性名称接收即#{userId},也可以采用参数名称.属性名称 即#{serviceRegistInfoDto.userId},这里也可以使用#{}来接收参数,可以采用${}来接受,建议采用#{}来接收,这里两者区别我就不进行详谈,大家如果想了解可以自行百度。
#Mybatise配置
mybatis:
#配置mapper中的xml路径
mapper-locations: classpath:mapper/*.xml
#xml文件映射的实体类,这个就是可以在mapper.xml文件中只需要写类名,不需要写全路径类名
type-aliases-package: com.iprobeinfo.backenduser.entity;
#这个是扫描的mapper的配置文件
config-location: classpath:/mybatis/mybatis-config.xml
这里我在我的mybatis和springBoot整合文件中进行详细解释过,想要具体了解的话,大家可以去我的博客主页里进行去查看,这里我就不给大家详谈了。
3、select查询标签中包含的where标签,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iprobeinfo.servicemanger.mapper.ArcgisServiceRegistInfoMapper">
<select id="selectArcgisServiceRegistInfos"
parameterType="com.iprobeinfo.servicemanger.entity.ServiceRegistInfoDto"
resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo">
select *
from TBL_SERVICE_REGIST_INFO
<where>
id=#{userId}
</where>
</select>
</mapper>
where标签和刚才直接所写的where id = xxx的作用是一样的,在mybatis解析后就变成了
select *
from TBL_SERVICE_REGIST_INFO
where id=#{userId}
它所存在的好处就是在多条件查询的时候,可以将多个条件都包裹在where标签中。
4、select查询标签中包含的 if
标签,代码块如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iprobeinfo.servicemanger.mapper.ArcgisServiceRegistInfoMapper">
<select id="selectArcgisServiceRegistInfos"
parameterType="com.iprobeinfo.servicemanger.entity.ServiceRegistInfoDto"
resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo">
select *
from TBL_SERVICE_REGIST_INFO
<where>
1=1
<if test="serviceName != null and serviceName != ''">
and (asri.SERVICE_NAME like CONCAT(CONCAT('%',#{serviceName}),'%') or
asri.KEY_WORD like CONCAT(CONCAT('%',#{serviceName}),'%'))
</if>
</where>
</select>
</mapper>
这里大概包含三个知识点,下面我来详细描述下。
4.1、if标签起到的作用就类似与在和java代码的if判断一样,mybatis在解析的时候会进行判断,如果为true,则增加if中的sql语句,否则不增加。if标签中的test属性是的进行判断的条件。例如 <if test="serviceName != null and serviceName != ''">
意思就是判断传过来的值serviceName 是否null和是否为空字符串。
4.2、where后面标签中我紧跟着了一个永为真的语句1=1
,它的目的我是为了拼接后面的多个and
sql语句。这个还是从同事手里学到的骚操作。
4.3、and (asri.SERVICE_NAME like CONCAT(CONCAT('%',#{serviceName}),'%')
这个语句中用到了CONCAT('%',#{serviceName})
是为了拼接字符传,拼接后成为了%serviceName
,注意这里只是在前面拼接了一个%号哈,我这里用到的模糊查询需要用到两个%,那么需要在后面继续拼接一个%,因此写成了CONCAT(CONCAT('%',#{serviceName}),'%')
,大家不要把括号给少写和包裹错哈,我当时就写错了一个,害的我找了半天,希望大家也注意下哈。
5、当传给xml的值是是个数组、list集合或者是实体中的一个某一个属性为list的集合勇敢怎么操作呢?不要怕,这里有foreach标签进行循环遍历,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iprobeinfo.servicemanger.mapper.ArcgisServiceRegistInfoMapper">
<select id="selectArcgisServiceRegistInfos"
parameterType="com.iprobeinfo.servicemanger.entity.ServiceRegistInfoDto"
resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo">
select *
from TBL_SERVICE_REGIST_INFO
<where>
1=1
<if test="serviceName != null and serviceName != ''">
and (asri.SERVICE_NAME like CONCAT(CONCAT('%',#{serviceName}),'%') or
asri.KEY_WORD like CONCAT(CONCAT('%',#{serviceName}),'%'))
</if>
<if test="serviceLabels != null and serviceLabels.size != 0">
and asri.SERVICE_LABEL in
<foreach collection="serviceLabels" item="item" open="(" separator="," close=")">
#{item, jdbcType=VARCHAR}
</foreach>
</if>
</where>
</select>
</mapper>
这里的foreach起到的作用就和java中的for循环是一样的作用。
5.1:collection
属性代表foreach遍历的是什么类型,如果是List集合,则collection=“list”;如果是array数组,写为collection=“array”;如果循环的是一个实体中引用的另一个实体的list集合,则可以直接写其名称,例如下面的这种:
在xml文件中的foreeach写成如下的所示:
5.2:
item
表示集合中每一个元素进行迭代时的别名,这个值可以随便起名,但是在下面的#{item}一定要进行对应上,否则失败。
5.3:index
指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,可以写也可以不写,一般写成idex="index"
,我一般不写。
5.4:open
表示该语句以什么开始,我这里是以(开始,所以写成open="("
。
5.5:close
表示该语句以什么结束,我这里是以)结束,所以写成close=")"
。
5.6:separator
表示在每次进行迭代之间以什么符号作为分隔符,我这里是in语句,是以逗号,
做的分割符。
这条语句经过mybatis分析后,将解析成如下语句:
select *
from TBL_SERVICE_REGIST_INFO
where 1=1
and (asri.SERVICE_NAME like %serviceName% or asri.KEY_WORD like %serviceName%))
and asri.SERVICE_LABEL in (1,5,6,7)
好了,以上就是关于mybatis的各种常用标签了,什么insert 、update 和delete标签的其他属性都和这种一样了,这里我就不给大家过多描述了,今天我看我这个解决redis缓存击穿和穿透的博客看来也写不完了,等到明天周六加班给大家干。好,今天喷到这,下面贴出我的xml文件供大家参考和探究。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iprobeinfo.servicemanger.mapper.ArcgisServiceRegistInfoMapper">
<!--<select id="selectArcgisServiceRegistInfos"-->
<!--resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo"-->
<!--parameterType="com.iprobeinfo.servicemanger.entity.ServiceRegistInfoDto" >-->
<!--select asri.SERVICE_ID,asri.SERVICE_NAME,asri.COVERAGE_AREA_ID,asri.RIGHT_TYPE,asri.SERVICE_INTRODUCE,asri.SERVICE_ORGANIZATION,-->
<!--asri.KEY_WORD,asri.SERVICE_TYPE,asri.COORDINATED_SYSTEM,asri.SERVICE_LABEL,asri.RELEASE_TIME,asri.SERVICE_PATH,mi.MENU_NAME,asri.MENU_ID,-->
<!--asri.PROVIDER_COMPANY_ID-->
<!--from TBL_SERVICE_REGIST_INFO asri-->
<!--left join TBL_MENU_INFO mi on asri.MENU_ID = mi.ID-->
<!--<where>-->
<!--1=1-->
<!--<if test="serviceName != null and serviceName != ''">-->
<!--and (asri.SERVICE_NAME like CONCAT(CONCAT('%',#{serviceName}),'%') or-->
<!--asri.KEY_WORD like CONCAT(CONCAT('%',#{serviceName}),'%'))-->
<!--</if>-->
<!--<if test="serviceLabels != null and serviceLabels.size != 0">-->
<!--and asri.SERVICE_LABEL in-->
<!--<foreach collection="serviceLabels" item="item" open="(" separator="," close=")">-->
<!--#{item, jdbcType=VARCHAR}-->
<!--</foreach>-->
<!--</if>-->
<!--<if test="serviceTypes != null and serviceTypes.size != 0">-->
<!--and asri.SERVICE_TYPE in-->
<!--<foreach collection="serviceTypes" item="item" open="(" separator="," close=")">-->
<!--#{item, jdbcType=NUMERIC}-->
<!--</foreach>-->
<!--</if>-->
<!--<if test="providerCompanyIds != null and providerCompanyIds.size != 0">-->
<!--and asri.PROVIDER_COMPANY_ID in-->
<!--<foreach collection="providerCompanyIds" item="item" open="(" separator="," close=")">-->
<!--#{item, jdbcType=NUMERIC}-->
<!--</foreach>-->
<!--</if>-->
<!--</where>-->
<!--</select>-->
<select id="selectArcgisServiceRegistInfos"
resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo"
parameterType="com.iprobeinfo.servicemanger.entity.ServiceRegistInfoDto" >
SELECT
asri.SERVICE_ID,
asri.SERVICE_NAME,
asri.COVERAGE_AREA_ID,
asri.RIGHT_TYPE,
asri.SERVICE_INTRODUCE,
asri.SERVICE_ORGANIZATION,
asri.KEY_WORD,
asri.SERVICE_TYPE,
asri.COORDINATED_SYSTEM,
asri.SERVICE_LABEL,
asri.RELEASE_TIME,
asri.SERVICE_PATH,
asri.MENU_ID,
mi.MENU_NAME,
asri.PROVIDER_COMPANY_ID,
0 IS_COLLECTION
FROM
TBL_SERVICE_REGIST_INFO asri
left join TBL_MENU_INFO mi on asri.MENU_ID = mi.ID
<where>
1=1
<if test="serviceName != null and serviceName != ''">
and (asri.SERVICE_NAME like CONCAT(CONCAT('%',#{serviceName}),'%') or
asri.KEY_WORD like CONCAT(CONCAT('%',#{serviceName}),'%'))
</if>
<if test="serviceLabels != null and serviceLabels.size != 0">
and asri.SERVICE_LABEL in
<foreach collection="serviceLabels" item="item" open="(" separator="," close=")">
#{item, jdbcType=VARCHAR}
</foreach>
</if>
<if test="serviceTypes != null and serviceTypes.size != 0">
and asri.SERVICE_TYPE in
<foreach collection="serviceTypes" item="item" open="(" separator="," close=")">
#{item, jdbcType=NUMERIC}
</foreach>
</if>
<if test="providerCompanyIds != null and providerCompanyIds.size != 0">
and asri.PROVIDER_COMPANY_ID in
<foreach collection="providerCompanyIds" item="item" open="(" separator="," close=")">
#{item, jdbcType=NUMERIC}
</foreach>
</if>
and service_id NOT IN ( SELECT service_id FROM TBL_SERVICE_REGIST_INFO re LEFT JOIN TBL_USER_SERVICEREGIST us ON re.SERVICE_ID = us.service_regist_id WHERE us.user_id = #{userId} and us.IS_COLLECTION = 1)
</where>
union
SELECT
asri.SERVICE_ID,
asri.SERVICE_NAME,
asri.COVERAGE_AREA_ID,
asri.RIGHT_TYPE,
asri.SERVICE_INTRODUCE,
asri.SERVICE_ORGANIZATION,
asri.KEY_WORD,
asri.SERVICE_TYPE,
asri.COORDINATED_SYSTEM,
asri.SERVICE_LABEL,
asri.RELEASE_TIME,
asri.SERVICE_PATH,
asri.MENU_ID,
mi.MENU_NAME,
asri.PROVIDER_COMPANY_ID,
IS_COLLECTION
FROM
TBL_SERVICE_REGIST_INFO asri
left join TBL_MENU_INFO mi on asri.MENU_ID = mi.ID
LEFT JOIN TBL_USER_SERVICEREGIST us ON asri.SERVICE_ID = us.service_regist_id
<where>
1=1
<if test="serviceName != null and serviceName != ''">
and (asri.SERVICE_NAME like CONCAT(CONCAT('%',#{serviceName}),'%') or
asri.KEY_WORD like CONCAT(CONCAT('%',#{serviceName}),'%'))
</if>
<if test="serviceLabels != null and serviceLabels.size != 0">
and asri.SERVICE_LABEL in
<foreach collection="serviceLabels" item="item" open="(" separator="," close=")">
#{item, jdbcType=VARCHAR}
</foreach>
</if>
<if test="serviceTypes != null and serviceTypes.size != 0">
and asri.SERVICE_TYPE in
<foreach collection="serviceTypes" item="item" open="(" separator="," close=")">
#{item, jdbcType=NUMERIC}
</foreach>
</if>
<if test="providerCompanyIds != null and providerCompanyIds.size != 0">
and asri.PROVIDER_COMPANY_ID in
<foreach collection="providerCompanyIds" item="item" open="(" separator="," close=")">
#{item, jdbcType=NUMERIC}
</foreach>
</if>
and us.user_id = #{userId}
</where>
</select>
<select id="selectServiceByAreaIds" parameterType="java.util.List" resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo">
select asri.SERVICE_ID ,asri.SERVICE_NAME,asri.COVERAGE_AREA_ID,asri.RIGHT_TYPE,asri.SERVICE_INTRODUCE,asri.SERVICE_ORGANIZATION,
asri.KEY_WORD,asri.SERVICE_TYPE,asri.COORDINATED_SYSTEM,asri.SERVICE_LABEL,asri.RELEASE_TIME,mi.MENU_NAME,asri.SERVICE_PATH,
mi.MENU_NAME,asri.MENU_ID,asri.PROVIDER_COMPANY_ID
from TBL_SERVICE_REGIST_INFO asri
left join TBL_MENU_INFO mi on asri.MENU_ID = mi.ID
where asri.COVERAGE_AREA_ID in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
<select id="selectServiceRegistInfosByIds" resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo" parameterType="java.util.List">
select asri.SERVICE_ID,asri.SERVICE_NAME,asri.COVERAGE_AREA_ID,asri.RIGHT_TYPE,asri.SERVICE_INTRODUCE,asri.SERVICE_ORGANIZATION,
asri.KEY_WORD,asri.SERVICE_TYPE,asri.COORDINATED_SYSTEM,asri.SERVICE_LABEL,asri.RELEASE_TIME,mi.MENU_NAME,asri.SERVICE_PATH,
mi.MENU_NAME,asri.MENU_ID,asri.REFRESH_CYCLE,asri.ACCOUNT_INFO,asri.PROVIDER_COMPANY_ID
from TBL_SERVICE_REGIST_INFO asri
left join TBL_MENU_INFO mi on asri.MENU_ID = mi.ID
where asri.SERVICE_ID in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
<resultMap id="selectServiceRegistInfosByIdsMap"
type="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo" autoMapping="true">
<collection property="menuInfo" ofType="com.iprobeinfo.api.servicemanger.vo.MenuInfo" autoMapping="true">
</collection>
</resultMap>
<select id="selectServiceLabels" resultType="String">
select SERVICE_LABEL
from TBL_SERVICE_REGIST_INFO
</select>
<select id="selectCount" resultType="integer" parameterType="integer">
SELECT COUNT(1)
from TBL_SERVICE_REGIST_INFO asri
<where>
<if test="coverageAreaIds != null and coverageAreaIds != ''" >
asri.COVERAGE_AREA_ID = #{coverageAreaIds, jdbcType=NUMERIC}
</if>
</where>
</select>
<insert id="intoUserCollection" parameterType="com.iprobeinfo.api.servicemanger.vo.UserServiceRegis">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="ID">
-- 设置插入自增主键
SELECT SEQ_CUST_INCOME_REPORT.CURRVAL AS ID from DUAL
</selectKey>
insert into TBL_USER_SERVICEREGIST(ID,USER_ID,SERVICE_REGIST_ID,IS_COLLECTION)
values(SEQ_CUST_INCOME_REPORT.NEXTVAL,#{userId},#{serviceRegistId},1)
</insert>
<select id="getIsCollection" resultType="com.iprobeinfo.api.servicemanger.vo.UserServiceRegis"
parameterType="com.iprobeinfo.api.servicemanger.vo.UserServiceRegis">
select *
from TBL_USER_SERVICEREGIST
where USER_ID = #{userId} and SERVICE_REGIST_ID = #{serviceRegistId}
</select>
<update id="updateUserCollection" parameterType="com.iprobeinfo.api.servicemanger.vo.UserServiceRegis">
update TBL_USER_SERVICEREGIST set IS_COLLECTION = #{isCollection,jdbcType=NUMERIC}
where USER_ID = #{userId ,jdbcType=NUMERIC} and SERVICE_REGIST_ID = #{serviceRegistId,jdbcType=NUMERIC}
</update>
<select id="selectCollectionByUserId" parameterType="com.iprobeinfo.api.servicemanger.vo.UserServiceRegis" resultType="com.iprobeinfo.api.servicemanger.vo.ServiceRegistInfo">
SELECT
asri.SERVICE_ID,
asri.SERVICE_NAME,
asri.COVERAGE_AREA_ID,
asri.RIGHT_TYPE,
asri.SERVICE_INTRODUCE,
asri.SERVICE_ORGANIZATION,
asri.KEY_WORD,
asri.SERVICE_TYPE,
asri.COORDINATED_SYSTEM,
asri.SERVICE_LABEL,
asri.RELEASE_TIME,
asri.SERVICE_PATH,
mi.MENU_NAME,
asri.MENU_ID,
asri.PROVIDER_COMPANY_ID,
IS_COLLECTION
FROM
TBL_SERVICE_REGIST_INFO asri
left join TBL_MENU_INFO mi on asri.MENU_ID = mi.ID
LEFT JOIN TBL_USER_SERVICEREGIST us ON asri.SERVICE_ID = us.service_regist_id
WHERE
us.user_id = #{userId}
and
us.IS_COLLECTION = 1
</select>
</mapper>