#和$的区别
#{}表示一个占位符号
-
通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,
-
#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。
-
可以自动对值添加 ’ ’ 单引号
${}表示拼接 sql 串
-
通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,
-
${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
-
比如order by id 这种的,以id排序 那么这个id 是没有单引号的,就是简单的SQL拼接,所以我们应该使用${} 而不是#{}
多个参数
当我们有多个变量的时候,我们就需要通过arg0,arg1来获取对应的变量了
// 接口方法
int updateNickname( @Param("id") int id,@Param("nickname")String nickname);
<update id="updateNickname">
update t_user set nickname = #{nickname} where id = #{id}
</update>
paramerterType 和 resultType
paramerterType
使用paramerterType可以设置传参类型
<select id="search" parameterType="int" resultType="Address">
select *
from t_address
where id = #{id}
</select>
resultType
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。
需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。
resultMap
<resultMap id="address" type="Address">
<result column="user_id" property="userId"></result>
<result column="ph" property="phone"/>
</resultMap>
实体中的属性必须和查询语句中的属性对应上,但是我们在开发的过程中也难免会遇到无法对应的情况。比如说我们在进行数据库设计的时候,多个单词往往是用_连接,但是在实体类中的属性往往采用小驼峰的方式命名。这就导致字段名无法对应上,这个时候我们就需要配置resultMap来解决这个问题了。
通过resultMap,我们可以指定查询结果字段和实体属性字段的映射关系
mybatis-config.xml 中mappers标签中的mapper
-
Resource 使用相对于类路径的资源如:<mapper resource="com/tledu/zrz/dao/IUserDao.xml" />
-
class 使用 mapper 接口类路径如:
<mapper class="com.tledu.zrz.dao.UserDao"/>
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
-
package 注册指定包下的所有 mapper 接口如:
<package name="com.tledu.zrz.mapper"/>
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中,并且这里如果希望能够扫描到包下面的xml文件的话,需要在maven中进行配置。
配置如下
<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>
动态sql
if
<select id="list" parameterType="User" resultMap="userResult">
select * from t_user where 1=1
<if test="username != null and username != ''">
and username = #{username}
</if>
<if test="nickname != null and nickname != ''">
and nickname like concat('%',#{nickname},'%')
</if>
</select>
choose、when、otherwise
<select id="list" parameterType="User" resultMap="userResult">
select * from t_user where 1=1
<choose>
<when test="id != null">
and id = #{id}
</when>
<when test="username != null and username != ''">
and username = #{username}
</when>
<otherwise>
and nickname = #{nickname}
</otherwise>
</choose>
</select>
where
<select id="list" parameterType="User" resultMap="userResult">
select * from t_user
<where>
<if test="username != null and username != ''">
and username = #{username}
</if>
<if test="nickname != null and nickname != ''">
and nickname like concat('%',#{nickname},'%')
</if>
</where>
</select>
set
<update id="updateNickname">
update t_user
<set>
<if test="nickname != null and nickname != ''">
nickname = #{nickname},
</if>
<if test="username != null and username != ''">
username = #{username},
</if>
</set>
where id = #{id}
</update>
foreach
<insert id="batchInsert">
insert into t_user (username, password, nickname) VALUES
<foreach collection="list" index="idx" item="item" separator=",">
(#{item.username},#{item.password},#{item.nickname})
</foreach>
</insert>
in 查询
<select id="list" parameterType="User" resultMap="userResult">
select * from t_user
<where>
<if test="user.username != null and user.username != ''">
and username = #{user.username}
</if>
<if test="user.nickname != null and user.nickname != ''">
and nickname like concat('%',#{user.nickname},'%')
</if>
and id in
<foreach collection="idList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</where>
</select>
联查
在项目中,某些实体类之间肯定有关联关系,比如一对一,一对多等,在mybatis 中可以通过association和collection,来处理这些关联关系。
1 对 1 关系
在实现1对1映射的时候,可以通过association属性进行设置。在这里有三种方式
在地址表中,每个地址对应有一个创建用户,每次查询地址的时候希望查询到创建用户的内容
第一种:使用select
<resultMap id="address" type="Address">
<id column="id" property="id" />
<association property="user" column="user_id" javaType="User" select="com.tledu.erp.dao.IUser2Dao.selectById"/>
</resultMap>
第二种:直接进行联查,在association中配置映射字段
<resultMap id="address" type="Address" autoMapping="true">
<id column="id" property="id" />
<association property="user" column="user_id" javaType="User" >
<id column="user_id" property="id" />
<result column="school_name" property="schoolName" />
</association>
</resultMap>
<select id="selectOne" resultMap="address">
select * from t_address left join t_user tu on tu.id = t_address.user_id where t_address.id = #{id}
</select>
第三种:嵌套的resultType
<resultMap id="addressMap" type="Address" autoMapping="true">
<id column="id" property="id"/>
<association property="user" column="user_id" resultMap="userMap">
</association>
</resultMap>
<resultMap id="userMap" type="User" autoMapping="true">
<id column="user_id" property="id" />
<result column="school_name" property="schoolName"/>
</resultMap>
<select id="selectOne" resultMap="addressMap">
select t_address.id,
addr,
phone,
postcode,
user_id,
username,
password,
nickname,
age,
sex,
school_name
from t_address
left join t_user tu on tu.id = t_address.user_id
where t_address.id = #{id}
</select>