SQL映射文件
Mybatis的强大之处在于SQL映射语句,SQL映射文件配置可以减少50%以上的代码。下面列出SQL映射文件的几个顶级元素配置。
- mapper: 映射文件的根元素节点,只有一个属性namespace(命名空间)。其作用如下:
- 用于区分不同的mapper,全局唯一
- 绑定DAO接口,即面向接口编程。当namespace绑定某一接口后,可以不用该接口的实现类,Mybatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句。因此namespace的命名必须跟接口同名。
- cache:配置给命名空间的缓存。
- cache-ref:从其他命名空间引用缓存配置。
- resultMap:用来描述数据库结果集和对象的对应关系。
- sql:可以重用的SQL块,也可以被其他语句引用
- insert:映射插入语句。
- update:映射更新语句。
- delect:映射删除语句。
- select:映射查询语句。
Mybatis的SQL映射文件中的mapper元素的namespace属性有如下要求:
(1)namespace的命名必须跟某个DAO接口同名,同属于DAO层,故在代码结构上,映射文件与该DAO接口应放在同一个package上,并习惯接口和mapper文件都是以Mapper结尾。
(2)在不同的mapper文件中,子元素的id可以相同,Mybatis通过namespace和子元素的id联合区分。接口中的方法与映射文件中SQ语句 id 一一对应。
单条件查询根据
以根据用户名模糊查询来获取用户列表为例,SQL映射语句如下所示:
由于在mybatis-config.xml中配置了:
<typeAliases>
<package name="sqlmapper"/>
</typeAliases>
所以参数类型和返回类型直接是类名,而不用加包名。
<?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="sqlmapper.UserMapper">
<insert id="addUser" parameterType="User">
insert into
userinfo(username,password,age)
values(#{username},#{password},#{age})
</insert>
<update id="updateUser" parameterType="User">
update userinfo
set
username=#{username},password=#{password},age=#{age}
where id=#{id}
</update>
<select id="getUserinfoById" parameterType="int" resultType="User">
select * from userinfo where id = #{id}
</select>
<!-- 根据用户名查询用户列表(模糊查询) -->
<select id="getUserListByUsername" parameterType="string"
resultType="User">
select * from userinfo
<where>
username like CONCAT('%',#{username},'%')
</where>
</select>
</mapper>
这是一个id为getUserListByUsername的映射语句,参数类型为 string ,返回结果的类型为 User 。为了使数据库查询的结果和返回类型中的属性能够自动匹配,对于MySQL数据库和JavaBean 都会采用Java命名驼峰规则,这样就不需要再做映射。(注:如果数据库的字段名和属性名不一致则需要手动映射)。参数的传递使用#{ 参数名 }。
接口类的代码如下:
public interface UserMapper {
public int addUser(User user);
public int updateUser(User user);
public User getUserinfoById(int id);
public ArrayList<User> getUserListByUsername(String username);
}
多条件查询
1、封装成JavaBean 进行入参
对于多条件查询,我们可以吧查询条件封装成对象进行入参。
改造UserMapper.java 代码:
public interface UserMapper {
public ArrayList<User> getUserList(User user);
}
改造UserMapper.xml代码:
<select id="getUserList" resultType="sqlmapping.User"
parameterType="sqlmapping.User">
select * from user
where username like CONCAT('%',#{username},'%') and userRole =#{userrole}
</select>
改造测试类:
User user = new User();
user.setUsername("l");
user.setUserrole(1);
userList = sqlSession.getMapper(UserMapper.class).getUserList(user);
示例中把条件参数封装成User对象进行入参,对User对象中 username 和 userrole 两个属性分别进行赋值,在映射查询语句中设置参数类型为User类型,传入的参数分别使用 #{username} 和 #{userrole}来表示,你就#{属性名}(参数对象的属性名)。
2、封装成 Map 类型进行入参
参数类型除了 JavaBean 之外,还有 Map 类型。代码如下:
改造测试类:
Map<String,String> userMap = new HashMap<String,String>();
userMap.put("uName", "sc");
userMap.put("uRole", "1");
userList = sqlSession.getMapper(UserMapper.class).getUserListByMap(userMap);
改造UserMapper.java 代码,把封装好的 userMap 作为参数传入接口的方法 :
public interface UserMapper {
public ArrayList<User> getUserListByMap(Map<String,String> userMap);
}
改造UserMapper.xml代码,把 parameterType=“Map” ,SQL 语句中的参数值使用 #{uName} 和 #{uRole} 来表示,即#{ Map 的 key},代码如下:
<select id="getUserListByMap" resultType="sqlmapping.User"
parameterType="Map">
select * from user
where username like CONCAT('%',#{uName},'%') and userRole =#{uRole}
</select>
自定义查询结果
resultMap 元素用来描述如何将结果集映射到 Java 对象,当数据库的字段名和 POJO 中的属性名不一致的情况下或者需要做复杂的联合查询是,就要用到 resultMap 自定义查询结果。
resultMap 元素的属性值和子节点:
- id 属性:唯一标识,此 id 值用于对 select 元素 resultMap 属性的引用。
- tyype 属性:表示该 resultMap 的映射结果类型。
- result 子节点:用于标识一些简单属性,其中 column 属性表示从数据库中查询的字段名, property 则表示查询出来的字段对应的值赋给实体对象的哪个属性。
实例,在 UserMapper.xml 中:
<resultMap id="BaseResultMap" type="sqlmapping.User">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="password" property="password" />
<result column="age" property="age" />
<result column="telephone" property="telephone" />
<result column="userRole" property="userrole" />
</resultMap>
注意:resultType 和 resultMap 本质上是一样的,在 select 元素中两个属性不能同时存在。
设置 resultMap 的自动映射级别
在 mybatis-config.xml 文件中:
<settings>
<!-- 设置日志输出为 LOG4J -->
<setting name="logImpl" value="LOG4J" />
<!-- 设置 resultMap 的自动映射级别为 NONE(禁止自动匹配) -->
<setting name="autoMappingBehavior" value="NONE"/>
</settings>
在 Mybatis 中,使用 resultMap 能够进行自动映射匹配的前提是字段名和属性名必须一致,在默认映射级别(PARTIAL)中,若字段名和属性名一致,即使在 resultMap 的定义中没有做属性名和字段名的匹配,也可以在后台获取到未匹配过的属性值;若字段名和属性名不一致,且在 resultMap 中没有做映射,那么就无法在后台获取输出。还可以设置为 FULL ,这样如果字段名和类中的对象(以一个类对象作为属性)的属性名一致,就会给类中的对象的属性值赋值。
多参数入参
当参数为基础数据类型时,不管是多参数入参,还是单独的一个参数入参,都需要使用 @Param 注解来进行参数传递。
示例代码如下,修改UserMapper 接口,使用基础类型数据入参时:
public int updatePwd(@Param("id")Integer id,@Param("userPassword")String pwd);
使用注解 @Param 来传入多个参数,如 @Param(“userPassword”)String pwd),相当于将该参数pwd重命名为userPassword,在映射的SQL语句中需要使用 #{注解名称},如 #{userPassword} 。
<update id="updatePwd">
update user set userPassword = #{userPassword} where id = #{id]
</update>