一、 mybatis的参数
(1) 映射文件中的mapper标签中的 parameterType resultType 函数形参的类型:
基 本类 型和 String 我 们可 以直接 写类型 名称 ,也 可以 使用包 名 . 类名的 方式 ,例如 :可以写 int INT INTEGER Integer java.lang.Integer 等等
实体类类型,目前我们只能使用全限定类名。
究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,而我们的是实体类并没有注册别名,所以必须写 全限定类名。在 mybatis 的官方文档的说明(第 19 页)
(2) 传递简单类型:int String char booean 等等
(3) 传递pojo(封装的实体类)对象: 实体类对象
Mybatis使用ognl表达式解析对象字段的值 #{ }或者 ${ } 中的值为pojo属性名称
什么是OGNL表达式??
(1) Object Graphic Navigation Language
对象 图 导航 语言
(2) 他是通过对对象取值的方法来获取数据。在写法上把get省略了。
类中的写法: user.getUsername()
OGNL的写法: user.username
(3) mybatis中为什么可以直接写username,而用user.username呢??
应为在mybatis中parameterType 已经提供了属性所属的类,不需要在写对象名
(实际上是resultType将查询到结果映射封装成pojo类型中,前提是该pojo类的**属性名**和查询到的数据库表的**字段名一致**)
如果当使用ognl表达式的时候,上面parameterType 属性没有提供该类的时候只能写全user.username
比如: 在写sql语句的时候 '%${username}%' #{birthday}
#{username} 就相当于user.username调用传入的User对象username属性
(4) 传递pojo包装类对象
在开发中使用pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其他查询条件(比如将用户购买商品信息作为查询条件),这时可以使用包装对象传递参数。Pojo类包含pojo
(把查询信息的实体类对象在包装一层,成为一个新的包装对象)
案例: 查询姓名中带“王”的所有user,查询条件放到QueryVo对象中的user属性中
第一步:声明好QueryVo对象
public class QueryVo {
private User user;
public QueryVo(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
第二步:接口中添加方法
//根据QueryVo对象中的条件查询用户
List<User> findUserByVo(QueryVo queryVo);
第三步:映射文件的<mapper>标签中配置
<!-- pojo包装类对象 -->
<!-- #{} pojo会先根据parameterType属性找到传入对象的类型 -->
<!-- #{user.username} 是传入的QueryVo对象的user.username值 -->
<select id="findUserByVo" resultType="com.zy.domain.User" parameterType="com.zy.domain.QueryVo">
select * from user where username like #{user.username}
</select>
第四步:测试方法
User user = new User();
user.setUsername("%王%");
QueryVo queryVo = new QueryVo(user);
List<User> all = iUserDao.findUserByVo(queryVo);
for (User temp:all) {
System.out.println(temp.toString());
}
二、Mybatis的输出结果封装
(1) 简单的 int String等等
(2)输出pojo(封装的实体类)的对象
(3)输出pojo(封装的实体类)列表(这里的pojo指的都是实体类)
(4) (重点)一般都会把 数据库的列表属性 和 实体类点的属性 一一对应,相同的来写:
如果所对应的属性名称不一样,就会显示不到相应的是数据库中的值
(应为mysql的不区分大小写,实体类上的属性与数据库列表属性可以不区分大小写,也可以进行匹配)
当实体类上的属性与数据库的列名不对应,应该怎么进行匹配??
方法一: 在sql语句上起别名(数据库列的别名对应为实体类的属性名)
可以发现,建立的实体类的属性与数据库中的列名不相同(在以下查询的sql语句中进行起别名)
select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;
方法二:配置 查询结果的列名和实体类的属性名的对应关系 在映射文件的<mapper>标签中写<resultMap>标签
(1) resultMap属性和resultType属性实现的是同样的功能: 都是提供要把数据库查询到的结果封装为什么类型的(结果类型)
(2) resultType属性 封装数据库查询的结果的时候:类的**属性名**和查询到的数据库表的**字段名一致**
(3) resultMap属性 是当类的**属性名**和查询到的数据库表的**字段名一致**不一致的时候,设置应该产生一个什么样的映射关系?
(4)<resultMap>可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
(5) <resultMap>标签的使用:https://www.jianshu.com/p/df86cb39d672
(6) 怎么使用<resultMap>标签设置的结果集??? 在resultMap属性等于<resultMap>设置的关系
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
<!-- 相当于配置一种映射的返回结果的封装类型,把在数据库查询到的结果和某一个类联系起来-->
<!-- 因为要把结果放到某个类中,但是与数据库的列名又不对应-->
<!-- 通过该标签把数据库的列名与实体类属性名进行配对-->
<!-- id属性 随便起一个名字,唯一标志,方便使用这个结果映射-->
<!-- tepe属性 对应的是哪一个实体类-->
<resultMap id="UserMap" type="com.zy.domain.User">
<!--主键字段的对应-->
<!--property属性 为上面type属性指向实体类对象的属性(对应java类的属性:严格区分大小写)-->
<!--column属性 数据库表的列名-->
<!--javaType属性 java中的数据类型-->
<!--jdbcType属性 数据库中的数据类型-->
<!--typeHandler属性 -->
<!-- 因为我们的属性和列都是有类型的,不写javaType属性和jdbcType属性 也是可以的-->
<id property="userId" column="" ></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
<!-- 返回的结果的封装类型不再用 resultType="com.zy.domain.User" -->
<!-- 用刚刚创建好的映射的结果类型 -->
<!--resultMap和resultType这两个属性其实是实现同一个功能-->
<select id="findAll" resultMap="UserMap" >
<!--select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;-->
select * from user;
</select>
(resultMap就是为了是存放的实体类和数据库表的字段进行一一的对应
(注意:一定对应的最基本的类型的对应关系))