1 #和$的区别
#{}表示一个占位符号
- 通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,
- #{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。
- 可以自动对值添加 ’ ’ 单引号
${}表示拼接 sql 串
- 通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,
- ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
- 比如order by id 这种的,以id排序 那么这个id 是没有单引号的,就是简单的SQL拼接,所以我们应该使用${} 而不是#{}
多个参数
当我涉及到多个参数传参的时候,这个时候,我们直接使用变量名会发现控制台有错误提示
Parameter 'XXX' not found. Available parameters are [arg1, arg0, param1, param2]说
这个使用我们也需要通过@Param的注解来解决这个问题
int update(@Param("addr") String addr, @Param("id")int id);
2 paramerterType 和 resultType
paramerterType 参数类型
之所以我们可以直接写类名的原因就是因为这些这些常用类型,mybatis已经帮我们配置好了别名。下图是类型对照说明。
针对于实体类,我们如果也想用简写,就需要我们自己去配置别名了。
resultType 结果集的类型
设置包 下所有实体类的别名,别名就是类名
<package name="com.example.mybatisIone.entity"/>
resultMap 匹配数据规则
多个单词往往是用_连接,但是在实体类中的属性往往采用小驼峰的方式命名。这就导致字段名无法对应上,这个时候我们就需要配置resultMap来解决这个问题了。
通过resultMap,我们可以指定查询结果字段和实体属性字段的映射关系。
<resultMap id="userResult" type="User">
<id column="id" property="id" />
<result property="nickname" column="nickname" />
<result property="schoolName" column="school_name" />
property 对应的是实体类 column 对应的是数据库
</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 映射文件名称相同,且放在同一个目录中,这里如果希望能够扫描到包下面的xml文件的话,需要在maven中进行配置。
-
package 注册指定包下的所有 mapper 接口如:
<package name="com.tledu.zrz.mapper"/>
需要在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>
id= 方法名
parameterType=方法返回的实体类
resultMap=结果集
where 标签解决了两个问题
解决了两个问题
1.去掉第一个遇到的and
2.当where标签内为空时,会自动去掉自己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标签解决了一个问题带来一个问题
解决问题
1.set标签帮咱们去掉了最后一个,
带来了一个问题
1.当标签内部为空时,把自己去掉了,带来了语法错误
<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
属性说明
- collection 需要遍历的列表
- item 每一项的形参名
- index 每一项索引名
- separtor 分隔符
- open 开始符号
- close 关闭符号
<insert id="insertB" parameterType="Address">
insert into t_address(addr,phone,postcode)values
<foreach collection="addressList" item="eve" index="index" separator=",">
(#{eve.addr},#{eve.phone},#{eve.postcode})
</foreach>
</insert>
使用foreach批量添加代码如下
<insert id="insertB" parameterType="Address">
insert into t_address(addr,phone,postcode)values
<foreach collection="addressList" item="eve" index="index" separator=",">
(#{eve.addr},#{eve.phone},#{eve.postcode})
</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="adderandmap" type="AdderAndUser" autoMapping="true">
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
<association property="user" javaType="User" autoMapping="true">
</association>
</resultMap>
第三种:嵌套的resultType
<!-- //第三种实现方法-->
<resultMap id="adderandmap2" type="AdderAndUser" autoMapping="true">
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
<association property="user" javaType="User" autoMapping="true" resultMap="qwe"/>
</resultMap>
<resultMap id="qwe" type="User" autoMapping="true">
</resultMap>