MyBatis学习总结(02)

MyBatis学习总结大全:
- MyBatis学习总结第一天
- MyBatis学习总结第二天
- MyBatis学习总结第三天

今日大纲

  • 动态sql
  • 缓存
  • 接口绑定
  • 或者叫动态代理
  • ResultType

    1、动态sql
    相当于条件查询,在代码中使用if语句来拼装sql语句,它会造成资源浪费,而且,不易于维护。If、switch语句是Java代码之罪。
    在写sql语句的时候,直接进行拼装。
    特殊字符转义

&lt;    <   小于
&gt;    >   大于
&amp;   &   和号
&apos;  '   省略号
&quot;  "   引号

< if>标签:
标签,相当于代码中的if(){}else{}
它帮我们做数据判断

    <select id="getUsers" resultType="user">
        select * from t_user 
            where 1=1 
            <if test="name != null and name !='' ">
                and name = #{name}
            </if>
            <if test="pwd !=null and pwd !='' ">
                and pwd =#{pwd}
            </if>
            <if test="age &gt; 23">
                and name ='王思聪'
            </if>

    </select>

< where>标签
标签就想到与sql语句中where条件,当where标签内的if判断条件执行,才执行where标签,如果if不执行,where也不执行,所以 1=1 就省略掉了。
Where标签,会自动判断sql语句,如果第一个and开始的,就省略掉,一般情况下,在if判断条件中都加and关键字。

    <select id="getUsers" resultType="user">
        select * from t_user 
            <where> 
                <if test="name != null and name !='' ">
                    and name = #{name}
                </if>
                <if test="pwd !=null and pwd !='' ">
                    and pwd =#{pwd}
                </if>
                <if test="age &gt; 23">
                    and name ='王思聪'
                </if>
            </where>
    </select>

< choose>标签
标签就相当于代码中switch,标签:当条件满足的时候执行when标签内容,当所有的when标签内容不满足时,执行默认标签中的内容。

    <select id="getUsers1" resultType="user">
        select * from t_user 
            <where> 
                <choose>
                    <when test="name != null and name !=''">
                        and name= #{name}
                    </when>

                    <otherwise>
                        and age &gt; 23
                    </otherwise>
                </choose>
            </where>
    </select>

< sql >和< include >
标签:用于定义sql语句
标签:用于引用标签定义的sql语句,这个引用可以在sql语句的任何位置

    <sql id="select">
         id,name,pwd
    </sql>
    <sql id="from">
        from t_user
    </sql>
    <select id="getUsers2" resultType="user">
        <!-- select * from t_user t where t.id in(select id from t_user1 where name =?)
        sql:语句的拆分,一般不用于单表操作,一般用于多表操作
        include:引用sql语句,可以在任何位置
        -->
        select 
        <include refid="select"/>
        <include refid="from"/>
    </select>

< bind>标签

标签用于给参数追加数据,随便添加

    <select id="getUserByName" resultType="user">
        <!-- bind:给参数追加内容,写的方式 '%'+name+'%'
            现在讲参数进行追加,然后再进行数据判断
            如果参数为空:会报错
        -->
        <bind name="name" value="name+'123'"/>
        select * from t_user 
            <where>
                <if test="name != null and name!='' ">
                    name like #{name}
                </if>
            </where>
    </select>

< set>标签
标签主要用于update语句。相对于update语句中set关键字,它会自动消除多余的”,”

    <!--  set 标签应用-->
    <update id="updateUser">
        <!-- update t_user set name=? and pwd=? where id =? -->
        update t_user 
            <set>
                <if test="name != null and name !=''">
                    name = #{name},
                </if>
                <if test="pwd != null and pwd !='' ">
                    pwd = #{pwd}
                </if>
            </set>
            <where>
                id=#{id}
            </where>

    </update>

< foreach>标签
< foreach>标签,主要用循环遍历,
Select * from t_user where id in(name),name就可以使用foreach

<!-- foreach应用 -->
    <select id="findUsers" resultType="user">
        select * from t_user 
            <where>
                id in
                    <!-- 
                        collection:集合对象
                        open:指的是以什么开始
                        close:指的是以什么结尾,与open成对出现
                        separator:指的数据以什么进行分割
                        item:指的遍历的数据项
                        mybatis的会自动给string数据添加'',不需要我们手动添加
                     -->
                    <foreach collection="list" open="(" separator="," close=")" item="ids">
                        #{ids}
                    </foreach>
            </where>
    </select>
    <select id="findUsersByName" resultType="user">
        select * from t_user
            <where>
                name in 
                <foreach collection="list" open="(" separator="," close=")" item="names">
                    #{names}
                </foreach>
            </where>
    </select>

< trim>标签
< trim>标签在mybatis里面是去除and|or|,

    <select id="queryUsers" resultType="user">
        select * from t_user 
            <!--
                prefix:前缀
                suffix:后缀
                prefixOverrides:前缀结束,去掉and|or关键字
                suffixOverrides:后缀结束,去掉and|or关键字
                <where><set>本身自带了去掉and|or|,的功能
              -->
            <trim prefix="WHERE"  prefixOverrides="AND|OR">
                <if test="name != null and name !='' ">
                    and name = #{name}
                </if>
                <if test="pwd !=null and pwd !='' ">
                    and pwd =#{pwd}
                </if>
                <if test="age &gt; 23">
                    and name ='王思聪'
                </if>
            </trim>
    </select>

简单类型传递参数

    <!-- 简单类型参数传递:现在一次传递多个参数 
        如果是多个简单类型的参数使用[param参数下标从1开始]
        在占位符中的name值是:[param参数下标从1开始],不是参数名称
    -->
    <select id="findUsersByParam" resultType="user">
        select * from t_user 
            <where> 
                <if test="param1 != null and param1 !='' ">
                    and name = #{param1}
                </if>
                <if test="param2 !=null and param2 !='' ">
                    and pwd =#{param2}
                </if>
                <if test="param3 &gt; 23">
                    and name ='王思聪'
                </if>
            </where>
    </select>   
    <!-- 简单类型参数传递:一次传递一个参数 
        作为判断条件的时候:使用_parameter来进行判断
        占位符中应用还是参数名称
    -->
    <select id="findUsersByParam1" resultType="user">
        select * from t_user
            <where>
                <if test="_parameter != null and _parameter != ''">
                    name = #{name}
                </if>
            </where>
    </select>

接口类:

public interface UserMapper {

    List<User> getUsers(Map<String, Object> map);

    List<User> getUsers1(User user);

    List<User> getUsers2();

    List<User> getUserByName(User user);

    int updateUser(User user);

    List<User> findUsers(List<Integer> ids);

    List<User> findUsersByName(List<String> names);

    List<User> queryUsers(User user);

    List<User> findUsersByParam(String name,String pwd, Integer age);

    List<User> findUsersByParam1(String name);
}

测试类:

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.bjsxt.mapper.UserMapper;
import com.bjsxt.pojo.User;
import com.bjsxt.utils.MybatisUtil;

public class TestMybatis {

    private SqlSession session ;

    @Before
    public void getSession(){
        session = MybatisUtil.getSession();
    }

    @After
    public void closeSession(){
        MybatisUtil.closeSession();
    }
    /**
     * 
     * @Description:   foreach应用
     * @author mao
     * @date   2017年10月11日
     */
    @Test
    public void findUsers(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<Integer> ids = new ArrayList<>();
        ids.add(2);
        ids.add(3);
        ids.add(6);
        ids.add(7);
        List<User> findUsers = mapper.findUsers(ids);
        for (User user : findUsers) {
            System.out.println(user);
        }
    }

    @Test
    public void findUsersByName(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<String> names = new ArrayList<>();
        names.add("王二麻子");
        names.add("张三丰");
        List<User> findUsersByName = mapper.findUsersByName(names);
        for (User user : findUsersByName) {
            System.out.println(user);
        }
    }

    @Test
    public void queryUsers(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setName("王二麻子");
        List<User> queryUsers = mapper.queryUsers(user);
        for (User user2 : queryUsers) {
            System.out.println(user2);
        }
    }
    /**
     * 
     * @Description:   简单类型参数传递:多个简单类型
     * @author mao
     * @date   2017年10月11日
     */
    @Test
    public void findUsersByParam(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> findUsersByParam = mapper.findUsersByParam("王二麻子", "12345", 22);
        for (User user : findUsersByParam) {
            System.out.println(user);
        }

    }

    @Test
    public void findUsersByParam1(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> findUsersByParam1 = mapper.findUsersByParam1("王二麻子");
        for (User user : findUsersByParam1) {
            System.out.println(user);
        }

    }

    @Test
    public void getUsers(){
        /**
         * 模糊查询
         * 字符拼接查询
         * 使用代码进行模糊查询,它效率很低
         * if(){}else{}称之为代码之罪
         * mybatis提供了动态sql,可以在sql中直接使用一些判断条件
         */
        StringBuffer sb = new StringBuffer();
        sb.append("select * from t_user where 1=1 ");
        User user = new User();
        if(user.getName() !=null){
            sb.append(" and name= XXX");
        }
        if(user.getPwd() != null){
            sb.append(" and pwd=XXX");
        }

        //执行sql
    }

    @Test
    public void getUserDymic(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<>();
        map.put("name", "王二麻子");
//      map.put("pwd", "12345");
//      map.put("age", 26);
        List<User> users = mapper.getUsers(map);
        for (User user : users) {
            System.out.println(user);
        }

    }
    @Test
    public void getUsers1(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        //user.setName("王二麻子");
        List<User> users1 = mapper.getUsers1(user);
        for (User user2 : users1) {
            System.out.println(user2);
        }
    }

    @Test
    public void getUsers3(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> users2 = mapper.getUsers2();
        for (User user : users2) {
            System.out.println(user);
        }
    }

    @Test
    public void getUserByName(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setName("张");
        List<User> userByName = mapper.getUserByName(user);
        for (User user2 : userByName) {
            System.out.println(user2);
        }
    }

    @Test
    public void updateUser(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setName("张666");
        //user.setPwd("456");
        user.setId(3);
        int updateUser = mapper.updateUser(user);
        session.commit();
        System.out.println(updateUser);

    }
}

Sql拼接:
1.Java代码
2.Mybatis提供的动态sql
3.不使用Java代码和mybatis提供的动态sql:主要用报表
报表:经过封装后,还是jsp或者html,直接操作数据库,在报表工具中直接写的是sql语句。

    <!-- 不使用Java代码  和 mybatis的标签拼接sql查询数据库数据  -->
    <select id="getUsersByParams" resultType="user">

        select * from t_user 
            where 
                (#{name} is null or name= #{name}) 
                and (#{pwd} is null or pwd = #{pwd})

    </select>

测试:

    public void getUsers6(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setName("王二麻子");
        List<User> usersByParams = mapper.getUsersByParams(user);
        for (User user2 : usersByParams) {
            System.out.println(user2);
        }
    }

缓存:
就是将数据放到内存中,电商项目,它的很多数据都是放在缓存中的。提高查询效率。但是mybatis的缓存做的不好,有大量数据冗余。
一级缓存
一级缓存:SqlSession,默认开启的,直接使用。
查询一条数据,又查询同样的一条数据,执行sql语句,查询第一条数据的时候,已经将数据放到一级缓存里面,在Sqlsession 没有关闭的情况下,查询同样的一条数据是从是缓存获取,不执行sql语句。
是依据 映射文件中标签中id属性值进行缓存(statementid进行缓存的)

    @Test
    public void getUserById(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<>();
        map.put("id", 3);
        User userById = mapper.getUserById(map);
        System.out.println(userById);

        Map<String, Object> map1 = new HashMap<>();
        map1.put("id", 3);
        User userById1 = mapper.getUserById2(map1);
        System.out.println(userById1);

    }

配置文件:

    <select id="getUserById" resultType="user">
        select * from t_user where id = #{id}
    </select>
    <select id="getUserById2" resultType="user">
        select * from t_user where id = #{id}
    </select>   

二级缓存
二级缓存:SqlSessionFactory,开启需要在映射文件中进行配置
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:
映射语句文件中的所有 select 语句将会被缓存。
映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <!-- 
    namespace:相当于包的概念
        要保证在一个映射文件中,保证statementid为唯一
   -->
  <mapper namespace="com.bjsxt.mapper.UserMapper">

    <!-- 
        <if>标签:相当于java代码中的if语句
        if:简单类型传递
        if标签:Java代码中的if判断条件 使用的是 && || 
            在if标签中使用的是 and
     -->
    <select id="getUsers" resultType="user">

        select * from t_user 
            where 1=1 
            <if test="_parameter != null and _parameter !='' ">
                and name like #{name}
            </if>
    </select>
    <!-- if语句的:对象和集合类型传递 -->
    <select id="getUsers1" resultType="user">

        select * from t_user 
            where 1=1 
            <if test="name != null and name !='' ">
                and name like #{name}
            </if>
    </select>
    <!-- if语句:多个判断条件, 
        where标签:去掉sql语句的where关键字
                mybatis会自动的进行判断,再进行删除
            它会自动判断,它内部的语句第一个 关键字是否是and 如果是,自动的去掉
            所以,一般使用where标签,它内部的所有if判断条件都添加and关键字
    -->
     <select id="getUsers2" resultType="user">
        select * from t_user 
            <where>
                <if test="name != null and name !='' ">
                    and name like #{name}
                </if>
                <if test="age &gt; 33">
                    and age &gt; 33
                </if>
            </where>
    </select>
    <!-- 
        choose标签:就相当于Java代码中的switch语句,当一个条件成立的话,后面的所有判断条件都不执行
        switch(falg){
            case falg:xxx; ==> when
            case falg:xxx; ==> when
            default: ==》otherwise
                XXX;
        }
     -->
     <select id="getUsers3" resultType="user">
        select * from t_user
            <where>
                <choose>
                    <when test="name != null and name != ''">
                        and name like #{name}
                    </when>
                    <when test="age &gt; 33">
                        and age &gt; 33
                    </when>
                    <otherwise>
                        and pwd ='zhangsanf'
                    </otherwise>
                </choose>
            </where>
     </select>
     <!-- 
        bind标签:相当于字符串拼接,它可以在参数的前后添加内容
        name属性值:参数名称
        value属性值:对参数进行改造
      -->
      <select id="getUsers4" resultType="user">
        <bind name="name" value="'%'+name+'%'"/>
        <!-- 
            先进行数据添加,再进行数据判断,
            参数为空,会报错,bind报错
         -->
        select * from t_user
            <where>
                <if test="name != null and name != ''">
                    and name like #{name}
                </if>
            </where>
      </select>
      <!-- 
        set标签:它就相当于 update语句set关键字,set关键字对自动去掉,号
       -->
       <update id="updateUser">
            <!-- update t_user set name=#{name} , age =#{age} where id=#{id} -->
            update t_user 
                <set>
                    <if test="name != null and name != ''">
                        name=#{name},
                    </if>
                    <if test="age != null">
                        age=#{age},
                    </if>
                </set>
                <where>
                    <if test="id != null">
                        id=#{id}
                    </if>
                </where>
       </update>
       <!-- foreach标签:相当于Java代码中的for循环
            需求:查询该集合中主键的值
            collection:指的是集合对象,对应的传递过来的参数集合类型
            open:以什么开始
            separator:数据以什么分割
            close:以什么结尾,与open成单出现
            item:参数名称,对应传递过来的参数名称
            如果遍历的是string类型,mybatis会自动的添加''号,不需要我们手动添加
        -->
       <select id="getUsers5" resultType="user">
            select * from t_user
                <where>
                    id in
                    <foreach collection="list" open="(" separator="," close=")" item="ids">
                        #{ids}
                    </foreach>
                </where>
       </select>
       <select id="getUsers6" resultType="user">
            select * from t_user
                <where>
                    name in
                    <foreach collection="list" open="(" separator="," close=")" item="names">
                        #{names}
                    </foreach>
                </where>
       </select>      
       <!-- 
         trim标签:
        -->
       <select id="getUsers7" resultType="user">
            select * from t_user 
                <!-- 
                prefix:前缀
                prefixOverrides:前缀以什么结束
                suffix:后置
                suffixOverrides:后置以什么结束
                 -->
                <trim prefix="WHERE" prefixOverrides="AND|OR">
                    <if test="name != null and name != ''">
                        and name like #{name}
                    </if>
                    <if test="age &gt; 33">
                        and age &gt; 33
                    </if>
                </trim>
       </select> 

       <!-- 
            <sql>标签:在外部定义sql语句
            <include>标签:在内部引用sql语句
            可以拼装成一个完成的sql语句,
            一般当sql语句量很大得时候,进行使用
        -->
       <sql id="select">
            select id,name,pwd,age 
       </sql>
       <sql id="from"> 
            from  t_user
       </sql>
       <select id="getUser8" resultType="user">
            <include refid="select"/>
            <include refid="from"/>
       </select>

       <update id="updateUser3">
        update t_user set 
            name = #{0},age=#{1} 
            where id= #{2}
       </update>

  </mapper>

接口:

public interface UserMapper {

     List<User> getUsers(String name);

     List<User> getUsers1(User User);

     List<User> getUsers2(Map<String, Object> map);

     List<User> getUsers3(Map<String, Object> map);

     int updateUser(Map<String, Object> map);

     int updateUser3(String name,Integer age,Integer id);

}

实现类:

    /**
     * 
     * @Description:接口代理   
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void getUsers(){
        //IUserDao userDao = new UserDaoImpl();
        /**
         * mybatis的通过getMapper来实现自动创建mapper接口的实现类
         * mapper.getUsers==》mybatis的session.selectList();
         */
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> users = mapper.getUsers("%张%");
//      List<User> users = session.selectList("getUsers","%张%");
        for (User user : users) {
            System.out.println(user);
        }

    }
    /**
     * 
     * @Description:   
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void getUsers1(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setName("%张%");
        List<User> users1 = mapper.getUsers1(user);
        for (User user2 : users1) {
            System.out.println(user2);
        }
    }
    /**
     * 
     * @Description:接口实现修改   
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void updataUser(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<>();
        map.put("name", "陈二狗");
        map.put("age", 33);
        map.put("id", 100);
        int updateUser = mapper.updateUser(map);
        System.out.println(updateUser);
        session.commit();
    }

    /**
     * 
     * @Description:传递多个简单类型参数   
     * 在statement中接收参数使用:参数的下标或者param1
     * 参数下边从0开始
     * param[args] :[args]使用1开始;例如:param1
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void updateUser1(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        int updateUser3 = mapper.updateUser3("田876", 33, 100);
        System.out.println(updateUser3);
        session.commit();

    }

    /**
     * 
     */
    @Test
    public void getUsers2(){

        List<User> selectList = session.selectList("com.bjsxt.mapper.UserMapper.getUsers","%张%");
        for (User user : selectList) {
            System.out.println(user);
        }

    }

}

ResultType
映射文件中的statement中的resultType;
resultType:对象类型、简单类型、集合类型
配置文件:

  <!-- 
    namespace:相当于包的概念
        要保证在一个映射文件中,保证statementid为唯一
   -->
  <mapper namespace="com.bjsxt.mapper.UserMapper">

    <select id="getUsers" resultType="user">
        select * from t_user
    </select>
    <!--resultType返回简单类型 -->
    <select id="getUsers1" resultType="int">
        select id,name,pwd from t_user 
    </select>   
    <!--resultType返回集合类型 -->
    <select id="getUsers2" resultType="map">
        select id,name,pwd from t_user where name like #{_parameter}
    </select> 

  </mapper>

接口:

public interface UserMapper {

     List<User> getUsers();

     List<Integer> getUsers1();

     List<Map<Object, Object>> getUsers2(String name);
}

实现类:

    /**
     * 
     * @Description:resultType返回值为对象类型   
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void getUsers(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> users = mapper.getUsers();
        for (User user : users) {
            System.out.println(user);
        }

    }
    /**
     * 
     * @Description:resultType返回简单类型
     * 1.在statement中的resultType中设置返回值类型
     * 2.在sql语句中 ,如果查询字段有多个,要保证第一个字段与返回值类型一致  
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void getUsers1(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<Integer> users1 = mapper.getUsers1();
        for (Integer integer : users1) {
            System.out.println(integer);
        }
    }
    /**
     * 
     * @Description:resultType返回map集合类型
     * 1.接口中定义的方法返回值是Map集合   
     * @author mao
     * @date   2017年10月30日
     */
    @Test
    public void getUsers2(){

        UserMapper mapper = session.getMapper(UserMapper.class);
        List<Map<Object, Object>> users2 = mapper.getUsers2("%张%");
        for (Map<Object, Object> map : users2) {
            System.out.println(map);
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anguser

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值