1.#和$的区别
#{}表示一个占位符号,可以防止sql注入
${}表示拼接 sql 串,可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换
当涉及到多个参数的时候,就可以使用注解的方式(@Param)来进行解决,如果参数的类型是String或者是类似于User实体类的时候,也需要用到注解
2.parameterType和resultType
2.1 parameter
SQL 语句传参,使用标签的 parameterType 属性来设定,该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类),基本类型和String我们直接写类名,或者包名.类名的方式,实体类我们也可以设置别名后,直接写类名
2.2 resultType
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型,如果我们设置过别名,可以直接写类名,如果没有设置,则必须写全限定类名,如果是实体类,实体类中的属性名称必须和查询语句的列名一致
2.3 resultMap
我们在进行数据库设计时,多个单词之间通常使用下划线进行链接,但是在实体类中的属性,我们一般用小驼峰命名法则,这会导致字段名无法对应,在这种情况下,我们就可以使用resultMap来指定查询结果字段和实体属性字段之间的对应关系
3.mybatis-config.xml 配置文件(其中包括两种方法)
3.1.1 直接配置属性
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
3.1.2 读取配置文件,创建db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/erp16?useUnicode=true&characterEncoding=UTF-8
username=root
password=root
配置文件读取
<properties resource="db.properties" />
3.2 typeAliases属性
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="com.tledu.zrz.pojo.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="com.tledu.zrz.pojo"/>
<package name="其它包"/>
</typeAliases>
3.3 mapper属性
mappers是映射器,通过Mybatis配置文件找到对应的mapper文件
3.3.1 resource
使用相对于类路径的资源
例如
<mapper resource="com/tledu/zrz/dao/IUserDao.xml" />
3.3.2 class
使用 mapper 接口类路径(此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中)
例如
<mapper class="com.tledu.zrz.dao.UserDao"/>
3.3.3 package
注册指定包下的所有 mapper 接口(此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中,并且这里如果希望能够扫描到包下面的xml文件的话,需要在maven中进行配置)
例如
<package name="com.tledu.zrz.mapper"/>
4. 动态SQL
4.1 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>
4.2 choose when otherwise
类似于java中的switch case default
<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>
4.3 where
在where条件不确定的时候,需要添加1=1才能确保拼接不出现错误,但是使用where标签之后,就不会出现这个问题了,直接添加条件就可以了,where标签使得代码更具语义化,更容易维护
<select id="list" parameterType="User" resultMap="userResult">
select * from t_user where
<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>
4.4 set
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>
4.5 foreach
批量操作的时候,我们使用foreach进行循环操作,如批量插入insert(foreach),批量删除delete(foreach in)
<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>
5. 联查
实体类之间肯定有关联关系,比如一对一,一对多等,在mybatis 中可以通过association和collection,来处理这些关联关系。
5.1 一对一
在实现1对1映射的时候,可以通过association属性进行设置
5.1.1 select
property配置了实体类对应的属性
column配置了关联字段
select对应了IUser2Dao中的查询语句
<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>
5.1.2 直接联查,在association中配置映射字段
autoType代表自动封装,如果不填写,则需要添加所有的对应关系
<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>
5.1.3 嵌套的resultType
通过这种方式可以多次引用userMap
<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>
5.2 一对多
5.2.1 select
在AddressDao中添加和在UserDao中添加
<select id="selectByUserId" resultType="Address">
select * from t_address where user_id = #{userId}
</select>
<resultMap id="userResult" type="User" autoMapping="true">
<id column="id" property="id"/>
<result property="nickname" column="nickname"/>
<result property="schoolName" column="school_name"/>
<collection property="addressList" column="id" autoMapping="true" select="com.tledu.erp.dao.IAddressDao.selectByUserId" >
</collection>
</resultMap>
<select id="selectById" parameterType="int" resultMap="userResult">
select *
from t_user
where id = #{id}
</select>
5.2.2 直接联查,在collection中配置映射字段
autoMapping代表自动封装,如果不填写,则需要添加所有的对应关系,在这里还需要配置ofType指定返回值类型
<resultMap id="userResult" type="User" autoMapping="true">
<id column="id" property="id"/>
<result property="nickname" column="nickname"/>
<result property="schoolName" column="school_name"/>
<collection property="addressList" column="phone" ofType="Address" autoMapping="true">
<id column="address_id" property="id" />
</collection>
</resultMap>
<select id="selectById" parameterType="int" resultMap="userResult">
select tu.id,
username,
password,
nickname,
age,
sex,
school_name,
ta.id as address_id,
addr,
phone,
postcode,
user_id
from t_user tu
left join t_address ta on tu.id = ta.user_id
where tu.id = #{id}
</select>
5.2.3 嵌套的resultType
<resultMap id="userResult" type="User" autoMapping="true">
<!-- <id column="id" property="id"/>-->
<result property="nickname" column="nickname"/>
<result property="schoolName" column="school_name"/>
<collection property="addressList" column="phone" ofType="Address" resultMap="addressResultMap" autoMapping="true">
</collection>
</resultMap>
<resultMap id="addressResultMap" type="Address" autoMapping="true">
<id column="address_id" property="id" />
</resultMap>
<select id="selectById" parameterType="int" resultMap="userResult">
select tu.id,
username,
password,
nickname,
age,
sex,
school_name,
ta.id as address_id,
addr,
phone,
postcode,
user_id
from t_user tu
left join t_address ta on tu.id = ta.user_id
where tu.id = #{id}
</select>