mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 为JavaBean起类别名 -->
<typeAliases>
<package name="com.xxx.model" />
</typeAliases>
<!-- 通过 mapper 接口包加载整个包的映射文件 -->
<mappers>
<package name="com/xxx/mapper" />
</mappers>
</configuration>
1、mybatis别名配置typeAliases
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
在configuration配置即可;
2、映射器mappers
需要配置mybatisa在哪里找映射文件;
第一种类路径的资源引用
<mapper resource="com/entity/UserMapper.xml"/>
第二种直接给出本地地址形式的,自己存放的地址,完全限定资源定位符
<mapper url="file:///var/mappers/UserMapper.xml"/>
第三种以类的形式去寻找
<mapper class="com.entity.AuthorMapper"/>
第四种包名的形式
<package name="com.entity.builder"/>
3、映射配置细节
resultMap和resultType
esultMap支持继承:extends=”User”说明继承了上一个resultMap,要是一个实体类很重的话,先给出一个框架大家都继承与他,是不错的选择.另外注意:ofType指定的是映射到list集合属性中pojo的类型
<!--多对多关联查询 -->
<resultMap id="User" type="com.entity.User">
<result property="id" column="id" />
<result property="username" column="username" />
<result property="password" column="password" />
</resultMap>
<resultMap id="user_info" type="User" extends="User">
<collection property="userInfos" ofType="com.entity.UserInfo"
column="uid">
<result property="id" column="id" />
<result property="address" column="address" />
</collection>
</resultMap>
<select id="getUser" resultMap="user_info">
select * from user u,userinfo i
where u.id=i.uid and u.id=#{id}
</select>
4、动态SQL语句完成多条件查询
if choose where set foreach
(1)If
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
(2)Choose
<select id="queryEmp" resultType="cn.test.entity.Emp">
select * from emp where 1=1
<choose>
<when test="deptNo!=null">
and deptno=#{deptNo}
</when>
<when test="deptName!=null">
and deptname=#{deptName}
</when>
<otherwise>
and personnum>#{personNum}
</otherwise>
</choose>
</select>
上面也说了,choose相当于Java中的switch语句;当第一个when满足时;就只执行第一个when中的条件。当when中的条件都不满足时;就会执行默认的的;也就是otherwise中的语句。
(3)Where
<select id="getU" resultMap="User" parameterType="com.entity.User">
select*from user
<where>
<if test="username!=null and username!=''">
username like concat('%',#{username},'%')
</if>
<if test="id!=null">
and id=#{id}
</if>
</where>
</select>
where下面第一个if语句中以and开头,也可以省略第一个and ,如果第一个if语句中有and;mybatis会将第一个and忽略。
(4)Set
<update id="updateEmp" parameterType="cn.test.entity.Emp" flushCache="true">
update emp
<set>
<if test="empName!=null">empname=#{empName},</if>
<if test="job!=null">job=#{job}</if>
</set>
where empno=#{empNo}
</update>
在mybatis中的SQL语句结尾不能加“;”,这样会导致mybatis无法识别字符;导致SQL语句的语法错误;
(5)Foreach
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 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>
foreach 元素的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串以及在迭代中间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。
<trim prefix = “” suffix=”” suffixOverrides=”” prefixOverrides=””></trim>
prefix:在trim标签内sql语句加上前缀
suffix: 在trim标签内sql语句加上后缀
SuffixOverrides: 去除指定多余的后缀内容
<!-- 查询学生list,like姓名、或=性别、或=生日、或=班级,使用choose -->
<select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">
SELECT * from STUDENT_TBL ST
<where>
<choose>
<when test="studentName!=null and studentName!='' ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')
</when>
<when test="studentSex!= null and studentSex!= '' ">
AND ST.STUDENT_SEX = #{studentSex}
</when>
<when test="studentBirthday!=null">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday}
</when>
<when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">
AND ST.CLASS_ID = #{classEntity.classID}
</when>
<otherwise>
</otherwise>
</choose>
</where>
</select>
5、mybatis中#和$的区别
#相当于对数据加上双引号 $相当于直接显示数据
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
6、mybatis中模糊查询
在oracle
like '%'||#{username}||'%'
在mysql
like concat(concat('%',#{username}),'%')
7、mybatis xml中的大于、小于的写法,like模糊查询的写法
xml特殊符号转义写法
< <
> >
<> <>
& &
' '
" "
也可以使用<![CDATA[ ]]>符号进行说明,将此类符号不进行解析
<![CDATA[ 这里写你的sql ]]>
mysql like的写法
like concat('%',#{param},'%') 或者 like '%${param}%' ,推荐使用前者,可以避免sql注入。
9、Mybatis一对一,一对多
association collection
10.mybatis缓存
mybatis 一级缓存:一个namespace下的sql,先查询了,在如果执行了修改就会让之前的查询失效
二级缓存:在多个namespace 下实现了缓存数据共享, 如果多个sqlSession查询同一语句,不在同一namespace的情况下,会在二级缓存中读取数据,如果涉及到多表查询,可能会有脏数据的情况。