20200104——复习mapper的配置文件

SqlMapConfig.xml
mybatis的全局文件
SqlMapConfig.xml中配置的内容和顺序如下:

properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)

properties属性
在这里插入图片描述
在我们的总配置文件中,这些东西都是参数变量,像数据库的密码,用户名还有地址什么的。如果需要更改了,不方便。我们把这些数据库连接的参数,单独的配置在db.properties中,只需要在SqlMapConfig.xml中加载该配置文件的属性值。

在sqlmapconfig不需要对数据库连接参数硬编码了

加载方法,有一个标签properties这个标签,里面有一个属性直接链接到写好的db.properties即可。
在这里插入图片描述
除了在外部引用文件,还可以在内部自定义属性,然后直接调用也即可

        <property name="" value=""></property>

注意: MyBatis 将按照下面的顺序来加载属性:
在 properties 元素体内定义的属性首先被读取。
然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
最后读取parameterType传递的属性,它会覆盖已读取的同名属性。

因此,通过parameterType传递的属性具有最高优先级,resource或 url 加载的属性次之,最低优先级的是 properties 元素体内定义的属性。

建议不要在properties元素体内添加任何的值,只将属性值定义在properties体内,
在properties文件中定义的属性名要有一定的特殊性

settings全局参数配置
mybatis框架在运行时,可以调整一些运行参数
比如:开启二级缓存,开启延迟加载

mybatis全局配置参数,如果运用不当,会影响mybatis的运行行为

typeAliases 别名
需求:在mapper.xml中定义了很多的statement,statement需要parameterType指定输入参数的类型,resultType指定输出结果的映射类型

如果在指定类型,输入类型的全路径不方便开发,可以定义一些别名。
可以针对parameter或者result指定的类型定一些别名
在mapper.xml中定义别名,方便开发

mabatis 支持默认别名,但是对于pojo类型需要自己调配

针对单个别名定义,这里用User进行定义
在这里插入图片描述

可以在mapper.xml中的resultType直接写入user
在这里插入图片描述

更改完别名程序依然运行成功
在这里插入图片描述
批量别名定义
如果我们到时候在这里插入图片描述
pojo类有很多,我们不可能一个一个导入,这样就有了批量别名定义

        <package name="cn.mmz.mybatis.pojo"></package>

批量定义别名常用

typeHandlers 类型处理器
mybatis 通过typeHandlers完成jdbc类型和java类型的转换
通常情况下,mybatis提供的类型处理器满足日常需要,不需要进行自定义

mappers mapper配置
一次加载一个,通过resource方法,单个映射文件加载
还可以通过mapper接口来加载

遵循的规范,需要将mapper接口类名和mapper.xml映射文件保持一致,且在一个目录

还可以进行批量加载,指定mapper接口的包名,mybatis自动扫描包下面的接口进行加载
推荐使用

批量加载,也需要mapper.xml与.java在同一个目录下面

输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型,hashmap、pojo包装类型
传递pojo的包装对象
需求:完成用户信息的综合查询,需要传入查询条件(可能包括用户信息,或者其他信息,商品信息,订单信息)
针对上面需求,建议使用自定义包装类型的pojo
定义包装类型pojo
在包装类型中,定义pojo包装进去。

package cn.mmz.mybatis.pojo;

/**
 * @Classname UserQueryVo
 * @Description TODO
 * @Date 2020/1/4 10:49
 * @Created by mmz
 */
public class UserQueryVo {
    //包装所需要的查询条件

    //用户查询条件
    private UserCustom userCustom;

    public UserCustom getUserCustom() {
        return userCustom;
    }

    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }
    //订单、商品条件
    
}

mapper.java

public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

mapper.xml

    <select id="findUserList" parameterType="UserQueryVo" resultType="UserCustom">
        select * from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
    </select>

测试代码

@Test
    public void findUserList() throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("张三丰");
        UserQueryVo userQueryVo = new UserQueryVo();
        userQueryVo.setUserCustom(userCustom);`在这里插入代码片`
        List<UserCustom> userCustoms =  userMapper.findUserList(userQueryVo);
        System.out.println(userCustoms);
    }

输出映射
resultType 与resultMap

如果我们把查询的字段select中,如果没写sex,最后查询出来映射的东西是映射不到UserQueryVo对象的

如果使用resultType进行输出的映射,只有查询出来的列名与pojo中的属性名一致,才可以映射成功,如果查询出来的列名与pojo中的属性全部不一致,没有生成创建pojo对象
只要有一个一致,就会创建pojo对象

需求:用户信息的综合查询总数,通过查询总数和上边用户综合查询列表才可以实现我们的分页。

    <select id="findUserCount" parameterType="UserQueryVo" resultType="int">
        select count(*)  from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
    </select>
 @Test
    public void findUserCount() throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("张三丰");
        UserQueryVo userQueryVo = new UserQueryVo();
        userQueryVo.setUserCustom(userCustom);
        int count = userMapper.findUserCount(userQueryVo);
        System.out.println(count);
    }

只有查询出来的结果集只有一行只有一列,可以使用简单类型进行结果的映射

不管是输出pojo单个对象还是一个列表(list包括pojo)
在mapper.xml指定的类型中是一样,不一样的是指定方法的返回值
输出单个对象,就是单个对象类型
如果是一个列表,就是list<pojo>

生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne还是selectList

resultMap
mybatis中使用resultMap完成高级输出结果映射

如果查询出来的列名与pojo属性名不一致,通过定义一个resultMap对列名和pojo属性之间做一个映射

需求是:将下边的Sql 使用UserCustom完成映射

  <select id="findUserByIdResultMap" parameterType="int" resultMap="">
        select * from user where id  =#{id}
    </select>

定义resultMap ,使用resultMap

<resultMap id="" type=""></resultMap>

type是最终映射成为的java对象的类型 User ,可以使用别名
id 对resultMap唯一标识

属性中:id标识查询结果集中唯一标识 column查询出来的列名 与property pojo中的属性名,也就是type指定的pojo中的类型名

        <id column="id_" property="id"></id>

result是对普通列的映射

    <resultMap id="userResultMap" type="User">
        <id column="id_" property="id"></id>
        <result column="username_" property="username"></result>
    </resultMap>

resultMap就是resultMap的id,上面提及到的唯一标识符

如果在其他的mapper中,前面加namespace

测试

    @Test
    public void findUserByIdResultMap() throws Exception {
        //创建Usermapper对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserByIdResultMap(1);
        System.out.println(user);
    }

总结
使用resultMap进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名做一个映射关系

动态sql

什么是动态sql,mybatis的核心就是对sql语句进行灵活的操作,通过表达式进行判断,对sql进行灵活的拼接、组装,也就是动态生成sql

需求:用户信息综合查询列表和 总数两个statement使用动态sql

select * from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'

查询的时候,如果第一个条件与第二条件都为空。那么就相当于查询全部了。
对查询条件进行判断,如果输入的参数不为空,那么再进行查询条件的拼接

进行判断

        <if test="userCustom.sex!=null and username.sex != ''">
          user.sex = #{userCustom.sex}
        </if>
<if test="userCustom != null ">
            <if test="userCustom.sex!=null and username.sex != ''">
                user.sex = #{userCustom.sex}
            </if>
            <if test="userCustom.username!=null and username.username != ''">
                user.username like '%${userCustom.username}%'
            </if>
        </if>

因为是两个查询,首先判断这个大的查询条件,如果为空,那么就查询全部,如果不为空,在一个一个进行判断,那么问题来了,如何加上这个and

用到了where标签,可以自动的去掉条件中第一个and

测试代码

@Test
    public void findUserList() throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);
        UserCustom userCustom = new UserCustom();
        //由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
//        userCustom.setSex("1");
        userCustom.setUsername("张三丰");
        UserQueryVo userQueryVo = new UserQueryVo();
        userQueryVo.setUserCustom(userCustom);
        List<UserCustom> userCustoms =  userMapper.findUserList(userQueryVo);
        System.out.println(userCustoms);
    }

sql片段
将上面的代码段抽取出来,组成一个sql片段
其他的statement中就可以引用这个片段了

定义一个sql片段
基于单表来定义sql片段,可重用性高

在sql片段不要包括where

定义sql 片段

<sql id="query_user_where">
            <if test="userCustom != null">
                <if test="userCustom.sex != null and userCustom.sex != ''">
                    and user.sex = #{userCustom.sex}
                </if>
                <if test="userCustom.username != null and userCustom.username != ''">
                    and user.username like '%${userCustom.username}%'
                </if>
            </if>
    </sql>

sql片段使用

 <where>
            <include refid="query_user_where"></include>
        </where>

用include标签,refid里面填上面定义好的sql的id

for each
向sql传递数组或者list,mybatis使用foreach解析

需求:在用户查询列表和查询总数的statement中增加多个id输入查询
在这里插入图片描述
先实验第一种

在输入参数类型,添加list<integer>
ids传入多个id

修改mapper.xml,在原来的mapper.xml文件中进行修改

                <if test="ids != null">
                    <foreach collection="" item="" open=""></foreach>
                </if>

collection指定输入对象的集合属性,也就是我们在Vo定义的ids
item 每次遍历的对象名 id
open 开始遍历时拼接的串 and (
close 是结束遍历拼接的串 )
separator 遍历的两个中间拼接的串 or
中间写上内容

 <if test="ids != null">
                    <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                      id =#{id}
                    </foreach>
                </if>

测试代码

@Test
    public void findUserList() throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);
        UserCustom userCustom = new UserCustom();
        //由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
//        userCustom.setSex("1");
        userCustom.setUsername("小明");
        List<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(10);
        ids.add(16);
        UserQueryVo userQueryVo = new UserQueryVo();
        userQueryVo.setIds(ids);
        userQueryVo.setUserCustom(userCustom);
        List<UserCustom> userCustoms =  userMapper.findUserList(userQueryVo);
        System.out.println(userCustoms);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值