這篇文章主要介紹了Mybatis映射檔實例詳解,需要的朋友可以參考下
# 一、輸入映射
##parameterType 指定輸入參數的Java類型,可以使用別名或類別的全限定名稱。它可以接收簡單類型、POJO、HashMap。1、傳遞簡單類型
根據使用者ID查詢使用者資訊:<select id="findUserById" parameterType="int" resultType="com.itheima.mybatis.po.User"> SELECT * FROM USER WHERE id =#{id} </select>
2、傳遞POJO物件
新增使用者:<insert id="insertUser" parameterType="com.itheima.mybatis.po.User"> <selectKey keyProperty="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address}) </insert>
3、傳遞POJO包裝物件
開發中透過pojo傳遞查詢條件,查詢條件是綜合的查詢條件,不僅包括用戶查詢條件還包括其它的查詢條件(例如將用戶購買商品資訊也作為查詢條件),這時可以使用包裝物件傳遞輸入參數。
3.1需求
綜合查詢使用者訊息,需要傳入查詢條件複雜,例如(使用者資訊、訂單資訊、商品資訊)。3.2 定義包裝物件
一般User.java類別要和資料表表字段一致,最好不要在這裡面添加其他字段,在mybatis的逆向工程時,會根據表結構,產生po類,如果在po類中擴展字段,此時會被覆寫掉。 所以針對要擴展的po類,我們需要建立一個擴展類,來繼承它。public class UserExt extends User{ //这里可以定义user的一些扩展信息 }定義POJO包裝類別:
#
public class UserQueryVO { //用户信息 private UserExt userExt; //商品ID集合 private List<Integer> idList; //商品信息 public List<Integer> getIdList() { return idList; } public void setIdList(List<Integer> idList) { this.idList = idList; } public UserExt getUserExt() { return userExt; } public void setUserExt(UserExt userExt) { this.userExt = userExt; } //订单信息 }
##3.3編寫Mapper介面//透過包裝類別來進行複雜的使用者資訊綜合查詢
public List365ec941ff246bca2de9473cb1305a57 findUserList(UserQueryVO userQueryVO);3.4寫mapper映射檔
<!-- 通过包装类来进行复杂的用户信息综合查询 --> <select id="findUserList" parameterType="userQueryVO" resultType="userExt"> SELECT * FROM USER WHERE sex=#{userExt.sex} AND username LIKE '%${userExt.username}%' </select>
注意:入參的型別變成UserQueryVO、結果集的型別變成UserExt,#{}裡面的參數變成UserQueryVO物件中的userExt屬性的sex和username子屬性。
3.5寫測試程式碼
#@Test public void findUserListTest() { // 创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通过SqlSession,获取mapper接口的动态代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //构造userQueryVO对象 UserQueryVO userQueryVO = new UserQueryVO(); // 构造UserExt对象 UserExt userExt = new UserExt(); userExt.setSex("1"); userExt.setUsername("小明"); userQueryVO.setUserExt(userExt); // 调用mapper对象的方法 List<UserExt> list = userMapper.findUserList(userQueryVO); System.out.println(list); // 关闭SqlSession sqlSession.close(); }
4、傳遞HashMap同傳遞POJO物件一樣,map的key相當於pojo的屬性。
4.1映射檔案
#<!-- 传递hashmap综合查询用户信息 --> <select id="findUserByHashmap" parameterType="hashmap" resultType="user"> select * from user where id=#{<span style="color:#ff0000;">id</span>} and username like '%${<span style="color:#ff0000;">username</span>}%' </select>
上邊紅色標註的id和username是hashmap的key。
4.2測試程式碼
#Public void testFindUserByHashmap()throws Exception{ //获取session SqlSession session = sqlSessionFactory.openSession(); //获限mapper接口实例 UserMapper userMapper = session.getMapper(UserMapper.class); //构造查询条件Hashmap对象 HashMap<String, Object> map = new HashMap<String, Object>(); map.put("id", 1); map.put("username", "管理员"); //传递Hashmap对象查询用户列表 List<User>list = userMapper.findUserByHashmap(map); //关闭session session.close(); }
異常測試:
##傳遞的map中的key和sql中解析的key不一致。 測試結果沒有報錯,只是透過key取得值為空。 二、輸出映射#1、resultType
(1)使用方法
使用resultType進行結果對應時,查詢的列名和對應的pojo屬性名完全一致,該列才能對應成功。 如果查詢的列名和映射的pojo屬性名全部不一致,那麼映射的物件為空,不會創建pojo物件;如果查詢的列名和映射的pojo屬性名有一個一致,那麼映射的物件不為空,就會建立pojo對象,但是只有映射正確的那一個屬性才有值。 (2)輸出簡單類型注意,對簡單類型的結果映射也是有要求的,查詢的列必須是一列,才能映射為簡單類型。 當輸出結果只有一列時,可以使用ResultType指定簡單類型作為輸出結果類型。 2.1需求綜合查詢使用者總數,需要傳入查詢條件複雜,例如(使用者資訊、訂單資訊、商品資訊)。
2.2Mapper對應檔案#
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> <select id="findUsersCount" parameterType="UserQueryVO" resultType="int"> SELECT count(1) FROM USER WHERE sex = #{userExt.sex} AND username LIKE '%${userExt.username}%' </select>
##2.3Mapper介面
//综合查询用户信息总数。学习:resultType输出简单类型
public int findUsersCount(UserQueryVO vo);
#2.4測試程式碼
##@Test
public void testFindUsersCount() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//构造userQueryVO对象
UserQueryVO userQueryVO = new UserQueryVO();
// 构造UserExt对象
UserExt userExt = new UserExt();
userExt.setSex("1");
userExt.setUsername("小明");
userQueryVO.setUserExt(userExt);
int count = mapper.findUsersCount(userQueryVO);
System.out.println(count); // 关闭SqlSession
sqlSession.close();
}
#<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
##3.2Mapper接口
1、輸出單一pojo物件//根据用户名称来模糊查询用户信息
public User findUsersByName(String username);
2、輸出pojo清單
//根据用户名称来模糊查询用户信息列表 public List<User> findUsersByName(String username);
總結:同樣的mapper映射文件,回傳單一物件和物件清單時,mapper介面在產生動態代理的時候,
会根据返回值的类型,决定调用selectOne方法还是selectList方法。
2、resultMap
resultMap可以进行高级结果映射(一对一、一对多映射)。
(1)使用方法
如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。
1、 定义resultMap
2、 使用resultMap作为statement的输出映射类型。
(2)需求
把下面SQL的输出结果集进行映射
SELECT id id_,username username_,sex sex_FROM USER WHERE id = 1
(3)Mapper映射文件
定义resultMap:
<!-- 定义resultMap --> <!-- [id]:定义resultMap的唯一标识 [type]:定义该resultMap最终映射的pojo对象 [id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签 [result标签]:映射结果集的普通列 [column]:SQL查询的列名,如果列有别名,则该处填写别名 [property]:pojo对象的属性名 --> <resultMap type="user" id="userResultMap"> <id column="id_" property="id"/> <result column="username_" property="username"/> <result column="sex_" property="sex"/> </resultMap>
定义statement:
<!-- 根据ID查询用户信息(学习resultMap) --> <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap"> SELECT id id_,username username_,sex sex_ FROM USER WHERE id = #{id} </select>
(4)Mapper接口定义
//根据ID查询用户信息(学习resultMap) public User findUserByIdResultMap(int id);<strong> </strong>
定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMap的type类型。
(5)测试代码
@Test public void findUserByIdResultMapTest() { // 创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通过SqlSession,获取mapper接口的动态代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 调用mapper对象的方法 User user = userMapper.findUserByIdResultMap(1); System.out.println(user); // 关闭SqlSession sqlSession.close(); }
三、动态SQL
1、If和where
Ø If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。
注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘';
Ø Where标签:会去掉条件中的第一个and符号。
(1)需求
用户信息综合查询列表和用户信息综合查询总数这两个statement的定义使用动态SQL。
(2)映射文件
<!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> <select id="findUsersByQueryVO" parameterType="cn.itcast.mybatis.po.QueryUserVO" resultType="User"> SELECT * FROM USER <where> <if test="userExt != null"> <if test="userExt.sex != null and userExt.sex != ''"> AND sex = #{userExt.sex} </if> <if test="userExt.username != null and userExt.username != ''"> AND username LIKE '%${userExt.username}%' </if> </if> </where> </select> <!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> <select id="findUsersCount" parameterType="QueryUserVO" resultType="int"> SELECT count(1) FROM USER <where> <if test="userExt != null"> <if test="userExt.sex != null and userExt.sex != ''"> AND sex = #{userExt.sex} </if> <if test="userExt.username != null and userExt.username != ''"> AND username LIKE '%${userExt.username}%' </if> </if> </where> </select>
(3)Mapper接口
//通过包装类来进行复杂的用户信息综合查询 public List<UserExt> findUserList(UserQueryVO userQueryVO); //综合查询用户总数 public int findUsersCount(UserQueryVO userQueryVO);
(4)测试代码
不传用户名:
@Test public void testFindUserList() throws Exception{ // 创建UserMapper对象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 由mybatis通过sqlsession来创建代理对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); QueryUserVO vo = new QueryUserVO(); User user = new User(); //此处使用动态SQL,不传username参数 user.setSex("1"); // user.setUsername("小明"); vo.setUser(user); List<User> list = mapper.findUserList(vo); System.out.println(user); sqlSession.close(); }
输出的SQL如下(也不包含用户名):
通过测试可以得知,打印出的SQL语句确实会随着条件的满足情况而不一样。
2、SQL片段
Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。
2.1定义SQL片段
使用sql标签来定义一个SQL片段:
<!-- 定义SQL片段 --> <!-- [sql标签]:定义一个SQL片段 [id]:SQL片段的唯一标识 建议: 1、SQL片段中的内容最好是以单表来定义 2、如果是查询字段,则不要写上SELECT 3、如果是条件语句,则不要写上WHERE --> <sql id="select_user_where"> <if test="userExt != null"> <if test="userExt.sex != null and userExt.sex != ''"> AND sex = #{userExt.sex} </if> <if test="userExt.username != null and userExt.username != ''"> AND username LIKE '%${userExt.username}%' </if> </if> </sql>
2.2引用SQL片段
使用4801eb3c8c45c8edef439cb1d2a07f8a 来引用SQL片段:
<!-- 根据用户id来查询用户信息(使用SQL片段) --> <!-- [include标签]:引用已经定义好的SQL片段 [refid]:引用的SQL片段id --> <select id="findUserList" parameterType="userQueryVO" resultType="userExt"> SELECT * FROM USER <where> <include refid="select_user_where"/> </where> </select> <!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> <select id="findUsersCount" parameterType="QueryUserVO" resultType="int"> SELECT count(1) FROM USER <where> <include refid="select_user_where"/> </where> </select>
3、foreach
向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。
(1)传递pojo对象中的list集合
1.1需求
在用户查询列表和查询总数的statement中增加多个id输入查询。
1.2SQL
SELECT * FROM user WHERE id IN (1,10,16)
1.3定义pojo中的list属性
package com.itheima.mybatis.po; import java.util.List; /** * <p>Title: UserQueryVO</p> * <p>Description: TODO(这里用一句话描述这个类的作用) <p> */ public class UserQueryVO { //用户信息 private UserExt userExt; //商品ID集合 private List<Integer> idList; //商品信息 public List<Integer> getIdList() { return idList; } public void setIdList(List<Integer> idList) { this.idList = idList; } public UserExt getUserExt() { return UserExt; } public void setUserExt(UserExt userExt) { this.UserExt = UserExt; } //订单信息 }
1.4映射文件
<!-- [foreach标签]:表示一个foreach循环 --> <!-- [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 --> <!-- [item]:每次遍历出来的对象 --> <!-- [open]:开始遍历时拼接的串 --> <!-- [close]:结束遍历时拼接的串 --> <!-- [separator]:遍历出的每个对象之间需要拼接的字符 --> <if test="idList != null and idList.size > 0"> <foreach collection="idList" item="id" open="AND id IN (" close=")" separator=","> #{id} </foreach> </if>
1.5Mapper接口
//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合) public List<UserExt> findUserList(UserQueryVO vo);
1.6测试代码
@Test public void testFindUserList() { // 创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通过SqlSession,获取mapper接口的动态代理对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 构造QueryUserVO对象 QueryUserVO vo = new QueryUserVO(); // UserExt ext = new UserExt(); // ext.setUsername("小明"); // ext.setSex("1"); // vo.setUserExt(ext); // 创建用户ID集合,然后设置到QueryUserVO对象中 List<Integer> idList = new ArrayList<Integer>(); idList.add(1); idList.add(10); idList.add(16); vo.setIdList(idList); // 调用mapper代理对象的方法 List<UserExt> list = mapper.findUserList(vo); System.out.println(list); // 关闭SqlSession sqlSession.close(); }
(2)直接传递List集合
2.1需求
根据用户ID的集合查询用户列表
2.2SQL
SELECT * FROM user WHERE id IN (1,10,16)
2.3映射文件
<!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) --> <!-- [foreach标签]:表示一个foreach循环 [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 [item]:定义遍历集合之后的参数名称 [open]:开始遍历之前需要拼接的SQL串 [close]:结束遍历之后需要拼接的SQL串 [separator]:遍历出的每个对象之间需要拼接的字符 --> <select id="findUsersByIdList" parameterType="java.util.List" resultType="user"> SELECT * FROM USER <where> <if test="list != null and list.size > 0"> <foreach collection="list" item="id" open="AND id IN (" close=")" separator=","> #{id} </foreach> </if> </where> </select>
2.4Mapper接口
//根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) public List<User> findUsersByIdList (List<Integer> idList);
2.5测试代码
@Test public void findUsersByIdListTest() { // 创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通过SqlSession,获取mapper接口的动态代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 构造List<Integer>集合 List<Integer> idList = new ArrayList<Integer>(); idList.add(1); idList.add(10); idList.add(16); // 调用mapper对象的方法 List<User> list = userMapper.findUsersByIdList (idList); System.out.println(list); // 关闭SqlSession sqlSession.close(); }
以上是Mybatis映射檔的實例程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!