Mapper.xml映射文件定義了操作數據的sql,這裏的每個sql都是一個statement。
輸入映射 parameterType
- 簡單類型: int string double
- pojo
- 包裝類型的pojo
- map
- list
- 多參數傳遞
輸出映射
resultType
- 簡單類型
- pojo
- List
- map
總結
1)輸出pojo和輸出List在statement中定義的resultType類型是一致的
2)使用resultType進行輸出映射,只有查詢出來的列名和POJO中的屬性名一致才能映射成功
如果查詢出的字段和pojo中的屬性至少一個匹配就能創建pojo對象,沒有一個匹配的則不會創建pojo對象
resultMap(高級映射)
基本概念
1)如果sql查詢字段名和pojo的屬性名不一致,可以通過resultMap將字段和屬性名建立對應關係
2)resultMap可以實現將查詢結果集映射爲複雜類型的pojo,就是高級映射
使用resultMap進行輸出映射步驟
- 定義一個resultMap:將查詢的字段名和pojo中的屬性做一個映射關係
- 指定statement中的resultMap:引用resultMap
內容
- 一對一查詢
- 一對多查詢
- 多對多查詢
動態SQL
概念
含義:動態SQL就是對SQL語句進行靈活操作,通過表達式進行判斷,對sql進行靈活判斷
需求:用戶信息的綜合查詢(用戶信息,訂單信息,商品信息)
解決方案:通過動態SQL的各種標籤對查詢條件進行判斷,如果輸入參數(查詢條件)不爲空,才進行sql操作
實例
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加載外部屬性文件 -->
<properties resource="db.properties"></properties>
<!-- 別名定義 -->
<typeAliases>
<!--
1.針對單個別名定義
type:類型的路徑
alias:別名
-->
<!-- <typeAlias type="com.hpe.mybatis.po.User" alias="user"/> -->
<!--
2.批量定義別名:mybatis可以自動掃描包中的po類,自動定義別名
name:指定包名
別名:類名(首字母不區分大小)
-->
<package name="com.hpe.mybatis.po"/>
<!-- 可以指定多個package -->
</typeAliases>
<!-- 類型處理器的配置 -->
<!-- 配置Mybatis運行環境 -->
<!-- 將來和spring整合之後,配置運行環境就廢棄了 -->
<environments default="development">
<environment id="development">
<!-- 事務管理器:使用JDBC事務管理 -->
<transactionManager type="JDBC" />
<!-- 配置數據庫連接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加載映射文件 -->
<mappers>
<!-- <mapper resource="mybatis/UserMapper.xml"/> -->
<!-- 1.resource:只能加載一個映射文件,指的是相對於類路徑的資源 -->
<!-- <mapper resource="UserMapper.xml"/> -->
<!-- <mapper url=""/> -->
<!-- 2.class:使用mapper接口類路徑的方式
要求:此種方式要求mapper接口的名稱和mapper映射文件名稱相同且在同一個目錄
-->
<!-- <mapper class="com.hpe.mybatis.mapper.UserMapper"/> -->
<!-- 3.批量加載 name:指定mapper接口的包名,mybatis會自動掃描包下的所有接口進行加載
要求:此種方式要求mapper接口的名稱和mapper映射文件名稱相同且在同一個目錄
規範:使用mapper接口類路徑的方式和批量加載的方式前提是使用mapper動態代理的開發方式
-->
<package name="com.hpe.mybatis.mapper"/>
</mappers>
</configuration>
mapper.java接口文件
package com.hpe.mybatis.mapper;
import java.util.List;
import com.hpe.mybatis.po.User;
import com.hpe.mybatis.po.UserQueryVo;
public interface UserMapper {
// 完成用戶的綜合查詢(姓名和性別)
List<User> findUserByQuery(UserQueryVo userQueryVo);
// 獲取用戶記錄總數
int findUserCount();
// 根據id查詢用戶信息
User findUserById(int id);
// 根據用戶名模糊查詢用戶信息
List<User> findUserByName(String name);
// 根據用戶id查詢用戶信息(根據輸出映射)
User findUserByIdResultMap(int id);
// 用戶信息綜合查詢2(使用用戶名、性別作爲查詢條件)
List<User> findUserByUser(User user);
// 根據用戶id更新用戶信息
int updateUser(User user);
}
mapper.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="com.hpe.mybatis.mapper.UserMapper">
<!-- 定義resultMap:對查詢的column和property建立對應關係
type:輸出映射所對應的Java對象類型,可以使用別名
id:對這個resultMap的唯一標識
-->
<resultMap type="User" id="userResultMap">
<!-- id:查詢結果集中的唯一標識(表中的主鍵)
property:type指定的pojo類型中的屬性名
column:查詢出來的列名
-->
<id column="userId" property="id"/>
<!-- 對普通列進行映射 -->
<result column="name" property="username"/>
<result column="sex_" property="sex"/>
<result column="address_" property="address"/>
</resultMap>
<!-- 定義SQL片段:可以實現共享,作爲綜合查詢條件的一部分
注意:基於單表定義的SQL判斷,SQL片段的重用性比較高
id:sql片段的唯一標識
在SQL中不要加上where,一個SQL可能增加多個SQL片段
-->
<sql id="query_user">
<if test="username!=null and username!=''">
AND username LIKE '%${username}%'
</if>
<if test="sex!=null and sex!=''">
AND sex = #{sex}
</if>
</sql>
<!-- 根據姓名和性別查詢 -->
<select id="findUserByQuery" parameterType="UserQueryVo" resultType="User">
SELECT * FROM user WHERE username LIKE '%${user.username}%' AND sex = #{user.sex}
</select>
<!-- 獲取用戶記錄總數 -->
<select id="findUserCount" resultType="int">
SELECT COUNT(*) FROM user
</select>
<!-- 根據id查詢用戶信息 -->
<select id="findUserById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<!-- 根據用戶名模糊查詢用戶信息 -->
<select id="findUserByName" parameterType="string" resultType="User">
SELECT * FROM user WHERE username LIKE '%${value}%'
</select>
<!-- 使用resultMap進行輸出映射
resultMap:引用resultMap的id,如果引用的resultMap在其他map文件中,需要加上namespace
-->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
SELECT id userId,username name,sex sex_,address address_ FROM user WHERE id = #{id}
</select>
<!-- 使用動態SQL實現用戶查詢
根據user的username和sex屬性是否爲空,動態生成SQL
-->
<select id="findUserByUser" parameterType="User" resultType="User">
SELECT * FROM user
<!-- where:可以自動去掉條件中的第一個and -->
<where>
<!-- 引入SQL片段
refid:指定SQL片段的標識(id)
如果引入的SQL片段不在次mapper.xml文件中,需要加上namespace
可以引入多個SQL片段
-->
<include refid="query_user"></include>
</where>
</select>
<!-- 根據用戶id更新用戶信息 -->
<update id="updateUser" parameterType="User">
<!-- UPDATE user SET username = #{username},sex = #{sex},address = #{address} WHERE id = #{id} -->
UPDATE user
<!-- set:會動態前置set關鍵字,同時會消除sql語句中多餘的逗號 -->
<set>
<if test="username!=null and username!=''">
username = #{username},
</if>
<if test="sex!=null and sex!=''">
sex = #{sex},
</if>
<if test="address!=null and address!=''">
address = #{address},
</if>
</set>
WHERE id = #{id}
</update>
</mapper>
測試test
package com.hpe.mybatis.test;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 com.hpe.mybatis.mapper.UserMapper;
import com.hpe.mybatis.po.User;
import com.hpe.mybatis.po.UserQueryVo;
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創建會話工廠,傳入Mybatis配置信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
// 用戶信息的綜合查詢
@Test
public void testFindUserByQuery(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
User user = new User();
user.setUsername("小");
user.setSex("2");
userQueryVo.setUser(user);
List<User> list = userMapper.findUserByQuery(userQueryVo);
sqlSession.close();
System.out.println(list);
}
// 查詢用戶記錄總數
@Test
public void testFindUserCount(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int count = userMapper.findUserCount();
sqlSession.close();
System.out.println(count);
}
// 根據id查詢用戶信息
@Test
public void testFindUserById(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
sqlSession.close();
System.out.println(user);
}
// 根據用戶名模糊查詢用戶信息
@Test
public void testFindUserByName(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByName("小");
sqlSession.close();
System.out.println(list);
}
// 根據用戶名id查詢用戶信息(輸出ResultMap)
@Test
public void testFindUserByIdResultMap(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserByIdResultMap(1);
sqlSession.close();
System.out.println(user);
}
// 根據動態SQL查詢用戶信息
@Test
public void testFindUserByUser(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setSex("2");
user.setUsername("小");
List<User> list = userMapper.findUserByUser(user);
sqlSession.close();
System.out.println(list);
}
// 根據動態SQL根據用戶id更新用戶信息
@Test
public void testUpdateUser(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(26);
user.setSex("2");
//user.setUsername("小");
int count = userMapper.updateUser(user);
sqlSession.commit();
sqlSession.close();
System.out.println(count);
}
}
動態SQL的foreach標籤
UserMapper.java
// 查詢多個用戶的信息
List<User> selectUserById(List<Integer> ids);
UserMapper.xml
<!-- 查詢多個用戶信息:可以使用兩種方式實現
1.SELECT * FROM user WHERE id = 24 OR id = 25
2.SELECT * FROM user WHERE id IN (24,25)
-->
<select id="selectUserById" parameterType="list" resultType="User">
SELECT * FROM user WHERE
<!-- 第一種方式
1.collection:指定輸出對象中的集合屬性,其值list:是默認情況使用
其值也可以用註解的方式在接口方法參數處聲明集合名稱
2.item:集合遍歷的每個對象(集合中迭代的別名)
3.open:foreach代碼的開始符號
4.close:foreach代碼的結束符號
5.separator:元素之間的分隔符
-->
<!-- <foreach collection="list" item="id" open="(" close=")" separator="OR">
每次遍歷要拼接的串
id = #{id}
</foreach> -->
<foreach collection="list" item="id" open="id IN (" close=")" separator=",">
<!-- 每次遍歷要拼接的串 -->
#{id}
</foreach>
</select>
UserMapperTest.java
// 查詢多個用戶信息
@Test
public void testSelectUserByIds(){
// 根據會話工廠創建會話
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用mybatis動態代理的方式生成代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(24);
ids.add(25);
ids.add(26);
List<User> list = userMapper.selectUserById(ids);
sqlSession.close();
System.out.println(list);
}