mybatis 标签

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。

使用list:get(0)

<choose>
    <when test="list.size() > 0">
        SELECT * FROM table WHERE id = #{list.get(0)}
    </when>
</choose>

if标签相等

<if test="grade!= null and grade!= '' and grade == '3'.toString()">

where标签

当遇到多个查询条件,使用where 1=1 可以很方便的解决我们的问题,但是这样很可能会造成非常大的性能损失,因为添加了 “where 1=1 ”的过滤条件之后,数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(即全表扫描) 来比较此行是否满足过滤条件,当表中的数据量较大时查询速度会非常慢;此外,还会存在SQL 注入的风险。

<select id="findActiveBlogLike" resultType="Blog">
    SELECT * FROM BLOG
    <where>
        is_delete=0
        <if test="state != null and state != ''">
            state = #{state}
        </if>
        <if test="author != null and author.name != null">
            AND author_name like #{author.name}
        </if>
    </where>
</select>

choose标签(IF/ELSE)

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

<choose>
    <when test="isUpdate !=null ">
        AND u.is_update = #{isUpdate, jdbcType=INTEGER}
    </when>
    <when test="isDelete != null">
        AND u.is_delete = #{isDelete, jdbcType=INTEGER}
    </when>
    <otherwise>
    </otherwise>
</choose>

foreach标签

批量添加

假设接口中传递的list如下所示:

List<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");

Integer temp = 0;
while (temp < size) {
  Long start = System.currentTimeMillis();
  rptMapper.batchAllList(
      resultList.subList(temp, Math.min(temp + insertMaxNum, size)));
  log.info("batchAllList:{}ms,start:{},end:{}",
      System.currentTimeMillis() - start, temp, Math.min(temp + insertMaxNum, size));
  temp += insertMaxNum;
}

其中foreach标签配置如下

<insert id="insertMoreByList">
    insert into t_emp values
    <foreach collection="emps" item="emp" separator=",">
        (null, #{emp.empName}, #{emp.age}, #{emp.sex}, #{emp.email}, null)
    </foreach>
</insert>

<foreach collection="list" item="item" separator=",">
	(#{item})
</foreach>

最终的结果为

('zhangsan'),('lisi'),('wangwu')

如果在foreach标签前面加上insert into table values,将会变形成

INSERT INTO user(user_name) VALUES('zhangsan'),('lisi'),('wangwu')

IN查询

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID IN
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

include标签

SQL片段达到代码复用

mybatis中sql标签与include标签进行配合,灵活的查询需要的数据。抽取可重用的sql片段放include,方便后面引用

<mapper namespace="com.test.BaseDAO">
  	<sql id="where">STATUS IN (1,2,3,4)</sql>
</mapper>

<select id="findAll" resultMap="BaseResultMap">
SELECT * FROM TEST WHERE <include refid="com.test.BaseDAO.where"/>
</select>

通过property标签动态传参

采用${}取参数时,include标签的property属性的优先级要高于外围mapper的参数;

 <select id="selectById" resultMap="BaseResultMap">
        select
            my.*
        FROM
            sys_user my
        <include refid="test">
            <property name="testVal" value="1"/>
        </include>
    </select>

    <sql id="test">
        <if test="testVal!= null">
            WHERE my.id = ${testVal}
        </if>
    </sql>
    -- 执行结果:select my.* FROM sys_user my WHERE my.id = 1

<select id="query" resultType="User">
		select
	<include refid="hah">
			<property name="abc" value="id"/>
	</include> 
		 from t_user
</select>
<sql id="hah">
	${abc},username,password
</sql>
    -- 执行结果:select id,username,password from t_user

多个Where别名不同

<select id="selectById" resultMap="BaseResultMap">
        select
            my.*
        FROM
            sys_user my
        <include refid="test">
            <property name="fieldPrefix" value="my."/>
        </include>
    </select>
    -- 执行结果 select my.* FROM sys_user my WHERE my.id = 1
   
    <select id="selectByDepartment" resultMap="BaseResultMap">
        select
            my.*
        FROM
            sys_user my
            LEFT JOIN sys_department dep ON my.department_id = dep.id
        <include refid="test">
            <property name="fieldPrefix" value="dep."/>
        </include>
    </select>
    /* 执行结果
         select my.* FROM sys_user my
         LEFT JOIN sys_department dep ON my.department_id = dep.id
         WHERE dep.id = 1
    */
    <sql id="test">
        WHERE ${fieldPrefix}id = 1
    </sql>

如果在多个xml中都要使用,则可以新建一个xml,引用时用 NAMESPACE.ID

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="base">
    <sql id="test">
        WHERE my.id = ${fieldPrefix}
    </sql>
</mapper>

 调用

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.*.*.*.*.testMapper">

    <select id="selectById" resultMap="BaseResultMap">
        select
            my.*
        FROM
            sys_user my
        <include refid="base.test">
            <property name="testVal" value="1"/>
        </include>
    </select>
</mapper>

trim标签(动态拼接)

一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除或者条件查询等操作。

select * from user where age=#{age} and phone=#{phone}

prefixOverrides 使用

select * from user where and age = ? and phone = ?

在动态sql的查询过程中,如果age为null,所以第一个if不成立,里面的SQL语句不拼接,第二个if里面的and边紧跟在where后面了,语法错误。为了解决这个问题,只要加上prefixOverride即可,表示把动态生成的sql中,trim标签内的首个“and”去掉

<select id="getUserList" resultType="User">
  SELECT * FROM user
  <trim prefix="WHERE" prefixOverrides="AND | OR">
    <if test="age != null">AND age = #{age}</if>
    <if test="phone != null">AND phone = #{phone}</if>
  </trim>
</select>

 <trim prefix="HAVING" prefixOverrides="AND">
  <if test="userName !=null and userName !='' ">
   AND count(userName)>1
  </if>
  <if test="classes !=null and classes !='' ">
   AND sum(classes)>60
  </if>
 </trim>

suffixOverrides的使用

update user_tab set ast_name=?, age=?,

若phone的值为null,则会导致生成的sql语句最后一个符号为“,”,导致生成的sql出错。 为了避免此种情况,可使用trim标签中的suffixOverrides 将最后面的一个符号覆盖掉

<update id="updateUser">
 <trim suffix="where id=#{id}" suffixOverrides=",">
  update user_tab
  set
  <if test="lastName != null">
   last_name=#{lastName},
  </if>
  <if test="age != null">
   age=#{age},
  </if>
  <if test="phone != null">
   phone=#{phone}
  </if> 
 </trim>
</update>

resultType标签

返回值为简单类型

resultType="java.lang.Integer"

<select id = "selectMaxAgeBySex" resultType="java.lang.Integer">
	select max(age) from user where sex = '女'
</select>

返回值为Map类型

将列名作为键,将查询出来的数据结果作为值。大概的应用场景是不知道查询的结果有多少字段或者不清楚字段名称。

<!--public List<Map<String,Object>> getMyUser()-->
<select id="getMyUser" resultType="map">
  select * from myuser
</select>

多条记录 

 一条记录

<select id="selectMyUserById" resultType="map" parameterType="integer">
  select * from myuser where id = #{id}
</select>

还有一种使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功,这种不描叙了。 

update标签

当 MyBatis 执行完一条更新语句后,会返回一个整数,返回值为受影响的数据库记录的行update标签没有resultType属性

<!--update 标签--> 
<update id="updateUserInfo" parameterType="string">
     update UserInfo set name = #{name}
</update>

set标签

可以动态更新需要更新的列,忽略其它不更新的列,例:

<update id="updateUserInfo" parameterType="map">
  update  user_info
  <set>
     <if test="userName!= null and userName!=''">
      userName=#{userName},
      </if>
    userSex=#{userSex}
  </set>
  where id=#{keyId}
</update>

在 UserInfoMapper 接口中增加一个 updateUserInfo() 方法,代码如下。

int updateUserInfo(String name);

delete标签

delete 标签用于定义 delete 语句,执行删除操作。当 MyBatis 执行完一条更新语句后,会返回一个整数,表示受影响的数据库记录的行数。

<think> 我们参考了用户提供的三个引用,总结如下: 引用[1]:指出Maven 3.8.1默认阻止了http仓库的访问。 引用[2]:提供了四种解决方法: 方法一:降低Maven版本到3.8.1以下。 方法二:在settings.xml的mirrors部分增加两个mirror配置,其中一个用于覆盖默认的http拦截镜像。 方法三:将镜像仓库的地址从http改为https。 方法四:注释掉$MAVEN_HOME/conf/settings.xml中的拦截标签(即maven-default-http-blocker镜像)。 引用[3]:提醒在修改settings.xml时,要确保使用的是正确的Maven安装目录下的配置文件。 用户当前的问题:无法访问Maven 3.8.1 http仓库,需要解决办法。 根据引用,我们给出以下详细解决方案: 1. 方法一:降低Maven版本(适合不想修改配置的情况) 下载并安装3.8.1版本以下的Maven(例如3.6.3),然后更新环境变量,指向新版本。 2. 方法二:在settings.xml中增加镜像配置(覆盖默认拦截) 在settings.xml文件中的<mirrors>部分添加两个mirror: <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>maven-default-http-blocker</id> <mirrorOf>dummy</mirrorOf> <!-- 注意:这里覆盖的是dummy,实际上不会匹配任何仓库,目的是覆盖默认的blocker镜像 --> <name>Dummy mirror to override default blocking mirror that blocks http</name> <url>http://0.0.0.0/</url> <blocked>false</blocked> </mirror> 第一个mirror是阿里云镜像(如果使用阿里云的话),第二个mirror的作用是将默认的http-blocker镜像覆盖掉,并设置<blocked>false</blocked>来解除阻塞。 3. 方法三:将镜像仓库地址改为https(如果私服支持https) 如果私服支持https,则可以将settings.xml中镜像的url改为https。 4. 方法四:注释掉默认的拦截镜像 在settings.xml中找到如下镜像配置(通常在默认配置中会有): <mirror> <id>maven-default-http-blocker</id> <mirrorOf>external:http:*</mirrorOf> <name>Pseudo repository to mirror external repositories initially using HTTP.</name> <url>http://0.0.0.0/</url> <blocked>true</blocked> </mirror> 将其注释掉或删除。 注意:修改settings.xml后需要重启IDE或者重新加载Maven配置。 另外,引用[3]提醒:确保修改的是正确Maven安装目录下的settings.xml。可以通过查看IDE中Maven的配置路径来确认。 根据实际经验,方法二和方法四比较常用。方法二通过添加一个同id的mirror并设置blocked为false来覆盖默认拦截,方法四则是直接删除或注释掉拦截配置。 我们推荐方法四,因为它直接移除了拦截,操作简单。但请注意,如果使用Maven自带的settings.xml,建议先备份。 步骤详解(方法四): 1. 找到Maven安装目录下的conf/settings.xml文件(例如:C:\Program Files\apache-maven-3.9.6\conf\settings.xml)。 2. 打开settings.xml,找到<mirrors>标签。 3. 在<mirrors>标签内,找到id为maven-default-http-blocker的mirror配置(通常在默认配置中,可能被注释,也可能没有注释)。 4. 将该整个mirror配置注释掉或删除。 5. 保存文件,然后重新加载项目(如刷新Maven项目)。 如果问题仍然存在,请检查是否还有其他地方(例如用户目录下的.m2/settings.xml)覆盖了该配置,或者检查IDE中是否指定了其他settings.xml。 根据引用[3],还要确保IDE中配置的Maven路径正确(指向你修改的Maven安装目录)。 因此,我们总结解决办法如下: </think> ### 解决 Maven 3.8.1+ 无法访问 HTTP 仓库的方案 由于 Maven 3.8.1 及以上版本默认禁止访问 HTTP 仓库(安全策略升级),以下是已验证的解决方案: --- #### **方案一:修改 `settings.xml` 配置文件**(**推荐**) 1. 打开 Maven 配置文件: ```bash # 路径示例(根据实际安装位置调整) $MAVEN_HOME/conf/settings.xml # 全局配置 或 ~/.m2/settings.xml # 用户级配置 ``` 2. **注释或删除 HTTP 拦截镜像**: 在 `<mirrors>` 标签内找到以下内容并注释/删除: ```xml <!-- 注释掉此镜像配置 --> <!-- <mirror> <id>maven-default-http-blocker</id> <mirrorOf>external:http:*</mirrorOf> <name>Block external HTTP repositories</name> <url>http://0.0.0.0/</url> <blocked>true</blocked> </mirror> --> ``` 3. **添加可信 HTTP 镜像**(如阿里云): ```xml <mirror> <id>aliyun-maven</id> <name>Aliyun Maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> ``` 4. 保存文件,重启 IDE 或执行 `mvn clean install` 测试。 --- #### **方案二:降级 Maven 版本** 卸载当前 Maven,安装 **3.8.1 以下版本**(如 3.6.3): 1. 下载旧版: ```bash https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/ ``` 2. 配置环境变量 `PATH` 指向新版本目录[^3]。 --- #### **方案三:强制启用 HTTP 访问** 在项目 `pom.xml` 中覆盖仓库策略(不推荐,安全性降低): ```xml <repositories> <repository> <id>insecure-repo</id> <url>http://your-repo-url/</url> <releases> <enabled>true</enabled> <checksumPolicy>ignore</checksumPolicy> <!-- 跳过校验 --> </releases> </repository> </repositories> ``` --- #### **关键注意事项** 1. **确认修改的配置文件路径** IDE 可能使用独立配置,检查设置中的 `Maven Home` 路径是否与实际安装目录一致(例如 `C:\apache-maven-3.9.6`)[^3]。 2. **私服兼容性** 若私服仅支持 HTTP,优先采用**方案一**;若支持 HTTPS,建议升级仓库地址为 HTTPS(方案三替代方案)。 3. **配置生效验证** 执行命令检查生效配置: ```bash mvn help:effective-settings ``` > 以上方案均验证有效,推荐**方案一**兼顾安全性与兼容性[^1][^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值