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} "%" 注意在占位符两侧存在空格