赞
踩
基本的就不说了,主要记录一下动态sql的
1.if 标签 if标签通常用于WHERE语句、UPDATE语句、INSERT语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。 <if test="name != null and name != ''"> and NAME = #{name} </if> 2.foreach 标签 foreach标签主要用于构建in条件,可在sql中对集合进行迭代。也常用到批量删除、添加等操作中。 <!-- in查询所有,不分页 --> <select id="selectIn" resultMap="BaseResultMap"> select name,hobby from student where id in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select> 3 choose标签 有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。 MyBatis提供了choose 元素,按顺序判断when中的条件出否成立, 如果有一个成立,则choose结束。当choose中所有when的条件都不满则时, 则执行 otherwise中的sql。类似于Java 的switch 语句,choose为switch, when为case,otherwise则为default。 if是与(and)的关系,而choose是或(or)的关系。 <select id="getStudentListChoose" parameterType="Student" resultMap="BaseResultMap"> SELECT * from STUDENT WHERE 1=1 <where> <choose> <when test="Name!=null and student!='' "> AND name LIKE CONCAT(CONCAT('%', #{student}),'%') </when> <when test="hobby!= null and hobby!= '' "> AND hobby = #{hobby} </when> <otherwise> AND AGE = 15 </otherwise> </choose> </where> </select> 4. where标签 这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。 此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。 <select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap"> SELECT * from STUDENT <where> <if test="name!=null and name!='' "> NAME LIKE CONCAT(CONCAT('%', #{name}),'%') </if> <if test="hobby!= null and hobby!= '' "> AND hobby = #{hobby} </if> </where> </select> 5. set 标签 当在update语句中使用if标签时,使用set标签可以将动态的配置set关键字,和剔除追 加到条件末尾的任何不相关的逗号。 <update id="updateStudent" parameterType="Object"> UPDATE STUDENT <set> <if test="name!=null and name!='' "> NAME = #{name}, </if> <if test="hobby!=null and hobby!='' "> MAJOR = #{major}, </if> <if test="hobby!=null and hobby!='' "> HOBBY = #{hobby} </if> </set> WHERE ID = #{id}; </update> 6.include标签 sql标签中id属性对应include标签中的refid属性。通过include标签将sql片段 和原sql片段进行拼接成一个完整的sql语句进行执行。 例如: <sql id="sqlid"> res_type_id,res_type </sql> <select id="selectbyId" resultType="com.property.vo.PubResTypeVO"> select <include refid="sqlid"/> from pub_res_type </select> 7.<-- 整合--> <select id="queryUserByVo" resultType="net.seehope.spring.project.pojo.User" parameterType="net.seehope.spring.project.pojo.vo.UserQueryVo"> select * from user <where> <if test="user !=null"> <if test="user.username!=null and user.username != ''"> and username = #{user.username} </if> <if test="user.id!=null and user.id != 0"> and id = #{user.id} </if> <if test="user.birthday!=null "> and birthday = #{user.birthday} </if> <if test="user.sex!=null and user.sex!=''"> and sex = #{user.sex} </if> <if test="user.address!=null and user.address!='' "> and address = #{user.address} </if> </if> <if test="ids!=null and ids.size()!=0"> <foreach collection="ids" open=" and id in (" close=")" separator="," item="id"> #{id} </foreach> </if> </where> </select> <trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim> prefix:在trim标签内sql语句加上前缀。 suffix:在trim标签内sql语句加上后缀。 suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。 prefixOverrides:指定去除多余的前缀内容 8.多表联查中: JavaType和ofType都是用来指定对象类型的,但是JavaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型。 collection、association标签是用于体现关联的。 如一个实体与另一个实体之间是一对多的关系, 那么在一的一方使用 collection 标签,对应多的一方的一个集合, 在多的一方使用association标签对应一的一方的一个实体 <collection property="orderDetail" ofType="net.seehope.ssm.pojo.OrderDetail"> <result property="id" column="id" /> <result property="ordersId" column="orders_id" /> <result property="itemsId" column="items_id" /> <result property="itemsNum" column="items_num" /> <!-- collection、association标签是用于体现关联的。 如一个实体与另一个实体之间是一对多的关系, 那么在一的一方使用 collection 标签,对应多的一方的一个集合, 在多的一方使用association标签对应一的一方的一个实体 --> <association property="items" javaType="net.seehope.ssm.pojo.Items"> <result property="id" column="id" /> <result property="name" column="name" /> <result property="price" column="price" /> <result property="detail" column="detail" /> <result property="pic" column="pic" /> </association> </collection>
2.1区别:
一级缓存的作用域在sqlSession中
二级缓存的作用域是针对mapper做缓存,根据namespace
2.2 一级缓存
一级缓存是框架默认给我们开启的,不需要做任何配置。
例如我们查询了id为1的用户,mybatis会将用户的对象存储在一级缓存中,如果在此中间sqlSession发生了增删改操作,则mybatis会清空一级缓存,避免脏读
2.2 二级缓存
//开启缓存
SqlSession session=sqlSessionFactory .openSession();
二级缓存是mapper级别的缓存,多个sqlSession操作同一个mapper,不管sqlSession是否相同,只要mapper的namespace相同即可共享数据。
工作原理:
sqlSession 关闭后(close) ,一级缓存的数据会保存到二级缓存中,新的相同就会去二级缓存中去查询。
二级缓存开启要求:
1,xml 配置中开启 二级缓存
2,去mapper映射文件中使用二级缓存
3,需要将要存储数据的 pojo 实现 Serializable接口,为了将数据取出做反序列化操作,因为二级的缓存的存储方式多种多样,有可能存储在内存中,也可能储存到磁盘中。
4.可全局,也可在想哪个类开缓存就放在哪XXXMapper.xml
3.1 #{变量名}可以进行预编译、类型匹配等操作,会转化成jdbc的类型
3.2 ${变量名}不进行数据类型匹配,直接替换,可进行字符串拼接,容易sql注入,而且类型不会自行转化
说明:Mybatis中对于延迟加载设置,只对于resultMap中的collection和association起作用,可以应用到一对一、一对多、多对一、多对多的所有关联查询中
4.1场景
多对一查询:推荐立即加载
需求场景:查询账户时,基本需要显示用户信息
一对多查询:推荐延迟加载(减少内存浪费)
需求场景:查询用户信息时,不需要立即把用户的全部账户显示,推荐使用延迟加载
<!--全局参数设置-->
<settings>
<!--延迟加载总开关-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--将aggressiveLazyLoading设置为false表示按需加载,默认为true-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--根据team的id查找player--> <select id="selectPlayerByTeamId" resultType="Player"> select id,name from t_player WHERE tid=#{id} </select> <!--关联属性映射关系--> <!--集合的数据来自select查询,该查询的条件是selectTeamByIdAlone查询出的id--> <resultMap id="teamMapAlone" type="Team"> <id column="id" property="id"/> <result column="name" property="name"/> <collection property="playerList" ofType="Player" select="selectPlayerByTeamId" column="id"/> </resultMap> <select id="selectTeamByIdAlone" resultMap="teamMapAlone"> SELECT id,name FROM t_team where id=#{id} </select>
dao层
Team selectTeamByIdAlone(int id);
测试:
@Test
public void selectTeamByIdAlone() {
Team team = teamDao.selectTeamByIdAlone(1);
System.out.println(team.getName());
System.out.println(team.getPlayerList().size());
}
开启懒加载后,只要代码中不使用player相关的数据,mybatis就不会进行sql查询,只有当真正使用的时候才会去发出sql语句查询。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。