• mybatis学习二


    本篇内容,紧接上一篇内容 Mybatis学习笔记一

    输入映射和输出映射

    传递简单类型和pojo类型上篇已介绍过,下面介绍一下包装类型。

    传递pojo包装对象

    开发中通过可以使用pojo传递查询条件。查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。包装对象即Pojo类中的一个属性是另外一个pojo。

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

    上一篇的SqlMapConfig.xml:(就是mybatis配置xml):

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    
         <typeAliases>  
            <typeAlias type="cn.itcast.mybatis.po.User" alias="User" />
             <typeAlias type="com.yyb.pojo.QueryVo" alias="QueryVo" />
             <typeAlias type="com.yyb.pojo.Orders" alias="Orders" />
        </typeAliases>
    
        <!-- 和spring整合后 environments配置将废除 -->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc事务管理 -->
                <transactionManager type="JDBC" />
                <!-- 数据库连接池 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url"
                        value="jdbc:mysql://192.168.1.20:3306/test?" />
                    <property name="username" value="root" />
                    <property name="password" value="root123" />
                </dataSource>
            </environment>
        </environments>
        
        <!--mapper文件夹下面的  -->
         <mappers>
            <mapper resource="mapper/UserMapper.xml"/>
            <mapper resource="mapper/orderMapper.xml"/>
        </mappers>
           
    </configuration>

     

    1、编写QueryVo

    复制代码
    package com.yyb.pojo;
    
    import java.io.Serializable;
    
    /**
     * Created by Administrator on 2017/8/16.
     */
    public class QueryVo implements Serializable{
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        private User user;
    
    }
    复制代码

    2、userMapper配置

        <select id="findByQueryVo"  parameterType="QueryVo" resultType="User">
            SELECT * FROM user WHERE username  like "%"#{user.username}"%"
        </select>

    3.、userMapper接口中添加

     List<User> findByQueryVo(QueryVo vo);

    4、测试类

    复制代码
        @org.junit.Test
        public void func2() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    
            QueryVo vo=new QueryVo();
            User u=new User();
            u.setUsername("五");
            vo.setUser(u);
            List<User> us = userMapper.findByQueryVo(vo);
            for (User use:us) {
                System.out.println(use);
            }
        }
    复制代码

    resultType(输出类型)

    1、输出简单类型。示例:查询用户表数据条数

    在userMapper.xml中添加如下代码:

       <select id="findUserCount"  resultType="Integer">
            SELECT COUNT(*) FROM user
        </select>

    在userMapper接口中添加以下代码:

     int findUserCount();

    测试方法

    复制代码
        @org.junit.Test
        public void func3() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            int count = userMapper.findUserCount();
            System.out.println(count);
        }
    复制代码

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

    2、输出pojo对象,参考上篇

    3、输出pojo列表,参考上篇

    4、resultMap

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

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

    resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

    示例:查询订单表order的所有数据

    添加Order实体

    package com.yyb.pojo;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class Orders  implements Serializable{
        private static final long serialVersionUID = 1L;
    
        private Integer id;
    
        private Integer userId;
    
        private String number;
    
        private Date createtime;
    
        private String note;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getUserId() {
            return userId;
        }
    
        public void setUserId(Integer userId) {
            this.userId = userId;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number == null ? null : number.trim();
        }
    
        public Date getCreatetime() {
            return createtime;
        }
    
        public void setCreatetime(Date createtime) {
            this.createtime = createtime;
        }
    
        public String getNote() {
            return note;
        }
    
        public void setNote(String note) {
            this.note = note == null ? null : note.trim();
        }
    
        
        
    }
    View Code

    添加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.yyb.mapper.OrderMapper" >

    <!--orders相当于id, Orders是别名,实际是映射的pojo类 ,user_id是数据库字段,userId是传入的参数--> <resultMap id="orders" type="Orders" > <!--<id column="id" property="id"></id>--> <result column="user_id" property="userId" ></result> </resultMap> <select id="queryOrderList" resultMap="orders"> SELECT id,user_id,number,createtime, note FROM orders </select> </mapper>
    复制代码

    添加orderMapper接口,在其中添加以下代码:

    复制代码
    package com.yyb.mapper;
    
    import com.yyb.pojo.Orders;
    
    import java.util.List;
    
    public interface OrderMapper {
        List<Orders> queryOrderList();
    }
    复制代码

    测试类

    复制代码
    package com.yyb.test;
    
    import com.yyb.mapper.OrderMapper;
    import com.yyb.pojo.Orders;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.InputStream;
    import java.util.List;
    
    /**
     * Created by Administrator on 2017/8/16.
     */
    public class TestOrder {
        @org.junit.Test
        public void func1() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            OrderMapper userMapper = sqlSession.getMapper(OrderMapper.class);
            List<Orders> orders = userMapper.queryOrderList();
            for (Orders o:orders) {
                System.out.println(o);
            }
        }
    }
    复制代码

    由于sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到pojo中。需要定义resultMap,把orderResultMap将sql查询列(user_id)和Order类属性(userId)对应起来。

    动态sql

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

    示例:根据性别和名字查询用户

    在userMapper接口中添加如下代码:

     List<User> findUserByWhere(User user);

    在userMapper.xml中添加如下代码:

    复制代码
     <select id="findUserByWhere" 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>
    复制代码

    测试方法如下:

    复制代码
    @org.junit.Test
        public void func4() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User u=new User();
            u.setUsername("张");
            //u.setSex("1");
            List<User> us = userMapper.findUserByWhere(u);
            for (User use:us) {
                System.out.println(use);
            }
        }
    复制代码

    If标签

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

    复制代码
            WHERE 1=1
            <if test="sex != null and sex != ''">
                AND sex = #{sex}
            </if>
            <if test="username != null and username != ''">
                AND username LIKE "%"#{username}"%"
            </if>
    复制代码

    Where标签

    上面的sql还有where 1=1 这样的语句,很麻烦,可以使用where标签进行改造,where标签可以自动添加where,同时处理sql语句中第一个and关键字。

    改造UserMapper.xml,如下:

    复制代码
     <select id="findUserByWhere" 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>
    复制代码

    Sql片段

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

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

    <!--sql片段-->
    <sql id="selector">
        SELECT id, username, birthday, sex, address FROM user
    </sql>
    复制代码
     <select id="findUserByWhere" parameterType="User" resultType="User">
            <include refid="selector"/>
            <where>
                <if test="sex != null">
                    AND sex = #{sex}
                </if>
                <if test="username != null and username != ''">
                    AND username LIKE '%${username}%'
                </if>
            </where>
        </select>
    复制代码

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

    foreach标签

    向sql传递数组或List,mybatis使用foreach解析。

    示例:根据多个id查询用户信息

    添加接口 findUserByIds

    改造QueryVo

    复制代码
    package com.yyb.pojo;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * Created by Administrator on 2017/8/16.
     */
    public class QueryVo implements Serializable{
        private User user;
    
        List<Integer> idsList;
    
        Integer[] ids;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
        public List<Integer> getIdsList() {
            return idsList;
        }
        public void setIdsList(List<Integer> idsList) {
            this.idsList = idsList;
        }
        public Integer[] getIds() {
            return ids;
        }
        public void setIds(Integer[] ids) {
            this.ids = ids;
        }
    }
    复制代码

    UserMapper.xml文件

    复制代码
     <select id="findUserByIds" parameterType="QueryVo" resultType="User">
            <include refid="selector"/>
            <where>
                <!-- foreach标签,进行遍历 -->
                <!-- collection:遍历的集合,这里是QueryVo的ids属性,当不使用包装类,直接传递数组或者list时,collection="Array" 或者collection="list" -->
                <!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
                <!-- open:在前面添加的sql片段 -->
                <!-- close:在结尾处添加的sql片段 -->
                <!-- separator:指定遍历的元素之间使用的分隔符 -->
                <foreach collection="idsList" item="item" open="id IN (" close=")" separator=",">
                    #{item}
                </foreach>
            </where>
        </select>
    复制代码

    测试方法:

    复制代码
        @org.junit.Test
        public void func5() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
           QueryVo vo=new QueryVo();
           List<Integer>list=new ArrayList<>();
            list.add(16);
            list.add(24);
            list.add(30);
            vo.setIdsList(list);
            List<User> us = userMapper.findUserByIds(vo);
            for (User use:us) {
                System.out.println(use);
            }
        }
    复制代码

    关联查询

    商品订单数据模型

     

    方式一:定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段(继承现有pojo)。此方法较为简单,企业中使用普遍。

    下面介绍方式二,使用resultMap,定义专门的resultMap用于映射一对一查询结果。

    一对一查询

    示例:查询所有订单信息,关联查询下单用户信息。

    注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

    在OrderMapper添加接口   List<Orders> queryOrderUser(); 

    在Order类中添加如下代码:

    复制代码
      //在Order类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。    
    private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; }
    复制代码

    在OrderMapper.xml中添加如下代码:

    复制代码
     <resultMap id="orderuser" type="Orders">
            <id column="id" property="id"></id>
            <result column="user_id" property="userId"></result>
            <result column="number" property="number"></result>
            <result column="createtime" property="createtime"></result>
            <result column="note" property="note"></result>

          <!-- association :配置一对一属性 -->

          <!-- property:order里面的User属性名 -->

          <!-- javaType:属性类型。。运行时候要删除这些注释,否则出错-->

            <association property="user" javaType="User">
                <id column="user_id" property="id"></id>
                <result column="username" property="username"></result>
                <result column="sex" property="sex"></result>
                <result column="birthday" property="birthday"></result>
                <result column="address" property="address"></result>
            </association>
        </resultMap>
        <select id="queryOrderUser" resultMap="orderuser">
           SELECT
                o.id,o.user_id,o.number,o.createtime, o.note ,
                u.username,u.sex,u.birthday,u.address
            FROM orders  o
            LEFT JOIN USER u
            ON o.user_id=u.id
        </select>
    复制代码

    测试代码:

    复制代码
     @org.junit.Test
        public void func2() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            OrderMapper userMapper = sqlSession.getMapper(OrderMapper.class);
            List<Orders> orders = userMapper.queryOrderUser();
            for (Orders o:orders) {//打断点调试查看user对象的值
                System.out.println(o);
            }
        }
    复制代码

     一对多查询

    案例:查询所有用户信息及用户关联的订单信息。

    用户信息和订单信息为一对多关系。

    修改pojo类,在User类中加入List<Order>属性,如下:

    复制代码
        private List<Orders>lsOrders;
    
        public List<Orders> getLsOrders() {
            return lsOrders;
        }
    
        public void setLsOrders(List<Orders> lsOrders) {
            this.lsOrders = lsOrders;
        }
    复制代码

    在userMapper接口中添加如下接口:  List<Orders> queryOrderUser(); 

    在UserMapper.xml添加如下代码:

    复制代码
    <resultMap id="userorder" type="User">
            <id column="user_id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="birthday"></result>
            <result column="address" property="address"></result>
    
            <collection property="lsOrders" ofType="Orders">
                <id column="id" property="id"></id>
                <result column="user_id" property="userId"></result>
                <result column="number" property="number"></result>
                <result column="createtime" property="createtime"></result>
                <result column="note" property="note"></result>
            </collection>
        </resultMap>
        <select id="findUserOrders" resultMap="userorder">
            SELECT
                u.username,u.sex,u.birthday,u.address,
                o.id,o.user_id,o.number,o.createtime, o.note
            FROM USER u
            LEFT JOIN orders  o
            ON o.user_id=u.id
        </select>
    复制代码

    测试代码如下:

    复制代码
    @org.junit.Test
        public void func6() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion帮我生成一个实现类  (给接口)
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<User> us = userMapper.findUserOrders();
            for (User u:us) {
                System.out.println(u);
            }
        }
  • 相关阅读:
    自定义Bootstrap样式弹出框
    自定义Bootstrap样式弹出框
    Java高级
    Java高级
    Java高级
    Java高级
    与jQuery的感情碰撞——由浅入深学jQuery
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/lgg20/p/11236619.html
Copyright © 2020-2023  润新知