一、实现动态sql语句用法
- 本文讲解 MyBatis
四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 - MyBatis
作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper。可以说,了解了这四大核心,便可知
MyBatis 八九。
(一)采用mybatis的配置文件方式
- 通过If判断时, 注意要做不等于空字符串校验。
<if test="name!=null and name!=''">
name,
</if>
另外:sex,age等不是字符串的,不用判断不为空。
<if test="sex!=null">
sex,
</if>
- 与where标签配合:where标签:该标签包含的元素内有返回值,就插入一个where。如果where后面的字符串是以and和or开头,就将他们自动剔除。
<!-- 根据参数(条件)查询-->
<select id="queryByParam" resultType="User">
<!-- select * from user where 1=1 恒成立,解决下面不管执行那个条件都成立-->
select * from user
<!-- where标签会自动去掉多余的and ,or-->
<where> <!-- 与查询时搭配使用我们where的sql语句的‘,’的最后一列会被自动省略 -->
<if test="name!=null and name!=''"> <!--查询时可以判断name是否是空的如果不为空就把数据库中这一列的值更改掉 如果为空就不修改数据库这一列的值也不会为Null-->
<!--方式一:直接用${}拼接参数,有sql注入攻击风险 -->
<!-- name like '%${name}%'-->
<!-- 方式二:使用sql系统函数concat拼接字符串-->
and name like concat('%',#{name},'%')
<!--方式三在调用的时候参数两侧加%号 ,不推荐-->
<!-- name like '%${name}%'-->
</if>
<if test="username!=null and username!=''">
and username like concat('%',#{username},'%')
</if>
<if test="sex!=null">
and sex =#{sex}
</if>
</where>
</select>
- update与set标签配合使用:set标签:该标签内有返回值,就插入一个set,如果set后面的字符串是以逗号结尾,就自动剔除。
<update id="update">
<!--修改时可以判断name是否是空的如果不为空就把数据库中这一列的值更改掉
如果为空就不修改这一列数据库这一列的值也不会为Null-->
update user
<!-- set标签会自动去掉多余的逗号-->
<set>
<!-- 与修改时搭配使用我们修改set的sql语句的‘,’的最后一列会被自动省略 -->
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="username!=null and username!=''">
username= #{username},
</if>
<if test="password!=null and password!=''">
password= #{password},
</if>
<if test="sex!=null">
sex= #{sex},
</if>
<if test="age!=null">
age=#{age},
</if>
<if test="birthday!=null and birthday!=''">
birthday= #{birthday},
</if>
</set>
where id=#{id}
</update>
(二)采用注解方式
四个注解:在接口类的方法上添加相应的注解
- @Insert("") 注解 相当于配置文件中的
<insert id="add">
insert into user(name,username,password,sex,age,birthday,create_time)
values(#{name},#{username},#{password},#{sex},#{age},#{birthday},now())
</insert>
- @Select("") 注解 相当于配置文件的:
<select id="queryById" resultType="User">
select * from user where id = #{id}
</select>
- @Delete("") 注解 相当于配置文件的:
<delete id="deleteById">
delete from user where id = #{id}
</delete>
- @Update("") 注解 相当于配置文件的:
<update id="update">
update user set
name=#{name},
username=#{username},
password=#{password},
sex=#{sex},
age=#{age},
birthday=#{birthday}
where id=#{id}
</update>
特别注意:如果方法上有多个参数,为了区分不同的参数名称,需要在参数前面加上@Param注解,指定sql使用的参数名称, 单个参数则可以不写。
@Select("select * from user order by id limit #{pageNum},#{pageSize}")
public List<User> queryByPage(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
二、mybatis框架的缓存机制
首先需要在接口类上加上注解:@CacheNamespace
@CacheNamespace 注解作用:开启此接口中的sql查询操作使用二级缓存。默认情况下,是没有开启二级缓存的,要开启二级缓存,前提是需要在全局配置mybatis-config.xml文件上中添加一行:
<!--开启二级缓存,把数据缓存到session工厂,各个session之间共享数据,默认false不开启-->
<setting name="cacheEnabled" value="true"/>
cacheEnabled:该配置影响所有映射器中配置缓存的全局开关
(一)一级缓存(特点)
- session级别,每一次会话级别,默认开启,同一个session内部都共享。 执行原理:每次查询数据时先从一级缓存直接取,如果有直接返回,否则取数据库查询,查询到结果后存入一级缓存中并返回。
- 每次执行更新(增删改)操作后,自动清楚一级缓存内容,不同session 之间不会共享。
(二)二级缓存(特点)
- 不同session 之间共享,sessionFactory级别,数据库实例级别,默认不开启。
-同一个session对象先从一级缓存取数据,如果没有再从二级缓存取数据,最后再查询数据库,查询到数据后分别存入一级缓存和二级缓存中 - 如果有更新操作,自动清楚一级缓存和二级缓存
三、采用配置文件的方式 实现多表关联
ResultMap可以将查询结果映射为复杂类型的student,比如在查询结果中包括student和list实现一对一查询和一对多查询。
<mapper namespace="com.hrr.mapper.StudentMapper">
<!-- 查询关联用户的resultMap 将整个查询的结果映射到 student 中 -->
<resultMap id="studentMap" type="student">
<!-- 配置映射的信息 -->
<!-- id:指定查询列中的唯 一标识,如果有多个列组成唯一标识,配置多个id
column:数据库信息的唯 一标识 列
property:数据库信息的唯 一标识 列所映射到student类中哪个属性
-->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="phone" column="phone"/>
<result property="classId" column="class_id"/>
<!-- 配置映射的关联的数据信息 -->
<!--多对一方配置,指定一方属性以及对应的类型-->
<!-- association:用于映射关联查询单个对象的信息 property:要将关联查询的信息映射到Classes类中哪个属性 -->
<association property="classes" javaType="Classes">
<!-- id:关联查询用户的唯 一标识
column:指定唯 一标识数据库信息的列
javaType:映射到Classes的哪个属性 -->
<id property="id" column="class_id"/>
<result property="name" column="className"/>
</association>
</resultMap>
<select id="queryByClassesName" resultMap="studentMap">
select s.*,c.name className from student s join classes c on s.class_id=c.id and c.`name`=#{name }
</select>
<select id="queryById" resultMap="studentMap">
select s.*,c.name className from student s,classes c where s.class_id = c.id and s.id = #{id};
</select>
</mapper>