mybatis知识点
1.#和$的区别
1.1.#{} 表示一个占位符号
#{}是预解析,可以放置sql注入
- 通过 #{} 可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换
- #{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值
- 可以自动对值添加 ‘’ 单引号
1.2.${} 表示拼接 sql 字符串
${}是字符串拼接,可能会有sql注入
- 通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换
- ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value
- 比如order by id 这种的,以id排序 那么这个id 是没有单引号的,就是简单的SQL拼接,所以我们应该使用${} 而不是#{},因为#{}会自动添加单引号使值变为字符串
- 注:一般我们获取变量值的时候使用#{}来读取属性,如果需要进行sql拼接的时候可以使用${},使用${}的时候要注意防止sql注入
2.多个参数
- 当我们想要传递多个参数的时候可以给变量添加 @Param 单个参数也可以加,例:
// 在传参的时候用@Param("别名"),如果传参是对象类型则不需要
Address getAddrById(@Param("id") int id);
- 如果使用的是包装类,或其他非基本数据类型,有时候也需要使用@Param
3.resultMap
如果实体类属性和数据库列名不同则需要写resultMap
<resultMap id="AddressResultMap" type="Address"><!-- autoMapping="true" 当其他值不能自动注入需要设置 -->
<!-- 标明主键-->
<id column="id" property="id"/>
<!-- 当实体类属性和数据库列名不同时需要写,因为不写就无法读到数据-->
<result column="user_id" property="userId"/>
</resultMap>
此时sql的返回值应是resultMap="resultMap的id值"
,而不是resultType
4.mybatis-config.xml 文件配置
- typeAliases配置
<!-- 设置别名,然后就可以使用别名来代替前面的路径 -->
<typeAliases>
<!-- 单个设置-->
<!-- <typeAlias type="com.tledu.Practice_29.entity.User" alias="User"/>-->
<!-- <typeAlias type="com.tledu.Practice_29.entity.Address" alias="Address"/>-->
<!-- 批量设置 该包下所有类都有别名,首字母大小写都可以-->
<package name="com.tledu.Practice_29.entity"/>
</typeAliases>
- mapper配置,前提:接口和xml文件必须放在同一目录下
<mappers>
<!-- 第一种sqlSession的方式-->
<!-- <mapper resource="mapper/User.xml"/>-->
<!-- 第二种注解的方式-->
<!-- <package name="com.tledu.Practice_29.mapper"/>-->
<!-- 第三种接口代理的方式-->
<!-- <mapper resource="mapper/User.xml"/>-->
<!-- <mapper resource="mapper/Address.xml"/>-->
<!-- <mapper class="com.tledu.Practice_29.mapper.IAddressMapper"/>-->
<!-- 批量配置mapper -->
<package name="com.tledu.Practice_29.mapper"/>
</mappers>
- Java目录下 .xml 和 .properties 文件想要参与编译必须在pom.xml例添加
<resources>
<resource>
<!-- directory:指定资源文件的位置 -->
<directory>src/main/java</directory>
<includes>
<!-- “**” 表示任意级目录 “*”表示任意任意文件 -->
<!-- mvn resources:resources :对资源做出处理,先于compile阶段 -->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!-- filtering:开启过滤,用指定的参数替换directory下的文件中的参数(eg. ${name}) -->
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
5.动态sql
5.1.if 和 where 用法
<select id="getAddrByDynamic" parameterType="Address" resultMap="AddressResultMap">
select * from t_address
<where>
<if test="addr!=null">
and addr=#{addr}
</if>
<if test="phone!=null">
and phone=#{phone}
</if>
<if test="postcode!=null">
and postcode=#{postcode}
</if>
<if test="userId!=null">
and user_id=#{userId}
</if>
</where>
</select>
- if
- if 标签中的条件满足时会自动拼接标签内的 sql 语句
- where
- 可以自动去掉第一个连接符 (and / or )
- 当where 中为空时,where 标签自动删除
5.2.set 标签用法
<update id="updateAddrByDynamic" parameterType="Address">
update t_address
<set>
<if test="addr!=null">
addr=#{addr},
</if>
<if test="phone!=null">
phone=#{phone},
</if>
<if test="postcode!=null">
postcode=#{postcode},
</if>
<if test="userId!=null">
user_id=#{userId},
</if>
</set>
where id=#{id}
</update>
- set
- set标签会自动去掉最后一个逗号
- 当set标签中的内容为空时,set标签也会自动删除,不过此时就会导致sql语法错误,可以通过添加判断条件防止该错误出现
6.批量操作
- foreach
- collection:被循环的列表
- separator:分隔符
- item:每一项
- index:索引
- open:再循环最开始拼接的
- close:再循环最末尾拼接的
6.1.批量拼接
<!-- 第一种-->
<!-- <insert id="addUserBatch" parameterType="User">-->
<!-- insert into t_user (username,password,nickname,type) values-->
<!-- <foreach collection="list" separator="," item="every">-->
<!-- (#{every.username},#{every.password},#{every.nickname},#{every.type})-->
<!-- </foreach>-->
<!-- </insert>-->
<!-- 第二种-->
<!-- 需要用@Param起名字和collection对应-->
<insert id="addAddrBatch" parameterType="Address">
insert into t_address(addr,phone,postcode,user_id) values
<foreach collection="list" separator="," item="every">
(#{every.addr},#{every.phone},#{every.postcode},#{every.userId})
</foreach>
- 当传递参数是 list列表类型 时,就需要用到批量操作,建议使用第一种
- 因为当 parameterType=“User”,User就是List<User>中的泛型User,foreach中的collection的属性就可以写list类型 collection=“list”
- 若 parameterType=“list” 那么foreach中的collection的属性就需要 用@Param起名字和collection的值对应,@Param就是接口中定义的方法所传递的参数的别名
6.2.批量删除
<delete id="deleteAddrBatch" parameterType="list">
delete from t_address where id in
<foreach collection="addressList" separator="," item="eve" open="(" close=")">
#{eve}
</foreach>
</delete>
注:
如果item的值存储的是一个对象的话,需要用 #{item的值.属性名}获取对应的值,例: #{every.addr}
如果item的值存储的只是一个值的话,就只需要用 #{item的值}获取对应的值即可,例:#{eve}