mybatis的动态sql与核心映射

一:mybatis中如何使用动态sql:
MyBatis的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。有些时候,SQL语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息。使用Oracle的序列、mySQL的函数生成Id。这时我们可以使用动态SQL。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

MyBatis中用于实现动态SQL的元素主要有:
1、if和where
if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。
where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理。如果所有的条件都不满足那么MyBatis就会查出所有的记录;如果输出后是and这个单词开头的,MyBatis会把第一个单词and忽略,当然如果是or开头的,MyBatis也会把它忽略。此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。

2、choose(when,otherwise)
choose元素的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的。
3、trim

trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能
4、set
set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在set标签包含的语句前输出一个set。如果包含的语句是以逗号结束的话将会把该逗号忽略。如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段,而不用每次更新全部字段。

5、foreach
foreach的主要用在构建in条件中,它可以在SQL语句中迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束。
collection属性用于指定传入参数的类型。该属性是必须指定的,在不同情况下,该属性的值是不一样的,主要有一下3种情况:
如果传入的是单参数且参数类型是一个List类型的时候,collection属性值为list。
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array。
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map。实际上在传入参数的时候,MyBatis也是把它封装成一个Map的,List实例将会以“list”作为键,而数组实例将会以“array”作为键。这个时候collection属性值就是传入的List或array对象在封装自身的map里面中的对应key。

具体使用
1.通过resource加载单个的映射文件UserMapper.xml

通过mapper接口加载单个mapper,要遵循一定的规范:
(1)前提是使用mapper代理开发(已经有4个规范)
(2)需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在同一目录下
在这里插入图片描述

通过批量加载mapper(推荐使用):实现条件是
要满足mapper接口加载映射文件和使用mapper代理开发同时满足
在这里插入图片描述

mybatis的核心输入映射和输出映射开始:
输入映射:
通过parameterType指定输入参数类型,类型可以是简单类型、hashmap、pojo的包装类型

输出映射
1,resultType
使用resultType进行输出映射时,只有查询输出结果列名和pojo中的属性名一致才可以,映射成功
如果查询出来的列名和pojo中的属性名没有一个一致的,就不会创建pojo对象
如果查询出来的列名和pojo中的属性名有一个一致,就会创建pojo对象
输出pojo对象和pojo列表
不管是输出的pojo单个对象还是一个列表(list中包含pojo),在mapper.xml中resultType指定的类型是一样的
在mapper.java指定的方法返回值类型不一样:
(1)输出单个pojo对象,方法返回值是个单个对象类型
(2)输出pojo对象list,方法返回值就是list对象类型
在动态代理对象中,是根据mapper方法的返回值类型来确定是调用selectOne(返回单个对象)还是selectList(返回集合对象)
2,resultMap
使用resultMap进行映射时,查询结果列名和pojo的属性名不一致时,resultMap会对列名和pojo属性名进行映射,保证其成功映射

1—创建 User 类
package com.offcn.entity;
import java.util.Date;
import java.util.List;
public class User {

private List<Address> addressList;
public Role getRole() {
    return role;
}

private Role role;

public List<Address> getAddressList() {
    return addressList;
}

public void setAddressList(List<Address> addressList) {
    this.addressList = addressList;
}}

2.第二部—定义接口UserMapper
package com.offcn.dao;

import com.offcn.entity.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface UserMapper {
List selectByName(User user);

/*     使用注解方式注入参数*/
/*List<User> selectByName(@Param("userName")
                                String userName, @Param("userRole") Integer userRole);*/

/*------*/
List<User> selectByMap(Map<String,String> map);


/*-------*/
List<User> selectByRole(User u);

/*-------*/
List<User> selectAddressByUserName(String userName);
/*---增加一个用户--*/
int addUser(User user);

/*---修改一个用户*/
int updateUser(User user);

/*-----查询userRole的2或3的所有用户,传一个数组参数*/

List<User> selectArrayUser(Integer[] userRole);

List<User> selectArrayUser(List<Integer> userRole);

}

3.第三步
映射文件UserMapper.xml配置 :

<mapper namespace="com.offcn.dao.UserMapper">
<!--这个id的名字必须与你的dao层方法名一样-->
<!--prefix加前缀,prefixOverrides去除第一个and关键词,suffix加后缀,suffixOverrides去除最后一个符号或关键字-->
<select id="selectByName"  resultType="User">
    select u.*,r.roleName from smbms_user u,smbms_role r
    <trim prefix="where" prefixOverrides="and" suffix="and u.userRole=r.id">
     <if test="userRole!=null">
         and userRole=#{userRole}
     </if>
    <if test="userName!=null and userName!=''">
       and userName  like concat ('%',#{userName},'%')
    </if>
    </trim>

</select>

<insert id="addUser" parameterType="User" >

    insert into smbms_user(userName,userPassword,UserCode,gender,birthday)
    values (#{userName},#{userPassword},#{userCode},#{gender},#{birthday})


  /*插入*/
</insert>
<!--prefix 加上前缀 -->
<update id="updateUser" parameterType="User">
    update smbms_user

    <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
        <if test="userCode !=null">userCode=#{userCode},</if>
        <if test="userName !=null">userName=#{userName},</if>
        <if test="userPassword  !=null">userPassword=#{userPassword},</if>
        <if test="gender !=null">gender=#{gender},</if>
        <if test="birthday !=null">birthday=#{birthday},</if>

    </trim>

</update>

<!--<select id="selectByMap" parameterType="Map" resultType="User">
     select u.*,r.roleName from smbms_user u,smbms_role r
    where userName like concat ('%',#{uName},'%') and
    userRole =#{uRole} and u.userRole=r.id
</select>-->

<!--resultMap的id与你select的resultMap的值对应-->
<!--type是代表你的返回值类型(可以给别名)-->
<resultMap id="selectByMapResult" type="User">
    <!--property的id代表 标签实体类的属性名,column代表是你的数据库列名-->
    <!--两种id必须相匹配,不匹配的时候两种情况-->
    <!--两种情况:-->
    <!--第一种:是你的标签实体类的属性名与你的数据库列名相对应-->
    <!--第二种:复杂查询的时候(一对一,一对多)-->
    <id property="id" column="id"></id>
    <result property="userName" column="userName"></result>
    <result property="userRole" column="userRole"></result>
    <result property="userPassword" column="userPassword"></result>


</resultMap>

<select id="selectByMap" parameterType="Map" resultMap="selectByMapResult">
     select u.*,r.id from smbms_user u,smbms_role r
    where userName like concat ('%',#{uName},'%') and
    userRole =#{uRole} and u.userRole=r.id
</select>

 <!--resultMap的id与下面的<select>标签的resultMap的值一样-->
<resultMap id="selectRoleMap" type="User">
    <id property="id" column="id"></id>
    <result property="userName" column="userName"></result>
    <result property="userRole" column="userRole"></result>
    <!--配置一对一的关系,association拿到的是你的属性名-->
    <!--javaType代表你的返回类型-->
    <association property="role" javaType="Role">
        <id property="id" column="r_id"></id>
        <result property="roleName" column="roleName"></result>
        <result property="roleCode" column="roleCode"></result>
         <!--如果下面select标签里的查询语句u的id与r的id字段名一致时,需要给r的id取一个别名r_id-->
    </association>
</resultMap>

<!--resultMap的值自己定义-->
<select id="selectByRole" parameterType="User" resultMap="selectRoleMap">

     select u.*,r.id as r_id,r.roleName,r.roleCode  from smbms_user u,smbms_role r
    where userName like concat ('%',#{userName},'%') and
    userRole =#{userRole} and u.userRole=r.id

</select>


<!--根据名字查询地址一对多的关系-->
<resultMap id="selectAddressMap" type="User">
    <id property="id" column="id"></id>
    <result property="userName" column="userName"></result>
    <!--开始配置一对多的关系-->
    <collection property="addressList" ofType="Address">
        <!--<id property="id" column="id"></id>-->
        <result property="addressDesc" column="addressDesc"></result>
        <result property="contact" column="contact"></result>
    </collection>

</resultMap>

<select id="selectAddressByUserName" parameterType="String" resultMap="selectAddressMap">
      select u.*,a.addressDesc,a.contact from smbms_address a,smbms_user u
       where a.userId=u.id and u.userName=#{userName}
</select>

<!--collection你要遍历的类型  list是指List集合 array是指数组 item你要自定义的条目名-->
<!--open以什么开始    separator以什么分割 close以什么结束 -->
<!--#{uRole}的值与item的名字要一样-->
<select id="selectArrayUser"  resultType="User">
    select * from smbms_user where userRole in
    <foreach collection="list" item="uRole" open="(" separator="," close=")">
      #{uRole}
    </foreach>
</select>

第四部:
测试类:

/----动态sql–/

        /*-查询全部-*/

        /*SqlSession sqlSession= SqlSessionUtils.getSqlSessionUtils().sqlSession;
        AddressMapper mapper = sqlSession.getMapper(AddressMapper.class);
        List<Address> addresses = mapper.selectAllAddress();
        for (Address a :addresses
                ) {
            System.out.println(a.getAddressDesc()+"--"+a.getContact());
        }*/

        /*----模糊c查询----*/
        /*SqlSession sqlSession= SqlSessionUtils.getSqlSessionUtils().sqlSession;
        AddressMapper mapper = sqlSession.getMapper(AddressMapper.class);
        Address address = mapper.selectOneAddress("李");
        System.out.println(address.getContact()+"---");*/

        /*--查询一条--*/
       /* SqlSession sqlSession= SqlSessionUtils.getSqlSessionUtils().sqlSession;
        AddressMapper mapper = sqlSession.getMapper(AddressMapper.class);
        Address address = mapper.checkAddress(3);
        System.out.println(address);*/

        /*-----注解配置的映射------*/
        /*查询mysql表中所有Address的方法*/
        /*SqlSession sqlSession= SqlSessionUtils.getSqlSessionUtils().sqlSession;
        AddressMapper mapper = sqlSession.getMapper(AddressMapper.class);
        List<Address> list = mapper.selectAllAddress();
        for (Address aa:list) {
            System.out.println(aa.getContact()+"###");
        }*/

        /*----------通过管理员名字模糊查询所有用户---------*/
       /* SqlSession sqlSession= SqlSessionUtils.getSqlSessionUtils().sqlSession;
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user=new User();
        user.setUserRole(3);
        user.setUserName("孙");
        List<User> list=mapper.selectByName(user);
        for (User u:list
             ) {
            System.out.println(u.getUserName()+"000");
        }*/

        SqlSession sqlSession= SqlSessionUtils.getSqlSessionUtils().sqlSession;
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        /*User user=new User();
        user.setUserRole(3);
        user.setUserName("孙");*/
       /* Map<String,String> map=new HashMap<String,String>();
        map.put("uName","孙");
        map.put("uRole","3");*/
        /*--如果你使用Map集合来进行传参,键名必须与你UserMapper.xml文件里面的占位符#{}的值必须一致--*/
       /* List<User> list=mapper.selectByRole(user);
        for (User u:list) {

            System.out.println(u.getUserName()+"---"+u.getUserRole());
            Role role = u.getRole();
            System.out.println(role.getRoleName()+"--"+role.getRoleCode());



        }*/

       /*---一对多:查询某一个人的所有地址---*/
       /* List<User> list = mapper.selectAddressByUserName("张华");
        for (User u:list
             ) {

            System.out.println(u.getUserName()+"\t");
            List<Address> addressList=u.getAddressList();
            for (Address a:addressList
                 ) {
                System.out.println(a.getContact()+"--"+a.getAddressDesc());
            }

        }*/

       /* List<User> list = mapper.selectByName("张", null);
        for (User u:list
             ) {
            System.out.println(u.getUserName()+"--"+u.getUserRole());
        }*/

       /*--增加一个--*/
        /*User user=new User();
        user.setUserName("vvv");
        user.setBirthday(new Date());
        user.setUserCode("asd");
        user.setUserPassword("2222");
        user.setGender(2);
        int i = mapper.addUser(user);
        System.out.println(i);*/

        /*---修改一个---*/
       /* User user=new User();
        user.setUserName("尼玛");
        user.setGender(2);
        user.setId(2);
        int i = mapper.updateUser(user);
        System.out.println(i);*/

        /*User user=new User();
        user.setUserName("尼玛");

        List<User> list = mapper.selectByName(user);
        for (User u:list
             ) {
            System.out.println(u.getUserName());
        }*/
        List<Integer> list1=new ArrayList<Integer>();
        list1.add(2);
        list1.add(3);
        List<User> list = mapper.selectArrayUser(list1);
        for (User u:list
             ) {
            System.out.println(u.getUserName());
        }

猜你喜欢

转载自blog.csdn.net/weixin_42772943/article/details/83032168
今日推荐