您的位置:首页 > 移动开发

Mybatis学习总结(四).Mapper映射文件

2017-02-07 21:22 603 查看
Mapper映射文件是在实际开发过程中使用最多的。Mapper文件中包含的元素有:
cache – 配置给定命名空间的缓存。
cache-ref – 从其他命名空间引用缓存配置。
resultMap – 映射复杂的结果对象。
sql – 可以重用的 SQL 块,也可以被其他语句引用。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句

select – 映射查询语句

<select id="queryUserById" resultType="User" parameterType="Long">
SELECT * FROM tb_user WHERE id = #{id}
</select>

id:是当前命名空间下的Statement的唯一标识(必须属性);

parameterType:输入的参数类型(可以省略);

resultType:将结果集映射为的java对象类型(必须属性);

标签内部:编写SQL语句

insert – 映射插入语句

<insert id="saveUser" parameterType="cn.zto.mybatis.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
NULL,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>

id:是当前命名空间下的Statement的唯一标识(必须属性);

parameterType:输入的参数类型(可以省略);

标签内部:编写SQL语句

获取自增Id

<!-- useGeneratedKeys: 开启自增id回填
keyColumn: 指定数据库表中列名
keyProperty: 指定对象的属性名
如果keyColumn 和 keyProperty 相同,则keyColumn可以省略不写 -->
<insert id="saveUser" parameterType="cn.zto.mybatis.pojo.User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
NULL,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>

@Test
public void testSaveUser() {
User user = new User();
user.setAge(20);
user.setBirthday(new Date());
user.setName("test_3");
user.setPassword("123456");
user.setSex(1);
user.setUserName("test_username_3");

this.userMapper.saveUser(user);
//获取自增id
System.out.println("id:"+user.getId());
}

update – 映射更新语句

<update id="updateUser" parameterType="cn.zto.mybatis.pojo.User">
UPDATE tb_user
SET
user_name = #{userName},
password = #{password},
name = #{name},
age = #{age},
sex = #{sex},
birthday = #{birthday},
updated = NOW()
WHERE
id = #{id}
</update>

id:是当前命名空间下的Statement的唯一标识(必须属性);

parameterType:输入的参数类型(可以省略);

标签内部:编写SQL语句

delete – 映射删除语句

<delete id="deleteUserById">
DELETE FROM tb_user WHERE id = #{id}
</delete>

id:是当前命名空间下的Statement的唯一标识(必须属性);

parameterType:输入的参数类型(可以省略);

标签内部:编写SQL语句


parameterType的传入参数

传入类型有三种:

1、简单类型,string、long、integer等
2、Pojo类型,User等
3、HashMap类型。

在使用#{}传参时,#{}只是做占位符,与参数名无关。

在使用${}传参时,是通过参数名获取参数的,如果没有指定参数名则可以通过value获取,如果指定则需要按照名称获取。

parameterType的传入多个参数

当Mapper接口中需要传递多个参数时有两种方法传递:

使用默认规则获取参数;
使用@Param注解表明参数传递;

其实parameterType参数是可以省略的

UserMapper.java
package cn.zto.mybatis.mapper;

import cn.zto.mybatis.pojo.User;

public interface UserMapper {

/**
* 模拟登陆
* @Title: login
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @param userName
* @param: @param passwd
* @param: @return
* @return: User
* @throws
*/
public User login(String userName,String passwd);

}


UserMapper.xml
<?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="cn.zto.mybatis.mapper.UserMapper">

<select id="login" resultType="User" >
SELECT * FROM tb_user WHERE user_name = #{userName} and password = #{passwd}
</select>

</mapper>


测试
package cn.zto.mybatis.mapper;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.zto.mybatis.pojo.User;

/**
* 动态代理实现类测试用例
*
*/
public class UserMapperTest {

private UserMapper userMapper;

@Before
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "test");
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过sqlSession获取到动态代理的实现类
this.userMapper = sqlSession.getMapper(UserMapper.class);
}

@Test
public void testLogin() {
User user = this.userMapper.login("zhangsan","123");
System.out.println(user);
}

}


结果出错,错误信息参数userName找不到,可用参数为0,1,param1,param2



修改参数:
<select id="login" resultType="User" >
<!-- SELECT * FROM tb_user WHERE user_name = #{userName} and password = #{passwd} -->
SELECT * FROM tb_user WHERE user_name = #{0} and password = #{1}
</select>
或者:
<select id="login" resultType="User" >
<!-- SELECT * FROM tb_user WHERE user_name = #{userName} and password = #{passwd} -->
SELECT * FROM tb_user WHERE user_name = #{param1} and password = #{param2}
</select>
测试通过。这种方式为使用默认规则参数,还有一种是通过@param注解获取参数
/**
* 模拟登陆
* @Title: login
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @param userName
* @param: @param passwd
* @param: @return
* @return: User
* @throws
*/
public User login(@Param("userName")String userName,@Param("passwd")String passwd);

<select id="login" resultType="User" >
SELECT * FROM tb_user WHERE user_name = #{userName} and password = #{passwd}
<!-- SELECT * FROM tb_user WHERE user_name = #{param1} and password = #{param2} -->
</select>

ResultType结果输出

输出类型有三种:
简单类型,string、long、integer等
Pojo类型,User等
HashMap类型。

‘#{}’与‘${}’的区别

在Mybatis的mapper中,参数传递有2种方式,一种是#{}另一种是${},两者有着很大的区别:

 
#{} 实现的是sql语句的预处理参数,之后执行sql中用?号代替,使用时不需要关注数据类型,Mybatis自动实现数据类型的转换。并且可以防止SQL注入。 
${} 实现是sql语句的直接拼接,不做数据类型转换,需要自行判断数据类型。不能防止SQL注入。

 

是不是${}就没用了呢?不是的,有些情况下就必须使用${},举个例子:

在分表存储的情况下,我们从哪张表查询是不确定的,也就是说sql语句不能写死,表名是动态的,查询条件的固定的,这样:SELECT * FROM ${tableName} WHERE id = #{id}

CommonMapper.java
package cn.zto.mybatis.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

public interface CommonMapper {

/**
* 根据表名查询表数据
*
* @param id
* @return
*/
public List<Map<String,Object>> queryByTableName(@Param("tableName")String tableName);

}
CommonMapper.xml
<?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="cn.zto.mybatis.mapper.CommonMapper">
<!--SELECT * FROM ${value}     ${value}:value是mybatis默认的参数名-->
<!--在接口中通过@Param来自定义参数名 -->
<select id="queryByTableName" resultType="HashMap" parameterType="String">
SELECT * FROM ${tableName}
</select>
</mapper>


测试
@Test
public void queryByTableName() {
List<Map<String, Object>> queryByTableName = this.commonMapper.queryByTableName("tb_user");
for (Map<String, Object> map : queryByTableName) {
System.out.println(map);
}
}


总结:

#{} 占位符,用于参数传递,和参数名称无关。

${}用于SQL拼接。

resultMap – 映射复杂的结果对象

ResultMap是Mybatis中最重要最强大的元素,使用ResultMap可以解决两大问题:

POJO属性名和表结构字段名不一致的问题(有些情况下也不是标准的驼峰格式)

完成高级查询,比如说,一对一、一对多、多对多。

解决表字段名和属性名不一致的问题有两种方法:

1、如果是驼峰似的命名规则可以在Mybatis配置文件中设置<setting name="mapUnderscoreToCamelCase" value="true"/>解决

2、使用ResultMap解决。

3、还可以起别名.





SQL片段

我们在java代码中会将公用的一些代码提取出来需要的地方直接调用方法即可,在Mybatis也是有类似的概念,那就是SQL片段。

在Mybatis中使用<sql id=”” />标签定义SQL片段,在需要的地方通过<include refid=“”/>引用

例如:
<sql id="userColumns">id,user_name,password,name,age,sex,birthday,created,updated</sql>

<select id="queryUserById" resultMap="userResultMap" parameterType="Long">
SELECT <include refid="userColumns"/> FROM tb_user WHERE id = #{id}
</select>

另外一种用法:

将所有的公用的SQL片段集中定义到一个Mapper.xml文件中,并将此Mapper.xml加入到全局配置文件mybatis-config.xml  ,其他Mapper.xml文件如需引入,通过命名空间.id即可。

<?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="my.common">

<sql id="userColumns">id,user_name,password,name,age,sex,birthday,created,updated</sql>

</mapper>

加入全局配置文件mybatis-config.xml
<mappers>
<mapper resource="UserMapper.xml" />
<mapper resource="CommonMapper.xml" />
</mappers>

在mapper映射文件中引用:
<select id="queryUserById" resultMap="userResultMap" parameterType="Long">
SELECT <include refid="my.common.userColumns"/> FROM tb_user WHERE id = #{id}
</select>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: