mybatis

作者: 小烧饼a | 来源:发表于2020-07-14 23:40 被阅读0次

    第四章 Mybatis输入类型和结果类型

    第1章

    1.1 parameterType****(输入类型)

    1.1.1 传递简单类型

    参考第一天内容。

    使用#{}占位符,或者${}进行Sql拼接。

    1.1.2 传递Pojo对象

    参考第一天的内容。

    {}或者${}括号中的值为Pojo属性名称。

    1.1.3 传递Pojo包装对象

    包装对象:Pojo类中的一个属性是另外一个Pojo。

    为什么使用包装对象?

    在平时的开发中,不一定就是单纯的对一个实体进行增删改查,例如完成用户信息的综合查询,有时需要传入查询条件很复杂,可能包括用户信息、关联表的其它信息等。针对这种需求,在Mybatis中我们可以使用自定义的包装类型的Pojo,在包装类型的Pojo中将复杂的查询条件包装进去。

    功能需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。

    1.1.3.1 编写QueryVo

    |

    public class QueryVo {

    // 包含其他的pojo

    privateUser user;

    public User getUser() {

    return user;

    }

    public voidsetUser(User user) {

    this.user= user;

    }

    }

    |

    1.1.3.2 Sql语句

    SELECT * FROM USER WHERE USERNAME LIKE '%王%'

    1.1.3.3 Mapper.xml文件

    在UserMapper.xml中配置Sql,如下图。

    [图片上传失败...(image-da9f7e-1594741154724)]

    1.1.3.4 Mapper接口

    在UserMapper接口中添加方法,如下图:

    [图片上传失败...(image-1b59f5-1594741154724)]

    1.1.3.5 测试方法

    在UserMapeprTest增加测试方法,如下:

    |

    @Test

    public void testQueryUserByQueryVo() {

    SqlSession sqlSession= this.sqlSessionFactory.openSession();

    UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

    // 使用userMapper执行查询,使用包装对象

    QueryVo queryVo= new QueryVo();

    // 设置user条件

    User user= new User();

    user.setUsername("%王%");

    // 设置到包装对象中

    queryVo.setUser(user);

    // 执行查询

    List<User> list= userMapper.queryUserByQueryVo(queryVo);

    for(User u: list) {

    System.out.println(u);

    }

    sqlSession.close();

    }

    |

    1.1.3.6 效果

    测试结果如下图:

    [图片上传失败...(image-fce264-1594741154724)]

    1.2 resultType(输出结果类型)

    1.2.1 输出简单类型

    功能需求:查询用户表数据条数

    Sql语句:SELECT count(*) FROM user

    1.2.1.1 M****apper.xml文件

    在UserMapper.xml中配置Sql,如下图:

    [图片上传失败...(image-5d5cba-1594741154724)]

    1.2.1.2 M****apper接口

    在UserMapper添加方法,如下图:

    [图片上传失败...(image-e7f492-1594741154723)]

    1.2.1.3 测试方法

    在UserMapeprTest增加测试方法,如下:

    |

    @Test

    public void testQueryUserCount() {

    SqlSession sqlSession= this.sqlSessionFactory.openSession();

    UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

    int count= userMapper.queryUserCount();

    System.out.println(count);

    sqlSession.close();

    }

    |

    1.2.1.4 效果

    测试结果如下图:

    [图片上传失败...(image-8a347b-1594741154723)]

    注意:输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型

    1.2.2 输出Pojo对象

    参考第一天内容

    1.2.3 输出Pojo列表

    参考第一天内容

    1.3 resultMap

    resultType可以指定将查询结果映射为Pojo,但需要Pojo的属性名和Sql查询的列名一致方可映射成功。

    如果Sql查询字段名和Pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到Pojo对象中。

    功能需求:查询订单表orders的所有数据

    Sql语句:SELECT id, user_id, number, createtime, note FROM orders

    1.3.1 创建数据表、初始化测试数据、****声明****P****ojo对象

    创建订单表并查询订单表的全部数据,Sql语句如下:

    |


    -- Table structure for orders


    DROP TABLE IF EXISTS orders;

    CREATE TABLE orders (

    id int(11) NOT NULL AUTO_INCREMENT,

    user_id int(11) NOT NULL COMMENT '下单用户id',

    number varchar(32) NOT NULL COMMENT '订单号',

    createtime datetime NOT NULL COMMENT '创建订单时间',

    note varchar(100) DEFAULT NULL COMMENT '备注',

    PRIMARY KEY (id),

    KEY FK_orders_1 (user_id),

    CONSTRAINT FK_orders_id FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE NO ACTION ON UPDATE NO ACTION

    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;


    -- Records of orders


    INSERT INTO orders VALUES ('3', '3', '1000010', '2015-02-04 13:22:35', null);

    INSERT INTO orders VALUES ('4', '3', '1000011', '2015-02-03 13:22:41', null);

    INSERT INTO orders VALUES ('5', '4', '1000012', '2015-02-12 16:13:23', null);

    |

    Orders对象:

    |

    public class Orders {

    // 订单id

    private int id;

    // 用户id

    privateInteger userId;

    // 订单号

    privateString number;

    // 订单创建时间

    privateDate createtime;

    // 备注

    privateString note;

    get/set…

    }

    |

    1.3.2 M****apper.xml文件

    创建OrdersMapper.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.itheima.mybatis.mapper.OrdersMapper">

    <select id="queryOrdersAll" resultType="orders">

    SELECT id, user_id,

    number,

    createtime, note FROM orders

    </select>

    </mapper>

    |

    1.3.3 Mapper接口

    编写接口如下:

    |

    public interface OrdersMapper {

    /**

    • 查询所有订单

    • @return

    */

    List<Orders> queryOrdersAll();

    }

    |

    1.3.4 测试方法

    编写测试方法OrdersMapperTest如下:

    |

    public class OrdersMapperTest {

    privateSqlSessionFactory sqlSessionFactory;

    @Before

    public voidinit() throws Exception {

    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

    this.sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);

    }

    @Test

    public void testQueryAll() {

    // 获取sqlSession

    SqlSession sqlSession= this.sqlSessionFactory.openSession();

    // 获取OrderMapper

    OrdersMapper orderMapper= sqlSession.getMapper(OrdersMapper.class);

    // 执行查询

    List<Orders> list= orderMapper.queryOrdersAll();

    for(Orders order: list) {

    System.out.println(order);

    }

    sqlSession.close();

    }

    }

    |

    1.3.5 效果

    测试效果如下图:

    [图片上传失败...(image-325f71-1594741154720)]

    发现userId为null

    解决方案:使用resultMap

    1.3.6 使用resultMap

    由于上边的mapper.xml中Sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到Pojo中。

    需要定义resultMap,把orderResultMap将Sql查询列(user_id)和Order类属性(userId)对应起来

    改造OrderMapper.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.itheima.mybatis.mapper.OrdersMapper">

    <resultMap type="orders" id="orderResultMap">

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

    <result property="userId" column="user_id" />

    <result property="number" column="number" />

    <result property="createtime" column="createtime" />

    <result property="note" column="note" />

    </resultMap>

    <select id="queryOrdersAll" resultMap="orderResultMap">

    SELECT id, user_id,

    number,

    createtime, note FROM orders

    </select>

    </mapper>

    |

    1.3.7 效果

    只需要修改Mapper.xml就可以了,再次测试结果如下:

    [图片上传失败...(image-7df7e5-1594741154719)]

    第1章 Mybatis映射文件的SQL深入

    Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了。

    参考的官方文档,描述如下:

    [图片上传失败...(image-c85a0f-1594741219533)]

    通过Mybatis提供的各种标签方法实现动态拼接Sql。

    功能需求:根据性别和名字查询用户

    Sql语句:

    SELECT id, username, birthday, sex, address FROM user WHERE sex = 1 AND username LIKE '%张%'

    1.1 If****标签

    1.1.1 Mapper.xml文件

    UserMapper.xml配置Sql,如下:

    |

    <select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT id, username, birthday, sex, address FROM user

    WHERE sex = #{sex} AND username LIKE #{username}

    </select>

    |

    1.1.2 Mapper接口

    编写Mapper接口,如下图:

    [图片上传失败...(image-c94ff7-1594741219533)]

    1.1.3 测试方法

    在UserMapperTest添加测试方法,如下:

    |

    @Test

    public void testQueryUserByWhere() {

    SqlSession sqlSession= this.sqlSessionFactory.openSession();

    UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

    // 使用userMapper执行根据条件查询用户

    User user= new User();

    user.setSex("1");

    user.setUsername("%王%");

    List<User> list= userMapper.queryUserByWhere(user);

    for(User u: list) {

    System.out.println(u);

    }

    sqlSession.close();

    }

    |

    1.1.4 效果

    测试效果如下图:

    [图片上传失败...(image-99183d-1594741219533)]

    如果注释掉 user.setSex("1"),测试结果如下图:

    [图片上传失败...(image-f6a548-1594741219533)]

    测试结果二很显然不合理。

    按照之前所学的,要解决这个问题,需要编写多个Sql,查询条件越多,需要编写的Sql就更多了,显然这样是不靠谱的。

    解决方案,使用动态Sql的if标签

    1.1.5 使用if标签

    改造UserMapper.xml,如下:

    |

    <select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT id, username, birthday, sex, address FROM user

    WHERE 1=1

    <if test="sex != null and sex != ''">

    AND sex = #{sex}

    </if>

    <if test="username != null and username != ''">

    AND username LIKE

    {username}

    </if>

    </select>

    |

    注意字符串类型的数据需要做不等于空字符串校验。

    1.1.6 效果

    [图片上传失败...(image-ae7b8a-1594741219533)]

    如上图所示,测试OK

    1.2 W****here标签

    上面的Sql还有where 1=1 这样的语句,很麻烦

    可以使用where标签进行改造

    改造UserMapper.xml,如下

    |

    <select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT id, username, birthday, sex, address FROM user

    <where>

    <if test="sex != null">

    AND sex = #{sex}

    </if>

    <if test="username != null and username != ''">

    AND username LIKE #{username}

    </if>

    </where>

    </select>

    |

    1.2.1 效果

    测试效果如下图:

    [图片上传失败...(image-66c06-1594741219533)]

    1.3 S****ql片段

    Sql中可将重复的Sql提取出来,使用时用include引用即可,最终达到Sql重用的目的。

    把上面例子中的id, username, birthday, sex, address提取出来,作为Sql片段,如下:

    |

    <select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT <include refid="userFields" /> FROM user

    <where>

    <if test="sex != null">

    AND sex = #{sex}

    </if>

    <if test="username != null and username != ''">

    AND username LIKE #{username}

    </if>

    </where>

    </select>

    <sql id="userFields">

    id, username, birthday, sex, address

    </sql>

    |

    如果要使用别的Mapper.xml配置的Sql片段,可以在refid前面加上对应的Mapper.xml的namespace,如下

    |

    SELECT <include refid="com.itheima.mybatis.mapper.OrdersMapper.userFields" /> FROM user

    |

    1.4 foreach标签

    向Sql传递List,Mybatis使用foreach解析。

    功能需求:根据多个id查询用户信息

    查询Sql语句:

    SELECT * FROM user WHERE id IN (1,10,24)

    1.4.1 Mapper.xml文件

    UserMapper.xml添加Sql,如下:

    |

    <select id="queryUserByIds" parameterType="list" resultType="user">

    SELECT * FROM user

    <where>

    <foreach collection="list" item="item" open="id IN (" close=")"

    separator=",">

    {item}

    </foreach>

    </where>

    </select>

    |

    测试方法如下图:

    |

    @Test

    public void testQueryUserByIds() {

    SqlSession sqlSession= this.sqlSessionFactory.openSession();

    UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

    // 使用userMapper执行根据条件查询用户

    List<Integer> ids= new ArrayList<Integer>();

    ids.add(2);

    ids.add(3);

    ids.add(4);

    List<User> list= userMapper.queryUserByIds(ids);

    for(User u: list) {

    System.out.println(u);

    }

    sqlSession.close();

    }

    |

    1.4.2 效果

    测试效果如下图:

    [图片上传失败...(image-a5840a-1594741219532)]

    相关文章

      网友评论

          本文标题:mybatis

          本文链接:https://www.haomeiwen.com/subject/wwzqhktx.html