02-Mybatis映射文件(Mapper.xml)配置详解
一,输入映射parameterType
第一种:简单类型
#{}表示占位符,parameterType接收简单类型的参数时,里面的名称可以任意
<select id="findUserById" parameterType="java.lang.Integer" resultType="User">
SELECT * FROM USER WHERE id = #{id}
</select>
${}表示拼接符,parameterType接收简单类型的参数时,里面的名称必须时value
<select id="findUserByName" parameterType="java.lang.String" resultType="com.qinzi.accountsystem.entity.User">
SELECT * FROM USER WHERE NAME LIKE "%${value}"
</select>
第二种类型:pojo类型
这里通过用户的用户名进行模糊查询演示pojo类型
在映射文件中添加模糊查询语句
<!--parameterType传递pojo类型-->
<select id="findUserByName" parameterType="com.qinzi.accountsystem.entity.User" resultType="com.qinzi.accountsystem.entity.User">
SELECT * FROM USER WHERE NAME LIKE "%${value}"
</select>
User类
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
测试类
public class UserDao{
//根据用户名进行模糊查询
@Override
public List<User> findUserByPojo(){
//全局配置文件路径:
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsetname("张三");
List<User> users = (List<User>)sqlSession.selectList("test.findUsersByPojo",user);//传入pojo
System.out.println(users);
sqlSession.close();
return users;
}
}
第三种:包装类型pojo
这里通过用户名和用户地址对用户进行查询来掩饰包装类型pojo:
首先创建包装pojo类:
public class UserVO {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
在映射文件中添加查询语句:
<!-- parameterType传递pojo包装类型 -->
<select id="findUsersByPojo1" parameterType="com.lc.mybatis.po.UserVO" resultType="user">
SELECT * FROM USER WHERE username LIKE "%${user.username}%" AND address=#{user.address}
</select>
测试类:
public class UserDao{
//根据用户名和地址进行查询
@Override
public List<User> findUserByPojo1(){
//全局配置文件路径:
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsetname("张三");
user.setAddress("郝汉山");
UserVO userVo = new UserVO();
userVo.setUser(user);
List<User> users = (List<User>)sqlSession.selectList("test.findUsersByPojo1",userVo);//传入pojo包装类
System.out.println(users);
sqlSession.close();
return users;
}
}
第四种:map集合类型
这里通过查询用户信息演示:
在映射文件中添加该查询语句:
<select id="findUsersByMap" parameterType="java.util.Map" resultType="user">
SELECT * FROM USER WHERE username LIKE "%${username}%" AND address=#{address}
</select>
测试方法:
public class UserDao{
//根据用户名和地址进行查询
@Override
public List<User> findUserByMap(){
//全局配置文件路径:
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
Map<String,String> map = new HashMap<>();
map.put("username","张三");
map.put("address","郝汉山");
List<User> users = (List<User>) sqlSession.selectList("test.findUsersByMap",map);//传入pojo包装类
System.out.println(users);
sqlSession.close();
return users;
}
}
二,resultType结果映射
resultType结果映射要求:
1.需要查询结果的列名和映射的对象的属性名一致,这样才能映射成功。如果映射没成功也不会报错,只是映射结果中对象的相应属性没有值,为空,如果应黑色的列名和对象中的属性名全部不一致,那么映射的对象为空。
2.如果在使用sql语句查询的时候给查询结果列设置了别名,则别名要和映射结果对象的属性名一致,这样才能保证映射成功。
第一种:简单类型
注意:如果结果映射为简单类型,则需要查询的结果为一列才能映射成功
例如:查询用户表中用户的总数。
映射文件为:
<!-- resultType:输出为简单类型 -->
<select id="findUserCount" resultType="int">
select count(*) from user;
</select>
测试代码:
public class UserDao{
@Override
public int findUserCount(){
//全局配置文件路径:
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
int userCount= sqlSession.selectOne("test.findUserCount");
System.out.println(userCount);
sqlSession.close();
return userCount;
}
}
第二种:POJO结果映射
参照pojo输入映射。
三,resultMap结果映射
使用resultMap结果映射时,不需要查询出来的结果集的列名和映射结果对象的属性名相同,但是需要声明一个resultMap,手动的方式来对列名和对象属性进行映射。(resultMap一般用于多表关联映射)
例如:通过查询用户表种的用户,并对查询出来的用户表的列名设置别名。
映射文件添加查询语句:
[id标签]: 映射结果集的唯一标识列,如果时多个字段联合唯一,则定义多个id标签
[result标签]:映射结果集的普通列
[column]: SQL查询的列名,如果列别名,则该处填写别名
[property]: pojo对象的属性名
column:列名,对应数据库中的数据字段,如果给数据库中的字段取了别名就使用别名
property:属性名,对应实体类中的属性字段
<!-- 如果查询出来的列名有别名就不能通过resultType来接收输出类型了,需要通过resultMap来声明传出类型 -->
<resultMap id="userMap1" type="com.qinzi.accountsystem.entity.User">
<!-- id标签:专门查询结果中唯一列映射 -->
<id column="id" property="id" />
<!-- result标签:映射查询结果中的普通列 -->
<result column="user_name" property="userName" />
<result column="pass_word" property="passWord"/>
</resultMap>
<select id="findUserResultMap" parameterType="int" resultMap="userMap1">
select id id,userName user_name,passWord pass_word from user id = #{id}
</select>
测试类
public class UserDao{
@Override
public User findUserResultMap(){
//全局配置文件路径:
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserResultMap",1);
System.out.println(user);
sqlSession.close();
return user;
}
}
四,动态sql
在mybaits中提供了一些动态sql标签,可以让我们开发效率更快,这些动态sql语句可以增加我们写sql语句的重用性,常用的动态sql语句标签有:if标签,sql片段(需要先定义后使用),where标签,foreach标签
通过下面例子来演示动态sql常用的标签。
需求分析:查询用户表中相关的用户
发出相关的sql语句有:
select * from user where username like “%张三%” and address=?;
select * from user;
select * from user where id in(1,2,10);
如何才能让这些语句在我们需要的时候就使用,不需要的时候就不使用。其实我们发现这三条语句有很多重复的地方,我们如果能做到让重复的能够重复使用,没有重复的可以按我们需求使用的话就能减少我们写很多sql语句。当然动态sql就是帮我们解决这些问题的。
映射文件:
<!-- 定义sql片段用于可以重用的sql片段 -->
<sql id="whereClause">
<!--if标签,可以对输入的参数进行判断-->
<!--test:判断制定的表达式-->
<if test="user!=null">
<if test="user.username!=null and user.username!=''">
AND username LIKE '%${user.username}%'
</if>
<if test="user.address!=null and user.address!=''">
AND address=#{user .address}
</if>
</if>
<if test="idList!=null">
AND id IN
<!-- foreach标签:可以循环传入参数 -->
<!-- collection:表示pojo集合中属性的属性名称 -->
<!-- item:每次便遍历出来的对象 -->
<!--open:开始遍历时拼接的串-->
<!--close:结束遍历时拼接的串-->
<!--separator:遍历每个对象之间需要拼接的字符串-->
<foreach collection="idList" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
</sql>
<select id="findUserList" parameterType="User" resultType="user">
SELECT * FROM USER
<!-- where标签: 默认去掉第一个AND,如果没有参数就去掉where自己-->
<where>
<!-- 引入sql片段 -->
<include refid="whereClause"></include>
</where>
</select>
userVo类
public class UserVO {
private User user;
private List<Integer> idList;
public List<Integer> getIdList() {
return idList;
}
public void setIdList(List<Integer> idList) {
this.idList = idList;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
测试类:
public class UserDao{
@Override
public void findUserList(){
//全局配置文件路径:
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//测试foreach语句执行
UserVO userVo = new UserVO();
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
userVo.setIdList(idList);
//测试select * from user where username like ? and address=?;
//User user = new User();
//user.setUsername("张三");
//user.setAddress("武当山");
//userVo.setUser(user);
List<User> users = sqlSession.selectOne("test.findUserList",userVo);
System.out.println(users);
sqlSession.close();
}
}