Mybatis基础学习笔记(四)

parameterType参数解析
  • parameterType:表示参数的类型,指定dao方法的形参数据类型,在mapper映射文件select标签中使用,Mybatis会在调用PreparedStatement.setXxx(索引,值)时将值赋予sql执行语句
<select id="findProductByPage" resultMap="productByPageMapper" parameterType="Condition">
    select * from products
    <where>
        <if test="id!=null ">
            and id = #{id}
        </if>
        <if test="name!=null">
            and name like #{name}
        </if>
        <if test="lp!=null">
            and price >= #{lp}
        </if>
        <if test="hp!=null">
            and  price <= #{hp}
        </if>
    </where>
    limit ${(currentPage-1)*size} , ${size};
</select>
  • 通过反射机制可以获取dao接口参数类型推断出parameterType,所以可以省略
  • 一个简单类型的参数,#{参数名称}中参数名称任取
  • 多个简单类型时使用@Param
  • 由Mybatis提供
  • 放置在dao接口对应方法的形参前
  • 属性为自定义的参数名称
  • 在使用了该注解后,mapper中占位符中所使用的参数名称为该注解的value属性值
  • 使用对象作为参数,在参数有多个时比较方便,将该对象的属性值作为sql语句的参数
  • Mybtis会调用该参数对应的getXxx获取该属性值(测试发现只要属性名或getXxx方法有一个匹配都可)
  • 另一种传递参数的办法
  • #{property,javaType=java中数据类型名,jdbcType=数据类型名称(CHAR、VARHCAR、INTEGER... ...)},这是一个完整格式
  • Mybatis可以自动检测数据类型信息,一般只写#
按位置传递参数
  • dao接口方法中,形参列表按位置从左往右为0,1,2,3... ...
  • 语法格式#{arg0},#{arg1}... ...
  • 这种形式显然不清晰
  • 3.5.1以上版本
使用Map传递参数
  • 使用方法#
  • Map<String,Object>,不够清晰
#和$的区别
  • 对#占位符使用的jdbc对象是PrepareStatement,Mybatis会创建出PrepareStatement,执行sql语句
  • 特点:
  • PrepareStatement对象执行sql语句效率高
  • 能避免sql注入,sql语句更安全
  • #{}常作为列值使用,位于等号右侧,数据类型不同时设置参数的方法不同(可能会补充引号)
  • ${字符}代表字符串连接,将sql语句的其他内容和${}的内容使用+连接方式连接在一起
  • 特点:
  • Mybatis此时使用Statement对象执行sql语句
  • 没有预编译,sql语句效率低
  • 使用字符串拼接方式,有sql注入风险,有代码安全问题
  • 不会区分数据类型,原样拼接字符串不会自动加引号(特点),导致mysql在执行查询时将参数当作表的列名,使用需自加引号,字符串替换在一些特殊情况下有作用
  • 常用作表名和列名,需要保证执行安全
  • 在简单参数查询时使用@Param命名参数,取值
resultType
  • 作用:封装数据结果,代表结果类型
  • 值的类型:
  • 1.类型的全限定名称:自定义的、基本类型、Map
  • 2.类型的别名, 例如 java.lang.Integer别名是int
  • 处理方式:mybatis执行sql语句, 然后mybatis调用类的无参数构造方法(使用反射),创建对象,同名的列赋值给同名的属性:如person.setName(rs.getString("name")),在返回值是List时,mybatis会把对象放入List集合中,行数据映射一个实体类对象
  • 在设置返回值类型为Map时,Mybatis会将表列名与对应的值分别作为k/v传入,在结果是一列时可行
设置别名
<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>
  • 另外一种方式:
<typeAliases>
  <package name="domain.blog"/>
</typeAliases>
<!--指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名-->
  • 就可读性而言写全限定类名更好
resultMap
  • 解决的问题:resultType中需要实体类的属性与表的列名对应,通过resultMap可以解决 实体类的属性与表的列名不对应的问题,或者在sql语句中使用别名也可解决
<resultMap id="productByPageMapper" type="Product">
    <!--对于主键使用id标签-->
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="price" column="price"/>
    <result property="quantity" column="quantity"/>
</resultMap>

<select id="findProductByPage" resultMap="productByPageMapper">
    ...
</select>
like
  • 使用#{}出现的问题:不会自动加百分号%,需要自行在设置查询参数时拼接百分号
  • 直接在sql语句中拼接组织like的内容:
  • sql语句like的格式:"%" #{name} "%" 注意在占位符两侧存在空格