java回顾:MyBatis参数、sql片段、动态sql、高级查询

目录

一、MyBatis参数

 SqlSessiong工具类

1、映射文件配置-入参

1.1 parameterType入参

1.2 单个入参,变量名任意定义:

1.3 多个入参,解决方案:

1.4 pojo类入参:

1.5 Map入参:

1.6 自增主键回填

2、参数值的获取

2.1 获取参数的方式

2.2 ${}取值的应用场景

3、结果集映射

3.1  简单结果映射resultType

3.2 resultType测例

3.3 结果映射resultMap

3.3 resultMap测例

3.4 resultMap标签映射流程 

4、SQL片段

4.1 引用当前文件中的SQL片段

二、动态sql(根据不同条件拼接SQL语句)

 1、OGNL表达式介绍

1.1 动态SQL中使用到的运算符: ognl表达式

2、动态SQL标签if、choose、where、set、foreach

2.1 if标签

2.2 if测例

2.3 choose标签:分支选择(多选一,遇到成立的条件即停止)

2.4 choose测例

2.5 where标签:拼接条件查询,去除多余and、or

2.6 where测例

2.7 set标签:update语句中,添加set关键字,会将动态sql最后多余的逗号去除

2.8 set测例

2.9 foreach标签:遍历集合或者数组,拼接成字符串用于sql中in关键字

2.10 foreach测例

2.11 特殊字符处理

三、高级查询

 1、一对一查询

1.1 一对一映射语法格式

1.2 一对一测例:

1.3 一对一查询映射规律

 2、一对多查询

1.1  一对多映射语法:

1.2 一对多测例 

1.3 一对多映射流程

1.4 一对多映小结

3、多对多查询

1.1 多对多映射

1.2 多对多测例

4、多对多查询扩展

5、ResultMap继承extend


一、MyBatis参数

 SqlSessiong工具类

public class SessionFactoryUtils {
    //声明一个工厂对象
    private static SqlSessionFactory factory;
    //在静态代码块中创建会话工厂
    static {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //得到输入流
        try(InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) {
            factory = builder.build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     静态方法得到会话工厂
     */
    public static SqlSessionFactory getSessionFactory() {
        return factory;
    }
    /**
     得到会话对象
     */
    public static SqlSession getSession() {
        return factory.openSession();//使用的是默认事务:手动提交
    }
}

1、映射文件配置-入参

1.1 parameterType入参

CRUD标签都有属性parameterType,底层的statement通过它指定接收的参数类型。入参数据有以下几种类型:HashMap,基本数据类型(包装类),实体类

在mybatis中入参的数据类型分为2大类:

  1. 基本数据类型:int,string,long,Date等;

  2. 复杂数据类型:类(pojo)和Map;

说明:如果传递参数是数组或者集合,底层都会封装到Map集合中。  

1.2 单个入参,变量名任意定义:

mapper.java
根据id查询用户信息,入参是单个参数:用户id
User queryById(Integer id); //接口方法传入一个参数
mapper.xml配置:
<!--根据id查询用户信息-->
    <!--返回值类型User,入参类型int,单个入参#{变量随便写}-->
    <select id="queryById" resultType="User" parameterType="int">
        select *  from user where id = #{ii}
    </select>

在xml中通过#{ 任意变量名}可接收到参数,若接口传入单个参数,可在xml中使用任意变量名接收

1.3 多个入参,解决方案:

mapper.java
多个入参,根据用户名和性别查询用户信息
User queryByNameAndSex(String name ,String sex);

错误演示:

    <!--返回值类型User,未定义入参类型-->
    <select id="queryByNameAndSex" resultType="User">
        select *  from user where name = #{name} and sex = #{sex}
    </select>

报参数绑定异常!

需使用参数索引(arg0,arg1)、参数位置(param1,param2)、或在接口处明确指定传入参数名

方式1:使用参数索引获取:arg0,arg1 (了解即可) 
<select id="queryByNameAndSex" resultType="user">
    select * from user where user_name=#{arg0} and sex=#{arg1}
</select>

方式2:使用参数位置获取:param1,param2 (了解即可) 
<select id="queryByNameAndSex" resultType="user">
    select * from user where user_name=#{param1} and sex=#{param2}
</select>

掌握:命名参数获取,在接口处明确指定传入参数名称。

mapper.java接口

List<User> queryByNameAndSex(@Param("name") String name,@Param("sex") String sex);

mapper.xml,变量名与接口中明确的@Param("name")参数名相同,接收参数时通过指定的名称获取参数值。

    <!--根据用户名和性别查询用户信息-->
    <select id="queryByNameAndSex" resultType="User">
        select *  from user where user_name = #{name} and sex = #{sex}
    </select>

1.4 pojo类入参:

mapper.java接口

保存用户,pojo对象作为入参
int saveUser (User user);

mapper.xml,#{变量},变量名与User类中属性名对应

<!--#{变量},变量名为User类中属性名,要一一对应-->
    <insert id="saveUser">
        insert into user values (null ,#{username},#{birthday},#{sex},#{address})
    </insert>

1.5 Map入参:

mapper.java接口

以map为参数插入用户信息
int saveUser2 (Map map);

        SqlSession sqlSession = SessionFactoryUtils.getSession();
        //获取接口代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<>();
        map.put("username","鞋垫老板");
        map.put("sex","男");
        map.put("address","鞋店");
        mapper.saveUser2(map);
        sqlSession.commit();
        sqlSession.close();

 mapper.xml

<!--#{变量},变量名与Map中key一一对应-->
    <insert id="saveUser2" parameterType="map">
        insert into user values (null ,#{username},null,#{sex},#{address})
    </insert>

1.6 自增主键回填

 1)使用insert标签的子标签selectKey+last_insert_id()函数实现实现

   <!-- selectKey:表示查询主键字段的标签
        keyColumn:表示表中字段名称,一般指主键名称
        keyProperty="id":表示pojo类中对应主键的属性名称
        order="AFTER":表示在操作之前或者之后获取主键值-->
<insert id="addUserAndGetFkId">
    insert into user values(null,#{username},#{birthday},#{sex},#{address})                                
        <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">                
            select last_insert_id()
        </selectKey>
</insert>

 2)使用insert标签的属性useGeneratedKeys,keyProperty,keyColumn实现

说明:直接在insert标签中增加属性的方式,只适合于支持自动增长主键类型的数据库

<!--useGeneratedKeys="true"表示开启获取主键id的功能
    keyColumn="id":表示指定表中主键字段名称
    keyProperty="id":表示指定pojo类中主键对应的属性名称-->
<insert id="addUserAndGetFkId2" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
    insert into user values(null,#{username},#{birthday},#{sex},#{address})
</insert>

2、参数值的获取

2.1 获取参数的方式

在mybatis中获取传入参数值的方式有两种:#{} 和 ${}

#{}: 使用#{}的sql是进行预编译的,防止sql注入。

${}:参数与sql直接拼接有sql注入的风险。${id} 获取id值时,接口必须使用命名参数取值@param,若取单个值,也可使用${value}获取。

mapper.java接口
User findById2(@Param("id") Integer id);

mapper.xml
<select id="findById2" resultType="user" parameterType="int">
    select * from user where id=${id}
</select>

2.2 ${}取值的应用场景

如果需要设置到SQL中的不是查询的条件,只能使用${}拼接;

SELECT COUNT(*) FROM  ${tableName}

例:传入参数:没有指定参数名称

User selectUserById(Integer id);

获取参数通过${value}获取
<select id="selectUserById" resultType="user">
    select * from user where id = ${value}
</select>

3、结果集映射

        mybatis框架提供了resultType和resultMap来对结果集进行封装; 只要一个方法有返回值需要处理,那么 resultType和resultMap必须有一个;

3.1  简单结果映射resultType

        从sql语句中返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。 可以使用 resultType 或 resultMap,但不能同时使用。

① 返回值是基本类型

        1)基本类型 int short double ...    别名: _基本类型名称

        2)包装类 类 String ArrayList ....   别名: 类名首字母小写

        3)自定义类 扫包取别名 类首字母小写(大写也可以)

② 返回值为一个pojo(User)对象时

        1)表中列明要与pojo中属性名称一致

        2)若表中列名与pojo中属性名称不一致,可使用as取别名使其一致即可

        3)如果满足驼峰映射,也可以开启驼峰映射设置

③返回值为一个List<User>时

        当返回值为List集合时,resultType需要设置成集合中存储的具体的pojo数据类型

 3.2 resultType测例

1)返回一条数据,封装到map中
接口:
Map<String,Object> findMapById(@Param("id") Integer id);
xml:
<select id="findMapById" resultType="map">
    select id,user_name as userName,address from user where id=#{id}
</select>

2)返回多条数据,封装到map中

获取所有用户,value为user对象:@MapKey("id"),指定key为id值

接口:
@MapKey("id")
Map<Integer,User> findAllToMap();
xml:
<select id="findAllToMap" resultType="map">
    select id,user_name as name,birthday,sex,address from user
</select>

3.3 结果映射resultMap

        正常开发中,数据库字段名称与Pojo类属性名称不一致时,一般通过驼峰映射或者AS关键字取别名可以搞定,但是对于复杂的orm映射,上述的2种方式就不能适用了。

        resultMap是mybatis中最重要最强大的元素,使用ResultMap可以解决ORM复杂映射问题:           1. POJO属性名和表结构字段名不一致的问题(字段名:user_name,属性名:name)             2. 完成高级查询,比如说,一对一、一对多、多对多

3.3 resultMap测例

        之前使用驼峰匹配,方便封装用户。现取消驼峰映射,使用ResultMap。

    <settings>
        <!--作用:表:user_name 类:userName/username 自动映射-->
        <!--关闭驼峰映射,测试resultMap-->
        <setting name="mapUnderscoreToCamelCase" value="false"/>
    </settings>

resultMap标签自定义结果集,自行设置结果集的封装方式。

id属性:resultMap标签的唯一标识,不能重复,一般是用来被引用的
type属性:结果集的封装类型
autoMapping属性:操作单表时,不配置默认为true,如果pojo对象中的属性名称和表中字段名称相同,则自动映射。
<!--type="user" 表示结果集的封装类型是user-->
    <resultMap id="userMap" type="User" autoMapping="true">
        <!--配置主键映射关系-->
        <id column="id" property="id"></id>
        <!--配置用户名的映射关系  column 表示数据表列  property表示pojo的属性-->
        <result column="user_name" property="username"></result>
    </resultMap>
    <select id="findUserById" resultMap="userMap">
        select id,user_name from user where id = #{id}
    </select>
        SqlSession sqlSession = SessionFactoryUtils.getSession();
        //获取接口代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //调用方法根据id查询单个数据
        User user = mapper.findUserById(2);
        System.out.println("user = " + user);
        sqlSession.close();

注意:若xml中sql只查询数据库部分字段,需在pojo

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值