Mybatis

  1. mybatis

  • 是一款优秀的持久层框架,用于简化JDBC开发的。

  • 持久层:就是将数据保存到数据库的那层代码。

  • javeEE 三层架构,表现层,业务层,持久层。

  1. 框架

  • 框架就是一个半成品软件,是一套可重用的,通用的,软件基础代码模型

  • 在框架的基础之上构建软件编写更加高效,规范,通用,可扩展。

官网:http://mybatis.org/mybatis-3/zh/index.html

传递参数

  • SQL语句设置多个参数有三种方式

    1. 散装参数:需要使用@Param(Sql中参数占位符)

    2. 实体类封装参数

      *只需要保证SQL中的参数名和实体类属性名对应上

    3. map集合

      * 只需要保证SQL中的参数名和map集合的键的名称对应上

案例

  • 要完成的功能列表清单

    1. 查询

      *查询所有数据

      *查看详情

      *条件查询

  1. 添加

  2. 修改

    *修改全部字段

    *修改动态字段

  3. 删除

    *删除一个

    *批量删除

总结

  • Mybatis完成操作需要几步?

    三步:编写接口方法-->编写SQL-->执行方法

 

条件查询

  • 查询-多条件-动态查寻

  • SQL语句会随着用户的输入或者外部的变化而变化,我们称之为动态sql。

  • Mybatis对动态SQL有很强大的支撑

    *if

    *choose(when,otherwise)

    *trim(where,set)

    *foreach

设置字符集

  • setting--->Editor-->File Encodings 改三处:

*Global Encoding

*Project Encoding

*Default Encoding

  • 具体

    useUnicode=true&characterEncoding=UTF-8"

mybatis 参数传递

  • MyBatis接口方法中可以接收各种各样的参数,mybatis底层

对于这些参数进行不同的封装处理方式

*单个参数

  1. POJO类 :直接使用,属性名和参数占位符名称一致

  2. Map集合:直接使用,键名 和参数占位符名称一致

  3. Collection: 封装为Map集合 @Param

    map.put("arg0",collection集合)

    map.put("collection",collection集合)

  4. List @Param

    map.put("arg0",list集合)

    map.put("collection",list集合)

    map.put("li'st",list集合)

  5. Array:封装为Map集合 @Param

    map.put("arg0"数组)

    map.put("array",组)

  6. 其它:直接使用

    *多个参数 @Param

    封装为Map集合,可以使用@Param 注解,替换掉Map集合中arg键名

    默认键名 :map.put("arg0",参数值1)

    map.put("param1",参数值1

    map.put("arg1",参数值2)

    map.put("param2",组参数值2

    *总结:建议使用@Param 注解来修改Map集合中的默认键名,并使用修改后的名称来获取值,这样可读性更高。

     

    总结代码

    *映射文件:重要

    <?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.yang.mapper.BrandMapper">

       <!--发现一个问题:
       数据库的表字段和实体类的属性不一致,导致不能完成自动封装
        解决方法2种: *起个别名  将不一致的名字起别名
                         缺点:每次都得写
                    *写个sql片段
                         缺点:不灵活
                    *resultMap:
                          * 定义<resultMap>标签
                          * 要将<select>标签中的<resultType>标签替换
       -->
       <!--
         id:唯一标识
         type:映射的类型,支持别名
       -->
       <resultMap id="brandResultMap" type="brand">
           <!--
              <resultMap>标签下2个:
                  <id>:主键的字段的映射
                      <column> :表的列名
                      <property>:实体类的属性名
                  <result>: 完成一般字段的映射
                       <column> :表的列名
                      <property>:实体类的属性名
           -->
           <result column="brand_name" property="brandName"></result>
           <result column="company_name" property="companyName"></result>
       </resultMap>

       <select id="selectAll" resultMap="brandResultMap">
           select *
           from tb_brand;
       </select>
       <!--sql片段
       <sql id="brand_column">
           id, brand_name as brandName,company_name as companyName,ordered,description,status
       </sql>
       //查询所有
       <select id="selectAll" resultType="brand">
           select
           <include refid="brand_column"/>
           from tb_brand;
       </select>-->
       <!--别名-->
       <!-- <select id="selectAll" resultType="brand">
            select  id, brand_name as brandName,company_name as companyName,ordered,description,status
            from tb_brand;
        </select>-->
       <!--缺陷-->
       <!--<select id="selectAll" resultType="brand">
           select * from tb_brand;
       </select>-->
       <!--查询详情-->
       <!--  参数占位符
                *#{}:会将替换为?,防止sql注入
                *${}:拼sql。会产生sql注入问题。
                *参数传递的时候一定要写 #{}
                *参数类型可以省略
                    <sselect>
                   parameterType="int"
                *特殊字符
                    1.转义字符
                    2.CDATA区
                     <![CDATA[
                             <
                            ]]>
       -->
       <!--查询详细信息-->
       <select id="selectById" resultMap="brandResultMap">
           select *
           from tb_brand
           where id = #{id};
       </select>

       <!--<select id="selectById" resultMap="brandResultMap">
           select * from tb_brand
           where id
              <![CDATA[
                 <
                ]]>
                 #{id};
       </select>-->
       <!--条件查询:都满足-->
       <!--<select id="selectByCondition" resultMap="brandResultMap">
           select *
           from tb_brand
           where status = #{status}
                 and brand_name like #{brandName}
                 and company_name like #{companyName};
       </select>-->
       <!--   动态sql条件查询
         if:条件判断
           *test:逻辑表达式
          *问题:
               第一个条件没有的的话,sql语法错误 where and ...
               解决:*恒等式 1=1
                     *<where>标签 会自动判断where条件,自动加上where或者去掉and
       -->
       <select id="selectByCondition" resultMap="brandResultMap">
           select *
           from tb_brand
           /*where 1 = 1*/
           <where>
               <if test="status != null">
                   and status = #{status}
               </if>
               <if test="brandName != null and brandName != '' ">
                   and brand_name like #{brandName}
               </if>
               /*不等于null 和 (String类型)空字符串*/
               <if test="companyName != null and companyName != '' ">
                   and company_name like #{companyName};
               </if>
           </where>
       </select>
       <!--单条件查询
       <choose> 相当于switch
       <when>相当于case
       -->
       <!--    <select id="selectByConditionSingle" resultMap="brandResultMap">
               select
                      *
               from tb_brand
               where
               <choose>
                   <when test="status != null">
                       status = #{status}
                   </when>
                   <when test="brandName != null and brandName != ''">
                       brand_name like #{brandName}
                   </when>
                   <when test="companyName != null and companyName != ''">
                       company_name like #{companyName}
                   </when>
                   <otherwise>
                       1=1
                   </otherwise>
               </choose>
           </select>-->
       <!--<where>标签包裹,防止用户不选择数据-->
       <select id="selectByConditionSingle" resultMap="brandResultMap">
           select
           *
           from tb_brand
           <where>
               <choose>
                   <when test="status != null">
                       status = #{status}
                   </when>
                   <when test="brandName != null and brandName != ''">
                       brand_name like #{brandName}
                   </when>
                   <when test="companyName != null and companyName != ''">
                       company_name like #{companyName}
                   </when>
               </choose>
           </where>
       </select>

       <!--添加数据  有时候需要返回id,需要添加useGeneratedKeys="true" keyProperty="id"标签-->
       <insert id="add" useGeneratedKeys="true" keyProperty="id">
           INSERT INTO tb_brand
              (brand_name, company_name, ordered, description, status)
           VALUES (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
       </insert>
       <!--修改数据 ,这种防止不了只修改单个的-->
       <!-- UPDATE 表名 SET 列名1=值1,列名2=值2,...[WHERE 条件]-->
       <!-- <update id="update">
           update tb_brand set
                brand_name=#{brandName},company_name=#{companyName},
                ordered=#{ordered},description=#{description},status=#{status}
            where id=#{id};
        </update>-->
       <!--动态sql修改:防止用户写只修改其中之一
        set标签和where标签一样的作用,可以规避逗号,和空字符串
       -->
       <update id="update">
           update tb_brand
           <set>
               <if test="brandName!=null and brandName!= '' ">
                   brand_name=#{brandName},
               </if>
               <if test="companyName!=null and companyName!= '' ">
                   company_name=#{companyName},
               </if>
               <if test="ordered!=null">
                   ordered=#{ordered},
               </if>
               <if test="description!=null and description!= '' ">
                   description=#{description},
               </if>
               <if test="status!=null">
                   status=#{status}
               </if>
           </set>
           where id=#{id};
       </update>
       <!--DELETE FROM 表名 [WHERE 条件]
        注意:修改语句中如果不加条件,则会将所有的数据删除。-->
       <!--单个删除-->
       <delete id="deleteById">
           delete from  tb_brand where id = #{id};
       </delete>
       
       <!--批量删除-->
           <!--
          *mybatis 会默认将数组名key的值为array
          *解决办法就是在@param("ids")
          *collection="ids"
          动态sql 用foreach标签遍历
             *item: 元素
             *collection:集合名称
             *separator:分隔符
       -->
       <delete id="deleteByIds">
           delete from  tb_brand where id in
           <foreach collection="ids" item="id" separator="," open="(" close=")">
               #{id}
           </foreach>
       </delete>
    </mapper>

    *接口:

    package com.yang.mapper;

    import com.yang.pojo.Brand;
    import org.apache.ibatis.annotations.Param;

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

    //品牌映射接口
    public interface BrandMapper {
       //查询所有数据
       List<Brand> selectAll();
       //查看详情
       List<Brand> selectById(Integer id);

       /**
        *条件查询
        *     1.散装参数 如果方法中有多个参数,则需要使用@param("sql语句中的占位符")
        *     2.对象参数 只要保证sql中的参数名和实体类中的属性名一致即可
        *     3.map集合参数
        *       只要保证sql中的参数名和map集合中的键的名称对的上就可以。
        *
        * @param status
        * @param brandName
        * @param companyName
        * @return list集合
        */
       List<Brand> selectByCondition(@Param("status") int status,@Param("brandName") String brandName,
                                     @Param("companyName") String companyName);

       /**
        * 对象参数
        * @param brand
        * @return
        */
    //   List<Brand> selectByCondition(Brand brand);

       /**
        * map集合的参数
        * @param map
        * @return
        */
    //   List<Brand> selectByCondition(Map map);

       /**
        * 单条件查询
        * @param brand
        * @return
        */
       List<Brand> selectByConditionSingle(Brand brand);

       /**
        * 添加数据
        * @param brand
        */
       void add(Brand brand);

       /**
        * 修改全部字段
        * @param brand
        */
       int update(Brand brand);

       /**
        * 删除一个
        * @param id
        */
       void deleteById(int id);

       /**
        * 批量删除
        * 传递的是数组参数
        * @param ids
        */
       void deleteByIds(@Param("ids") int[] ids);
    }

    *mybatis-config.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>
           <package name="com.yang.pojo"/>
       </typeAliases>
       <!--<environments default="development">   配置数据库连接信息,通过default默认值来切换-->
       <environments default="development">
           <environment id="development">
               <transactionManager type="JDBC"/>
               <dataSource type="POOLED">
                   <property name="driver" value="com.mysql.jdbc.Driver"/>
                   <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                   <property name="username" value="root"/>
                   <property name="password" value="123456"/>
               </dataSource>
           </environment>
           <environment id="test">
               <transactionManager type="JDBC"/>
               <dataSource type="POOLED">
                   <property name="driver" value="com.mysql.jdbc.Driver"/>
                   <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"/>
                   <property name="username" value="root"/>
                   <property name="password" value="123456"/>
               </dataSource>
           </environment>
       </environments>
       <!--加载sql映射文件-->
       <mappers>
    <!--        <mapper resource="com/yang/mapper.UserMapper.xml"/>-->
    <!--        包扫描-->
           <package name="com/yang/mapper"/>
       </mappers>
    </configuration>

    *test代码

    package com.yang.test;

    import com.yang.mapper.BrandMapper;
    import com.yang.pojo.Brand;
    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 org.junit.Test;

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    public class MybatisTest {


       @Test
       public void selectAll() throws IOException {
           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession();
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
           //4.执行方法
           List<Brand> brands = mapper.selectAll();
           System.out.println(brands);
           //4.释放资源
           sqlSession.close();
      }
       @Test
       public void selectById() throws IOException {
           int id = 1;
           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession();
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
           //4.执行方法
           List<Brand> brands = mapper.selectById(id);
           System.out.println(brands);
           //4.释放资源
           sqlSession.close();
      }

       @Test
       public void selectByCondition() throws IOException {
           int status = 1;
           String brandName = "华为";
           String companyName = "华为";
           // 数据处理
           brandName = "%"+brandName+"%";
           companyName = "%"+companyName+"%";
           //创建对象
    //       Brand brand = new Brand();
    //       brand.setStatus(status);
    //       brand.setBrandName(brandName);
    //       brand.setCompanyName(companyName);
           //创建集合
    //       Map map = new HashMap();
    //       map.put("status",status);
    //       map.put("brandName",brandName);
    //       map.put("companyName",companyName);
           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession();
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
           //4.执行方法
           List<Brand> brands = mapper.selectByCondition(status, brandName, companyName);
    //       List<Brand> brands = mapper.selectByCondition(brand);
    //       List<Brand> brands = mapper.selectByCondition(map);


           System.out.println(brands);

           //4.释放资源
           sqlSession.close();
      }
       @Test
       public void selectByConditionSingle() throws IOException {
           int status = 1;
           String brandName =  "华为";
           String companyName = "华为";
           // 数据处理
           brandName = "%"+brandName+"%";
           companyName = "%"+companyName+"%";
           //创建对象
           Brand brand = new Brand();
    //       brand.setStatus(status);
           brand.setBrandName(brandName);
    //       brand.setCompanyName(companyName);

           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession();
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
           //4.执行方法
           List<Brand> brands = mapper.selectByConditionSingle(brand);
           System.out.println(brands);
           //4.释放资源
           sqlSession.close();
      }
       @Test
       public void add() throws IOException {
           int status = 1;
           String brandName = "荣耀手机";
           String companyName = "荣耀科技有西安公司";
           String description = "这是以荣耀为主题的音乐手机之一";
           int ordered = 66;

           Brand brand = new Brand();
           brand.setStatus(status);
           brand.setBrandName(brandName);
           brand.setCompanyName(companyName);
           brand.setDescription(description);
           brand.setOrdered(ordered);

           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession();
           /*

              openSession()默认开启事务,进行增删改之后需要提交事务sqlSession.commit()
              openSession(true)可以设置true/false来表示是否自动提交事务
            */
    //       SqlSession sqlSession = sqlSessionFactory.openSession(true);
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
           //4.执行方法
           mapper.add(brand);
           /*
             获取不到id
             在sql<insert>标签中添加 useGeneratedKeys="true" keyProperty="id" 即可获取成功
            */
           Integer id = brand.getId();
           System.out.println(id);
           //6.提交事务
           sqlSession.commit();
           //5.释放资源
           sqlSession.close();

      }
       @Test
       public void update() throws IOException {
           int id = 10;
           int status = 0;
           String brandName = "女朋友手机";
           String companyName = "科技有西安公司";
           String description = "这是以为主题的音乐手机之一";
           int ordered = 200;

           //创建对象
           Brand brand = new Brand();
           brand.setStatus(status);
           brand.setBrandName(brandName);
           brand.setCompanyName(companyName);
           brand.setOrdered(ordered);
           brand.setId(id);
           brand.setDescription(description);

           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession(true);
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

           //4.执行方法
           int row = mapper.update(brand);
           System.out.println(row);

           //4.释放资源
           sqlSession.close();
      }
       @Test
       public void deleteById() throws IOException {

           int id = 10;

           //创建对象
           Brand brand = new Brand();
           brand.setId(id);

           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession(true);
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

           //4.执行方法
           mapper.deleteById(id);

           //4.释放资源
           sqlSession.close();
      }
       @Test
       public void deleteByIds() throws IOException {
           //创建一个集合,添加三个元素
          int[] ids = {4,9,11};

           //1.构建SqlSessionFactory
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           //2.获取session对象
           SqlSession sqlSession = sqlSessionFactory.openSession(true);
           //3.获得接口的代理对象
           BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

           //4.执行方法
           mapper.deleteByIds(ids);

           //4.释放资源
           sqlSession.close();
      }
    }