当前位置 博文首页 > 文章内容

    mybatis

    作者: 栏目:未分类 时间:2020-07-05 9:00:46

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    mybatis基础

    入门

    SqlSessionFactoryBuilder

    这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。

    SqlSessionFactory

    SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

    SqlSession

    每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。 换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

    try (SqlSession session = sqlSessionFactory.openSession()) {
      // 你的应用逻辑代码
    }
    

    在你的所有的代码中一致地使用这种模式来保证所有数据库资源都能被正确地关闭。


    类名称 作用域(Scope)
    SqlSessionFactoryBuilder method
    SqlSessionFactory application
    SqlSession request/method(可以认为是线程级)
    Mapper method

    传参

    方法不加@param注解时,并且只有一个参数的时候:
    【a】String类型等,xml中可以通过#{任意值}都可以取出参数值;
    【b】Entity对象类型:xml中可以通过#{实体对象中的属性名称}取出参数值;
    【c】Map 类型:xml文件可以通过#{map中的键key}可以取出参数值;
    【d】List 类型:xml中必须要写collection=”list”或者 collection=”collection”才能够取出参数值;
    【e】Array数组类型:xml中必须要写collection=”array”才能够取出参数值;
    
    方法加@param注解时,并且只有一个参数的时候:
    【a】String类型等:如@param(value="name") ,xml中可以使用#{name}或者#{param1}取出参数值;
    【b】对象Entity类型: 如@param(value="student"),xml可以通过#{student.对象属性}取值,或者#{param1.对象属性}取出参数值;
    【c】Map 类型:如@param(value="paramsMap"),xml可以通过#{paramsMap.map的key}取值,或者#{param1.map的key}取出参数值;
    【d】List集合类型:如@param(value="ids"),xml中可以通过 collection=“ids”或者collection=”param1”取出参数值;
    【e】Array类型:如@param(value="ids"),此时要写collection=“ids”或者collection=”param1”取出参数值;
    
    当有多个参数的时候,如果没有指定@Param,那么可以使用#{param1},#{param2}…#{paramN}取出 或者 使用#{0},#{1}…#{N}取出,否则会报参数找不到异常;如果指定了@Param(value="xxx"),那么取参数的时候 可以使用@Param中指定的名称#{xxx}取出 或者 使用#{param1},#{param2}…#{paramN}取出。
    
    

    日志&异常&注意

    • logging.level.com.rjf.mapper=debug 启用mybatis-spring-boot-starter的sql打印(注意包名!)
    • Cannot determine value type from string 'xxxxxx' 缺少无参构造函数
    • <![CDATA[ ]]> CDATA 部分中的所有内容都会被解析器忽略。

    mybatis注解

    @Insert:实现新增。

    @Update:实现更新。

    @Delete:实现删除。

    @Select:实现查询。

    @Result:实现结果集封装。

    @Results:可以与@Result一起使用,封装多个结果集。

    @One:实现一对一结果集封装。

    @Many:实现一对多结果集封装。

    @Param:当方法参数有多个的时候,建立SQL语句中的占位符参数值与方法参数的映射关系。

    缓存

    一级缓存

    作用域在session级别,当sql和参数都未变时,启用缓存数据,默认开启无法关闭

    sqlSession.clearCache() 可以强制清除缓存
    

    二级缓存

    作用域在mapper的namespace,同一个namespace(接口)中查询sql可以从缓存中命中。

    开启方式:在mapper中添加 --->

    <cache
      eviction="FIFO"
      flushInterval="60000"
      size="512"
      readOnly="true"/>
    

    传统Xml配置

    properties

    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
    

    setting

    <settings>
      <setting name="cacheEnabled" value="true"/>
      <setting name="lazyLoadingEnabled" value="true"/>
      <setting name="multipleResultSetsEnabled" value="true"/>
      <setting name="useColumnLabel" value="true"/>
      <setting name="useGeneratedKeys" value="false"/>
      <setting name="autoMappingBehavior" value="PARTIAL"/>
      <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
      <setting name="defaultExecutorType" value="SIMPLE"/>
      <setting name="defaultStatementTimeout" value="25"/>
      <setting name="defaultFetchSize" value="100"/>
      <setting name="safeRowBoundsEnabled" value="false"/>
      <setting name="mapUnderscoreToCamelCase" value="false"/>
      <setting name="localCacheScope" value="SESSION"/>
      <setting name="jdbcTypeForNull" value="OTHER"/>
      <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    </settings>
    
    

    typeAliases

    <typeAliases>
      <typeAlias alias="Author" type="domain.blog.Author"/>
      <typeAlias alias="Blog" type="domain.blog.Blog"/>
      <typeAlias alias="Comment" type="domain.blog.Comment"/>
      <typeAlias alias="Post" type="domain.blog.Post"/>
      <typeAlias alias="Section" type="domain.blog.Section"/>
      <typeAlias alias="Tag" type="domain.blog.Tag"/>
    </typeAliases>
    

    mappers

    <!-- 将包内的映射器接口实现全部注册为映射器 -->
    <mappers>
      <package name="org.mybatis.builder"/>
    </mappers>
    

    实例

    <?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>
      
      <!-- 可选development:开发模式,work:工作模式 -->
        <environments default="development">
            <environment id="development">
    
              <!-- 事务管理,使用JDBC的提交和回滚设置 -->
                <transactionManager type="JDBC" />
    
                <!-- 配置数据源,使用连接池 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
                    <property name="username" value="你的数据库用户名" />
                    <property name="password" value="你的数据库密码" />
                </dataSource>
    
            </environment>
        </environments>
    
        <!-- 注册映射文件 -->
        <mappers>
        <mapper resource="com/mybatis/entities/userMapper.xml"/>
        </mappers>
    </configuration>
    

    springboot方式配置

    # 对应实体类的包名
    mybatis.typeAliasesPackage=com.rjf.pojo
    
    # mapper.xml文件所在位置
    mybatis.mapper-locations= classpath:mapper/*.xml
    

    映射文件

    SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

    • cache – 对给定命名空间的缓存配置。
    • cache-ref – 对其他命名空间缓存配置的引用。
    • resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
    • parameterMap – 已被废弃!老式风格的参数映射。更好的办法是使用内联参数,此元素可能在将来被移除。文档中不会介绍此元素。
    • sql – 可被其他语句引用的可重用语句块。
    • insert – 映射插入语句
    • update – 映射更新语句
    • delete – 映射删除语句
    • select – 映射查询语句
    <insert
      id="insertAuthor"
      parameterType="domain.blog.Author"
      flushCache="true"
      statementType="PREPARED"
      keyProperty=""
      keyColumn=""
      useGeneratedKeys=""
      timeout="20">
      
    <delete
      id="deleteAuthor"
      parameterType="domain.blog.Author"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
     
    <update
      id="updateAuthor"
      parameterType="domain.blog.Author"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
      
    <select
      id="selectPerson"
      parameterType="int"
      parameterMap="deprecated"
      resultType="hashmap"
      resultMap="personResultMap"
      flushCache="false"
      useCache="true"
      timeout="10"
      fetchSize="256"
      statementType="PREPARED"
      resultSetType="FORWARD_ONLY">
    

    参数

    方法1:顺序传参法
    public User selectUser(String name, int deptId);
    
    <select id="selectUser" resultMap="UserResultMap">
        select * from user
        where user_name = #{0} and dept_id = #{1}
    </select>
    

    {}里面的数字代表你传入参数的顺序。这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。

    方法2:@Param注解传参法
    public User selectUser(@Param("userName") String name, int @Param("deptId") deptId);
    
    <select id="selectUser" resultMap="UserResultMap">
        select * from user
        where user_name = #{userName} and dept_id = #{deptId}
    </select>
    

    {}里面的名称对应的是注解 @Param括号里面修饰的名称。这种方法在参数不多的情况还是比较直观的,推荐使用。

    方法3:Map传参法
    public User selectUser(Map<String, Object> params);
    
    <select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
        select * from user
        where user_name = #{userName} and dept_id = #{deptId}
    </select>
    

    {}里面的名称对应的是 Map里面的key名称。这种方法适合传递多个参数,且参数易变能灵活传递的情况。

    方法4:Java Bean传参法
    public User selectUser(User params);
    
    <select id="selectUser" parameterType="com.test.User" resultMap="UserResultMap">
        select * from user
        where user_name = #{userName} and dept_id = #{deptId}
    </select>
    

    {}里面的名称对应的是 User类里面的成员属性。这种方法很直观,但需要建一个实体类,扩展不容易,需要加属性,看情况使用(当使用了@Param时,采用params.id方式获取参数)。

    标签详解

    select中的几个常用属性说明:
    id属性:当前名称空间下的statement的唯一标识。必须。要求id和mapper接口中的方法的名字一致。
    resultType:将结果集映射为java的对象类型。必须(和 resultMap 二选一)
    parameterType:传入参数类型。可以省略
    
    insert 的几个常用属性说明:
    id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
    parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
    useGeneratedKeys:开启主键回写
    keyColumn:指定数据库的主键
    keyProperty:主键对应的pojo属性名
    标签内部:具体的sql语句。
    
    update 的几个常用属性说明:
    id属性:当前名称空间下的statement的唯一标识(必须属性);
    parameterType:传入的参数类型,可以省略。
    标签内部:具体的sql语句。
    
    delete 的几个常用属性说明:
    id属性:当前名称空间下的statement的唯一标识(必须属性);
    parameterType:传入的参数类型,可以省略。
    标签内部:具体的sql语句。
    

    增删查改 实例

    <!-- 新增的Statement
           id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
           parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
           useGeneratedKeys:开启主键回写
           keyColumn:指定数据库的主键
           keyProperty:主键对应的pojo属性名
    -->
    
    <insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id" >
            insert into user
            (id, name, password)
            values (
            null,
            #{name},
            #{password}
            )
    </insert>
    
    <delete id="delete">
       delete from user where id=#{id}
    </delete>
    
    <select id="getOne" resultMap="BaseResultMap">
       select * from user limit 0,1
    </select>
    
    <!-- 
          更新的statement
          id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
          parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
     -->
     
    <update id="update">
           update user
           <set>
               <if test="name !=null">name=#{name},</if>
               <if test="password !=null">password=#{password},</if>
           </set>
    </update>
    

    association & collection

        <resultMap id="Base_Student" type="Student">
            <result column="id" property="id" jdbcType="NUMERIC"/>
            <result column="name" property="name" jdbcType="VARCHAR"/>
            <result column="password" property="password" jdbcType="VARCHAR"/>
            <result column="clsid" property="clsId" jdbcType="NUMERIC"/>
            <association  property="cls" javaType="Cls">
                <result column="id" property="id" jdbcType="NUMERIC"/>
                <result column="clsname" property="clsName" jdbcType="VARCHAR"/>
            </association>
        </resultMap>
    
        <select id="getStudent" resultMap="Base_Student">
              select
                s.id,
                s.name,
                s.password,
                c.id,
                c.clsname
              from student s
              left join cls c on s.clsid=c.id
              where s.id=#{id}
        </select>
    
        <resultMap id="Base_Cls" type="Cls">
            <result column="id" property="id" jdbcType="NUMERIC"/>
            <result column="clsname" property="clsName" jdbcType="VARCHAR"/>
            <collection  property="students" javaType="ArrayList" ofType="Student">
                <result column="id" property="id" jdbcType="NUMERIC"/>
                <result column="name" property="name" jdbcType="VARCHAR"/>
                <result column="password" property="password" jdbcType="VARCHAR"/>
                <result column="clsid" property="clsId" jdbcType="NUMERIC"/>
            </collection>
        </resultMap>
    
        <select id="getCls" resultMap="Base_Cls" >
            select
              c.id,
              c.clsname,
              s.id,
              s.name,
              s.password,
              s.clsid
            from cls c
            left join student s on c.id=s.clsid
            where c.id = #{id}
        </select>
    

    sql

    这个元素可以被用来定义可重用的 SQL 代码段,这些 SQL 代码可以被包含在其他语句中。它可以(在加载的时候)被静态地设置参数。 在不同的包含语句中可以设置不同的值到参数占位符上。比如:

    <sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
    

    结果映射

    resultMap
    • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
    • result – 注入到字段或 JavaBean 属性的普通结果
    • association – 一个复杂类型的关联;许多结果将包装成这种类型
    • 嵌套结果映射 – 关联本身可以是一个 resultMap 元素,或者从别处引用一个
    • collection – 一个复杂类型的集合
    • 嵌套结果映射 – 集合本身可以是一个 resultMap 元素,或者从别处引用一个
    • discriminator – 使用结果值来决定使用哪个 resultMap
    • case – 基于某些值的结果映射
    • 嵌套结果映射 – case 本身可以是一个 resultMap 元素,因此可以具有相同的结构和元素,或者从别处引用一个
    <resultMap id="userResultMap" type="User" autoMapping="true">
      <id property="id" column="user_id" />
      <result  column="user_name" property="username"/>
      <result  column="hashed_password" property="password"/>
    </resultMap>
    

    jdbcType & javaType

    1. MyBatis 插入空值时,需要指定JdbcType
      mybatis insert空值报空值异常,但是在pl/sql不会提示错误,主要原因是mybatis无法进行转换

    2. Mybatis中javaType和jdbcType对应关系

        JDBCType            JavaType
        
        CHAR                String
        VARCHAR             String
        LONGVARCHAR         String
        NUMERIC             java.math.BigDecimal
        DECIMAL             java.math.BigDecimal
        BIT                 boolean
        BOOLEAN             boolean
        TINYINT             byte
        SMALLINT            short
        INTEGER             int
        BIGINT              long
        REAL                float
        FLOAT               double
        DOUBLE              double
        BINARY              byte[]
        VARBINARY           byte[]
        LONGVARBINARY       byte[]
        DATE                java.sql.Date
        TIME                java.sql.Time
        TIMESTAMP           java.sql.Timestamp
        CLOB                Clob
        BLOB                Blob
        ARRAY               Array
        DISTINCT            mapping of underlying type
        STRUCT              Struct
        REF                 Ref
        DATALINK            java.net.URL[color=red][/color]
    

    mapper实例

    <?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">
    <mapper namespace="com.rjf.mapper.StudentDao">
    
        <select id="getOne" resultType="Student">
            select  * from student where id=#{id}
        </select>
    
    
        <resultMap id="Base_Student" type="Student">
            <result column="id" property="id" jdbcType="NUMERIC"/>
            <result column="name" property="name" jdbcType="VARCHAR"/>
            <result column="password" property="password" jdbcType="VARCHAR"/>
            <result column="clsid" property="clsId" jdbcType="NUMERIC"/>
            <association  property="cls" javaType="Cls">
                <result column="id" property="id" jdbcType="NUMERIC"/>
                <result column="clsname" property="clsName" jdbcType="VARCHAR"/>
            </association>
        </resultMap>
    
    
        <select id="getStudent" resultMap="Base_Student">
              select
                s.id,
                s.name,
                s.password,
                c.id,
                c.clsname
              from student s
              left join cls c on s.clsid=c.id
              where s.id=#{id}
        </select>
    
        <resultMap id="Base_Cls" type="Cls">
            <result column="id" property="id" jdbcType="NUMERIC"/>
            <result column="clsname" property="clsName" jdbcType="VARCHAR"/>
            <collection column="id" property="students" javaType="ArrayList" ofType="Student">
                <result column="id" property="id" jdbcType="NUMERIC"/>
                <result column="name" property="name" jdbcType="VARCHAR"/>
                <result column="password" property="password" jdbcType="VARCHAR"/>
                <result column="clsid" property="clsId" jdbcType="NUMERIC"/>
            </collection>
        </resultMap>
    
        <select id="getCls" resultMap="Base_Cls" >
            select
              c.id,
              c.clsname,
              s.id,
              s.name,
              s.password,
              s.clsid
            from cls c
            left join student s on c.id=s.clsid
            where c.id = #{id}
        </select>
    
    </mapper>
    
    
    

    动态SQL

    if

        <select id="findActiveUser" resultType="User">
            select * from user
            where state = 'active'
            <if test="name != null">
                and name like '${%name}'
            </if>
        </select>
    

    choose,when,otherwise

        <select id="getUserListByNameOrId" resultMap="BaseResultMap">
            select * from user where 1=1
            <choose>
                <when test="name !=null"> and name like '%${name}'</when>
                <otherwise> and name='xiaoming'</otherwise>
            </choose>
        </select>
    

    trim,where,set

        <select id="getUserListById" resultMap="BaseResultMap">
            select * from user
            <where>
                <if test="id !=null">and id=#{id}</if>
            </where>
        </select>
        <!-- 等价于 -->
        <trim prefix="WHERE" prefixOverrides="AND |OR ">
          ...
        </trim>
    
        <update id="updateByUser">
            update user
            <set>
                <if test="name !=null">name =#{name},</if>
                <if test="password !=null">password =#{password},</if>
            </set>
            where id = #{id}
        </update>
        <!-- 等价于 -->
        <trim prefix="SET" suffixOverrides=",">
          ...
        </trim>
    

    foreach

        <select id="getUserListByIdList" resultMap="BaseResultMap">
            select *
            from user
            where id in
            <foreach collection="list" item="id"  open="(" separator="," close=")">
                #{id}
            </foreach>
        </select>
    

    mybatis-spring-boot-starter

    引入pom依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.0.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.18</version>
                <scope>compile</scope>
                <!-- compile是防止idea的warning报警 -->
            </dependency>
    

    application.propertiestis添加数据库和mybatis配置

    spring.datasource.url=jdbc:mysql://localhost:3306/mybatistest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
    mybatis.mapper-locations= classpath:mapper/*.xml
    mybatis.type-aliases-package=com.rjf.pojo
    logging.level.com.rjf.mapper=debug (必须及时改包!)
    

    实体类

    package com.rjf.pojo;
    
    public class User {
    
        private int id;
        private String name;
        private String password;
        //省略 set & get
    }
    

    UserMapper.java接口

    package com.rjf.mapper;
    
    import com.rjf.pojo.User;
    import org.apache.ibatis.annotations.Mapper;
    import java.util.List;
    
    @Mapper
    public interface UserMapper {
    
        List<User> getAll();
    
        User findById(int id);
    
        int insert(User user);
    
        int update(User user);
    
        int delete(int id);
    
    }
    

    UserMapper.xml 映射文件

    <?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">
    <mapper namespace="com.rjf.mapper.UserMapper">
        <resultMap id="BaseResultMap" type="com.rjf.pojo.User" >
            <result column="id" property="id" />
            <result column="name" property="name" />
            <result column="password" property="password" />
        </resultMap>
        
        <sql id="userColums" >
            id,name,password
        </sql>
    
        <select id="getAll" resultMap="BaseResultMap">
            select 
            <include refid="userColums"></include>
             from mysql_user
        </select>
    
        <select id="findById" resultMap="BaseResultMap">
            select
            <include refid="userColums"></include>
             from mysql_user where id = #{id}
        </select>
    
        <insert id="insert" >
            insert into mysql_user (name,password)
            values (#{name},#{password})
        </insert>
    
        <update id="update">
            update mysql_user set
                name=#{name},
                password=#{password}
            where name=#{name}
        </update>
    
        <delete id="delete">
            delete from mysql_user where id=#{id}
        </delete>
    
      <!--  choose标签 辅助标签when otherwise-->
        <select id="findUserLikeNameAndPassword" resultType="com.rjf.pojo.User">
            select
            <include refid="userColums"></include>
            from mysql_user
            where 1=1
            <choose>
                <when test="name!=null">
                    and name=#{name}
                </when>
                <when test="password!=null">
                    and password=#{password}
                </when>
                <otherwise>
                    and 1=1
                </otherwise>
            </choose>
        </select>
    
        <!--trim标签 字标签where set-->
        <select id="findUserLike" resultMap="BaseResultMap">
            select
            <include refid="userColums"></include>
            from mysql_user
            <trim prefix="where" prefixOverrides="and | or">
                <if test="name!=null">
                    and name=#{name}
                </if>
                <if test="password!=null">
                    and password=#{password}
                </if>
            </trim>
        </select>
    
    </mapper>