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可以自动检测数据类型信息,一般只写#{property}
按位置传递参数
- dao接口方法中,形参列表按位置从左往右为0,1,2,3... ...
- 语法格式#{arg0},#{arg1}... ...
- 这种形式显然不清晰
- 3.5.1以上版本
使用Map传递参数
- 使用方法#{key}
- 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} "%" 注意在占位符两侧存在空格