一、参数设置
当传入多个参数时,我们需要使用@Param
注解进行取名,而不是使用每种类型默认的参数名。
源码定位到:MapperMethod#convertArgsToSqlCommandParam
,最终可以看出参数是存在一个Map集合
中(param)。
1.1 普通类型
User findUserById(int id);
<select id="findUserById" resultType="com.shang.pojo.User">
select * from user where id = #{id}
</select>
User findUser(@Param("id") int id,@Param("name") String name);
<select id="findUser" resultType="com.shang.pojo.User">
select * from user where id = #{id} and name = #{name}
</select>
1.2 对象类型
一般情况下,#{}
中可以直接使用对象中的属性名称。但如果使用注解@Param("xxx")
,则必须使用xxx.属性名
。
User findByUser(User user);
<select id="findByUser" resultType="com.shang.pojo.User">
select * from user where id = #{id} and name = #{name}
</select>
// 对象类型加上@Param,使用 xxx.属性名取值
User findByUser(@Param("user") User user);
<select id="findByUser" resultType="com.shang.pojo.User">
select * from user where id = #{user.id} and name = #{user.name}
</select>
1.3 Map类型
#{}
里的名称为map中的 key ,一般情况下,可以直接使用key的值。但如果给Map使用注解@Param("xxx"),则必须是 xxx.key。
User findUserByMap(Map<String,Object> map);
<select id="findUserByMap" resultType="com.shang.pojo.User">
select * from user where id = #{id} and name = #{name}
</select>
User findUserByMap(@Param("user") Map<String,Object> map);
<select id="findUserByMap" resultType="com.shang.pojo.User">
select * from user where id = #{user.id} and name = #{user.name}
</select>
1.4 Array类型与List类型
List类型与Array必须使用@Param注解,且注解中的value值要与foreach中的collection值对应。如果不使用,则collection值是默认值 list、array等(不建议使用)。
List<User> findAll(@Param("ids") List<Integer> ids);
<select id="findAll" resultType="com.shang.pojo.User">
select * from user where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
List<User> findAllArr(@Param("ids") Integer[] ids);
<select id="findAllArr" resultType="com.shang.pojo.User">
select * from user where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
二、结果映射
2.1 一对一映射
每个mapper都定义各自对应的BasexxxMap,可通过extends
来继承当前mapper文件的BasexxxMap。
一对一需使用association
,可通过resultMap的全路径名称定位到另一个mapper中的BasexxxMap,columnPrefix为其中的字段加前缀。
// ArticleMapper.java
List<Article> findAll();
// ArticleMapper.xml
<mapper namespace="com.shang.mapper.ArticleMapper">
<resultMap id="BaseArticleMap" type="com.shang.pojo.Article">
<id property="id" column="id"/>
<result property="title" column="title"/>
<result property="a_id" column="a_id"/>
</resultMap>
<resultMap id="articleMap" type="com.shang.pojo.Article" extends="BaseArticleMap">
<association property="author" javaType="com.shang.pojo.Author" columnPrefix="author_"
resultMap="com.shang.mapper.AuthorMapper.BaseAuthorMap"/>
</resultMap>
<select id="findAll" resultMap="articleMap">
select ar.*,au.id as author_id,au.name as author_name from article ar,author au
where ar.a_id = au.id
</select>
</mapper>
// AuthorMapper.xml
<mapper namespace="com.shang.mapper.AuthorMapper">
<resultMap id="BaseAuthorMap" type="com.shang.pojo.Author">
<id property="id" column="id"/>
<result property="name" column="name"/>
</resultMap>
</mapper>
2.2 一对一映射(懒加载)
select
指定使用哪一个sql查询;fetchType
指定为懒加载;column
指定sql需要的参数。
column="{aid=a_id}"分析,aid
表示select中的入参名
,a_id
表示从当前sql查询的列名
。
<resultMap id="articleMap1" type="com.shang.pojo.Article" extends="BaseArticleMap">
<association property="author" javaType="com.shang.pojo.Author" columnPrefix="author_"
select="com.shang.mapper.AuthorMapper.findById" column="{aid=a_id}" fetchType="lazy"/>
</resultMap>
Article findArticles(int id);
// 查询出 a_id 列
<select id="findArticles" resultMap="articleMap1">
select * from article where id = #{id}
</select>
// 入参名 aid
Author findById(int aid);
<select id="findById" resultMap="BaseAuthorMap">
select * from author where id = #{aid}
</select>
2.3 一对多映射 和 一对多映射(懒加载)
与一对一基本 相似,除了需要指定ofType
三、返回主键
方式一
useGeneratedKeys="true"
表示启用生成主键,keyProperty="id"
表示生成的主键绑定到id属性上。
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into user(id,name,age) values(#{id},#{name},#{age})
</insert>
通过 user.getId()
就可以拿到插入的最新数据的id。
@Test
public void addUser() throws IOException {
User user = new User();
user.setName("嬴政");
user.setAge(13);
sqlSession.insert("com.shang.mapper.UserMapper.insertUser",user);
System.out.println("id==>"+user.getId());
sqlSession.commit();
}
方式二
<insert id="insertUser">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user(id,name,age) values(#{id},#{name},#{age})
</insert>