Mybatis学习系列(二)Mapper映射文件

 Mapper映射文件,作用是用来配置SQL映射语句,根据不同的SQL语句性质,使用不同的标签,mapper文件中常用的标签有<iselect>、<insert>、<update>、<delete>

常见增删改查示例

<!-- namespace:此处使用包名+文件名 的形式 -->
<mapper namespace="com.sl.mapper.ProductMapper">

    <!--select – 映射查询语句
       id:唯一标识 parameterType:参数类型,此处是根据id查询,类型为int resultType:返回值类型, 
        #{id}: 参数 -->
    <select id="selectProduct" parameterType="int" resultType="com.sl.po.Product">
        select * from products where id = #{id}
    </select>
    
    <!-- insert – 映射插入语句
      注: sql中参数最好和po中属性命名一致   
     -->
    <insert id="insertProduct" parameterType="com.sl.po.Product">
        insert into products(name,description,UnitPrice,IsNew)
        values(#{name},#{description},#{UnitPrice},#{IsNew})
    </insert>
    
    <!-- update – 映射更新语句 -->
    <update id="updateProduct" parameterType="com.sl.po.Product">
        update products set UnitPrice = #{UnitPrice},IsNew=#{IsNew} where id=#{id}
    </update>
    
    <!-- delete – 映射删除语句-->
    <delete id="deleteProduct" parameterType="int">
        delete from products where id=#{id}
    </delete>
</mapper>

测试代码:


public class TestClient {

    // 定义会话SqlSession
    SqlSession session = null;

    @Before
    public void init() throws IOException {
        // 定义mabatis全局配置文件
        String resource = "SqlMapConfig.xml";

        // 加载mybatis全局配置文件
        // InputStream inputStream =
        // TestClient.class.getClassLoader().getResourceAsStream(resource);

        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(inputStream);
        // 根据sqlSessionFactory产生会话sqlsession
        session = factory.openSession();
    }

    // select by id
    // @Test
    public void testSelectProduct() {
        String statement = "com.sl.mapper.ProductMapper.selectProduct";
        Product product = session.selectOne(statement, 1);
        System.out.println(product);

        session.close();
    }

    // insert
    // @Test
    public void testInsertProduct() {
        String statement = "com.sl.mapper.ProductMapper.insertProduct";
        Product product = new Product();
        product.setName("小酒馆");
        product.setDescription("xxxx");
        product.setIsNew(true);
        product.setUnitPrice(new BigDecimal(1000));
        int count = session.insert(statement, product);
        // System.out.println(product);
        session.commit();// insert 需要commit
        session.close();
    }

    // update
    // @Test
    public void testUpdateProduct() {
        String statement = "com.sl.mapper.ProductMapper.updateProduct";
        Product product = new Product();
        product.setId(24);
        product.setIsNew(true);
        product.setUnitPrice(new BigDecimal(2000));

        int count = session.update(statement, product);
        // System.out.println(product);
        session.commit();// insert 需要commit
        session.close();
    }

    // update
    // @Test
    public void testProduct() {
        String statement = "com.sl.mapper.ProductMapper.deleteProduct";

        int count = session.delete(statement, 24);
        // System.out.println(product);
        session.commit();// insert 需要commit
        session.close();
    }
}

View Code

Mapper 输入参数映射配置

Mybatis中parameterType为输入参数类型,可以配置为基本数据类型、基本数据包装类型、或自定义数据类型(JavaBean),Sql语句中使用#{}或${}传入参数。

#{}实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符,使用占位符#{}可以防止sql注入,使用时不需要关心参数值的类型,mybatis将自动进行java类型和jdbc类型的转换。

${}可以将参数拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果传入的是个简单类型,括号中只能是value,即:${value}:

示例:

     <!-- ${} sql拼接 -->
     <select id="selectProductByName" parameterType="string" resultType="com.sl.po.Product">
      select * from products where name like '%${value}%'
     </select>
     <!-- #{} 参数化 -->
      <select id="selectProductByName2" parameterType="string" resultType="com.sl.po.Product">
      select * from products where name like #{value}
     </select>

@Test
    public void testSelectByProductName() {
        //使用like '%${value}%'
        String statement = "com.sl.mapper.ProductMapper.selectProductByName";
        List<Product> listProduct = session.selectList(statement,"琶洲");
        for (Product product : listProduct) {
            System.out.println(product);
        }
        
        System.out.println("***************************************************");
        
        //使用 like #{value}
        String statement2 = "com.sl.mapper.ProductMapper.selectProductByName2";
        List<Product> listProduct2 = session.selectList(statement2,"%国际%");
        for (Product product : listProduct2) {
            System.out.println(product);
        }
        // 关闭会话
        session.close();
    }

View Code

映射基本数据类型

<select id="selectProduct" parameterType="int" resultType="com.sl.po.Product">
        select * from products where id = #{id}
    </select>

映射基本数据类型时,也参数名也可用value代替,#{value}   即:  select * from products where id = #{id}

映射pojo对象

<!-- pojo -->
     <select id="selectProductByPoJo" parameterType="com.sl.po.Product" resultType="com.sl.po.Product">
      select * from products where unitprice>#{UnitPrice} and isnew =#{IsNew} 
</select>

参数名必须与pojo对象属性一致,此处UnitPrice 与 IsNew为Product属性。


       @Test
    public void testselectProductByPoJo() {
        
        String statement = "com.sl.mapper.ProductMapper.selectProductByPoJo";
        Product pro = new Product();
        pro.setUnitPrice(new BigDecimal(30));
        pro.setIsNew(true);
        
        List<Product> listProduct = session.selectList(statement,pro);
        for (Product product : listProduct) {
            System.out.println(product);
        }
        
        // 关闭会话
        session.close();
    }

View Code

映射pojo封装对象

    <!-- pojo包装对象 -->
     <select id="selectProductByVo" parameterType="com.sl.po.ProductVo" resultType="com.sl.po.Product">
      select * from products where citycode=#{product.cityCode} and isnew =#{product.isNew} 
    </select>

       @Test
    public void testselectProductByVo() {
        
        String statement = "com.sl.mapper.ProductMapper.selectProductByVo";
        ProductVo vo= new ProductVo();
        //vo.setCategory(category);
        Product po =new Product();
        po.setCityCode("A01");
        po.setIsNew(true);
        vo.setProduct(po);
        
        List<Product> listProduct = session.selectList(statement,vo);
        for (Product product : listProduct) {
            System.out.println(product);
        }
        
        // 关闭会话
        session.close();
    }

View Code


public class ProductVo {

    private int category;
    
    private Product product;
    
    
    public int getCategory() {
        return category;
    }

    public void setCategory(int category) {
        this.category = category;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }
}

View Code

映射hashmap

     <!-- hashmap -->
     <select id="selectProductByHashMap" parameterType="hashmap" resultType="com.sl.po.Product">
      select * from products where citycode=#{cityCode} and isnew =#{isNew} 
    </select>

       @Test
    public void testselectProductByHashMap() {
        
        String statement = "com.sl.mapper.ProductMapper.selectProductByHashMap";
        
        HashMap<String, Object> map =new HashMap<String, Object>();
        map.put("cityCode", "A02");
        map.put("isNew", true);
        
        List<Product> listProduct = session.selectList(statement,map);
        for (Product product : listProduct) {
            System.out.println(product);
        }
        
        // 关闭会话
        session.close();
    }

View Code

Mapper 结果集映射配置

MyBatis的mapper映射文件中,resultType为输出结果集类型,同样支持基本数据类型及自定义数据类型。SQL语句查询后返回的结果集会映射到配置标签的输出映射属性对应的Java类型上。Mapper的输出映射有两种配置,分别是resultType和resultMap,注意两者不能同时使用。

映射基本数据类型

<!-- 返回结果只有一行一列时可以使用基本数据类型 -->
    <select id="countProducts" resultType="int">
        select count(1) from products 
    </select>

       @Test
    public void testCountProduct() {
        String statement = "com.sl.mapper.ProductMapper.countProducts";

        int count = session.selectOne(statement);
        System.out.println(count);
        session.commit();// insert 需要commit
        session.close();
    }

View Code

映射pojo对象

<!-- 返回自定义类型  返回List<PoJo>,  resultType配置为PoJo类型,而不是List-->
    <select id="selectProductById" parameterType="int" resultType="com.sl.po.Product">
        select * from products where id = #{id}
    </select>

public void testSelectProduct() {
        String statement = "com.sl.mapper.ProductMapper. selectProductById ";
        Product product = session.selectOne(statement, 1);
        System.out.println(product);

        session.close();
    }

View Code

映射pojo列表

注意:映射pojo单个对象和映射pojo列表mapper配置文件中resultType都配置为pojo类型,

区别只是返回单个对象是内部调用session.selectOne返回pojo对象,返回pojo列表时内部调用session.selectList方法。

<!-- 返回自定义类型
返回单个对象,  resultType为返回对象的类型 
--> <select id="selectAllProduct" resultType="com.sl.po.Product"> select * from products </select>

        @Test
    public void testSelectAllProduct() {
        String statement = "com.sl.mapper.ProductMapper.selectAllProduct";
        List<Product> listProduct = session.selectList(statement);
        for (Product product : listProduct) {
            System.out.println(product);
        }
        // 关闭会话
        session.close();
    }

View Code

映射hashmap

     <!-- 返回hashmap -->
    <select id="selectProductById2" parameterType="int" resultType="hashmap">
        select * from products where id = #{id}
    </select>
    <!-- 返回List<hashmap> -->
    <select id="selectAllProduct2" resultType="hashmap">
        select * from products
    </select>

     @Test
    public void testSelectProductById() {
        String statement = "com.sl.mapper.ProductMapper.selectProductById2";
        HashMap<String, Object> map = session.selectOne(statement, 1);

        Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
        }
        // 关闭会话
        session.close();
    }

@Test
        public void testSelectProducts2() {
            String statement = "com.sl.mapper.ProductMapper.selectAllProduct2";
            
            List<HashMap<String, Object>> list = session.selectList(statement);

            for (HashMap<String, Object> map : list) {
                Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, Object> entry = it.next();
                    System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
                }
            }
            
            // 关闭会话
            session.close();
        }

View Code

使用resultMap映射结果集

使用resultType可以映射结果集时需要pojo的属性名和sql查询结果的列名一致才可以映射成功。如果sql查询结果集字段名和pojo的属性名不一致,则需要通过resultMap将字段名和属性名作一个对应关系(sql 查询取别名与pojo属性一致也可以) ,resultMap实质上还需要将查询结果映射到pojo对象中。resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

    <!-- 使用resultMap映射结果集   -->
    <select id="selectProductInfo" resultMap="productInfoResultMap">
        select p.`Name` pName,p.Description,c.citycode,c.`name` cName 
        from products  p
        join city c
        on p.citycode = c.citycode
    </select>
    <resultMap id="productInfoResultMap" type="com.sl.po.ProductInfo">
          <result property="ProductName" column="pName"/>
          <result property="CityName" column="cName"/>
    </resultMap>

@Test
    public void testselectProductInfo() {
        String statement = "com.sl.mapper.ProductMapper.selectProductInfo";

        List<ProductInfo> list = session.selectList(statement);
        for (ProductInfo info : list) {
            System.out.println(info);
        }
        session.close();
    }

View Code


public class ProductInfo {

    private int Id;
    private String ProductName;
    private String Description;
    private String CityCode;
    private String CityName;
    
    
    public int getId() {
        return Id;
    }
    public void setId(int id) {
        Id = id;
    }
    public String getProductName() {
        return ProductName;
    }
    public void setProductName(String productName) {
        ProductName = productName;
    }
    public String getDescription() {
        return Description;
    }
    public void setDescription(String description) {
        Description = description;
    }
    public String getCityCode() {
        return CityCode;
    }
    public void setCityCode(String cityCode) {
        CityCode = cityCode;
    }
    public String getCityName() {
        return CityName;
    }
    public void setCityName(String cityName) {
        CityName = cityName;
    }
    
    @Override
    public String toString() {
        return "Product [id=" + Id + ", ProductName=" + ProductName + ", Description=" + Description
                + ", CityCode=" + CityCode + ", CityName=" + CityName + "]";
    }
}

View Code