3.1 环境准备

  1. 准备数据库表

    -- 删除tb_brand表 
    drop table if exists tb_brand; 
    -- 创建tb_brand表 
    create table tb_brand
    (
    -- id 主键
    id int primary key auto_increment,
    -- 品牌名称
    brand_name varchar(20),
    -- 企业名称
    company_name varchar(20),
    -- 排序字段
    ordered int,
    -- 描述信息
    description varchar(100),
    -- 状态:0:禁用 1:启用
    status int
    );
    -- 添加数据
    insert into tb_brand (brand_name, company_name, ordered, description, status
    values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
    ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、
    ('小米', '小米科技有限公司', 50, 'are you ok', 1);
    
  2. 实体类Brand

    public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用 1:启用
    private Integer status;
    //省略 setter and getter。自己写时要补全这部分代码
    }
    
  3. 测试用例

    在resources下引入xml文件

    并且com.ucloud.mapper一定要逐级建包,并引入mapper.xml文件

    Untitled

  4. 安装MyBatisX插件

3.2 配置文件完成CRUD

3.2.1 查询

  1. 查询所有数据

    Mapper接口

    public interface BrandMapper {
     
        public List<Brand> selectAll();
    }
    

    Mapper.xml

    <mapper namespace="com.ucloud.mapper.BrandMapper">
        <resultMap id="brandResultMap" type="brand">
     
            <result column="brand_name" property="brandName"/>
            <result column="company_name" property="companyName"/>
        </resultMap>
    <!--进行别名定义-->
        <select id="selectAll" resultType="brand" resultMap="brandResultMap">
            select * from  tb_brand;
        </select>
    </mapper>
    

    编写测试方法

    @Test
        public void testSelectAll() throws IOException {
            //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.
                    getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory =
                    new SqlSessionFactoryBuilder().build(inputStream);
     
    //2. 获取SqlSession对象,用它来执行sql
            SqlSession sqlSession = sqlSessionFactory.openSession();
    //3. 执行sql
            BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
            List<Brand> brands = brandMapper.selectAll();
    //参数是一个字符串,该字符串必须是映射配置文件的namespace.id
            System.out.println(brands);
    //4. 释放资源
            sqlSession.close();
        }
    
  2. 查看详情

    Mapper接口

    Brand selectById(int id);
    

    Mapper.xml

    <select id="selectById" parameterType="int" resultMap="brandResultMap">
        select * from  tb_brand where id=#{id};
    </select>
    

    编写测试方法: 在 MybatisTest 类中编写测试查询所有的方法

    @Test
        public void testSelectById() throws IOException {
           //接收参数
            int id=1;
            //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.
                    getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory =
                    new SqlSessionFactoryBuilder().build(inputStream);
     
    //2. 获取SqlSession对象,用它来执行sql
            SqlSession sqlSession = sqlSessionFactory.openSession();
    //3. 执行sql
            BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
            Brand brand = brandMapper.selectById(id);
    //参数是一个字符串,该字符串必须是映射配置文件的namespace.id
            System.out.println(brand);
    //4. 释放资源
            sqlSession.close();
        }
    

    <aside> 🌷 mybatis提供了两种参数占位符

    **#{}** :执行SQL时,会将 #{} 占位符替换为?,将来自动设置参数值。从上述例子可 以看出使用#{} 底层使用的是PreparedStatement,好处:安全

    ${} :拼接SQL。底层使用的是 Statement ,会存在SQL注入问题。表名或者列名不确定的情况

    </aside>

    <aside> 🌷 特殊字符的处理

    第一种方法:

    Untitled

    第二种方法:

    Untitled

    </aside>

    <aside> 🌷 parameterType使用

    对于有参数的mapper接口方法,我们在映射配置文件中应该配置 ParameterType 来 指定参数类型。只不过该属性都可以省略。

    </aside>

  3. 多条件查询**: 动态SQL查询**

    Mapper接口

    List<Brand>selectByCondition(
                @Param("status")int status,
                @Param("companyName")String companyName,
                @Param("brandName")String brandName
        );
    

    Mapper.xml

    <select id="selectByCondition" resultMap="brandResultMap">
       select * from  tb_brand
        <where>
            <if test="status!=null">
                and status=#{status}
            </if>
            <if test="companyName!=null and companyName!=''">
                and company_name like #{companyName}
            </if>
            <if test="brandName!=null and brandName!=''">
                and brand_name like #{brandName}
            </if>
        </where>
    

    编写测试方法:在 MybatisTest 类中编写测试查询所有的方法

    @Test
        public void testSelectByCondition() throws IOException {
            //接收参数
            int status=1;
           String companyName="华为";
           String brandName="华为";
           companyName="%"+companyName+"%";
           brandName="%"+brandName+"%";
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.
                    getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory =
                    new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
            List<Brand> brands= brandMapper.selectByCondition(status,companyName,brandName);
            System.out.println(brands);
            sqlSession.close();
        }
    

    <aside> 🌷 @Param("参数名称")

    使用 @Param("参数名称") 标记每一个参数,在映射配置文件中就需要使用 #{参数 名称} 进行占位

    </aside>

  4. 单个条件动态查询

    Mapper接口

    List<Brand> selectByConditionSingle(Brand brand);
    

    Mapper.xml

    <select id="selectByConditionSingle" resultMap="brandResultMap">
        select * from  tb_brand
        <where>
            <choose>
                <when test="status!=null"><!--相当于case-->
                    status=#{status}
                </when>
                <when test="companyName!=null and companyName!=''"><!--相当于case-->
                    company_name like #{companyName}
                </when>
                <when test="brandName!=null and brandName!=''"><!--相当于case-->
                    brand_name like #{brandName}
                </when>
            </choose>
        </where>
    </select>
    

    编写测试方法: 在 MybatisTest 类中编写测试查询所有的方法

    @Test
        public void testSelectBySingle() throws IOException {
            //接收参数
            int status=1;
            String companyName="华为";
            String brandName="华为";
            companyName="%"+companyName+"%";
            brandName="%"+brandName+"%";
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.
                    getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory =
                    new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
    
            List<Brand> brands= brandMapper.selectByCondition(status,companyName,brandName);
    // c传入对象查询
    				List<Brand> brands= brandMapper.selectByCondition(brand);
    // 传入map集合
    				List<Brand> brands= brandMapper.selectByCondition(map);
            System.out.println(brands);
            sqlSession.close();
        }
    

3.2.2 动态SQL查询

<aside> 🌷 if标签

针对上述的需要,Mybatis对动态SQL有很强大的支撑:

if 
choose (when, otherwise) 
trim (where, set)
foreach

if 标签:条件判断

test 属性:逻辑表达式

</aside>

<aside> 🌷 where 标签

作用: 替换where关键字

会动态的去掉第一个条件前的 and; 如果所有的参数没有值则不加where关键字

</aside>

3.2.2.1 if

使用恒等式来对查询条件进行统一

<select id="selectByCondition" resultMap="brandResultMap">
	select * from  tb_brand
	where **1 = 1**
	    <if test="status!=null">
	        and status=#{status}
	    </if>
	    <if test="companyName!=null and companyName!=''">
	        and company_name like #{companyName}
	    </if>
	    <if test="brandName!=null and brandName!=''">
	        and brand_name like #{brandName}
	    </if>
</select>

3.2.2.2 where

在不使用恒等式的情况下可以使用<where>标签

<select id="selectByCondition" resultMap="brandResultMap">
	select * from  tb_brand
	<where>
	    <if test="status!=null">
	        status=#{status}
	    </if>
	    <if test="companyName!=null and companyName!=''">
	        company_name like #{companyName}
	    </if>
	    <if test="brandName!=null and brandName!=''">
	        brand_name like #{brandName}
	    </if>
	</where>
</select>

3.2.2.3 choose

效果等同于switch—case;配套使用的还有when, otherwise

<choose>
  <when test="status!=null"><!--相当于case-->
      status=#{status}
  </when>
  <when test="companyName!=null and companyName!=''"><!--相当于case-->
      company_name like #{companyName}
  </when>
  <when test="brandName!=null and brandName!=''"><!--相当于case-->
      brand_name like #{brandName}
  </when>
	<otherwise>
		1 = 1
	</otherwise>
</choose>

3.2.3 添加

Mapper接口

void add(Brand brand);

Mapper.xml

<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>

编写测试方法: 在 MybatisTest 类中编写测试查询所有的方法

@Test
    public void testAdd()throws IOException{
        //接收参数
        int status=1;
        String companyName="苹果手机";
        String brandName="苹果";
        String description="手机中贵族";
        int ordered=100;
 
        //封装对象
        Brand brand=new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);
        brand.setDescription(description);
        brand.setOrdered(ordered);
 
 
        String url="mybatis-config.xml";
        InputStream inputStream= Resources.getResourceAsStream(url);
        //1.加载mybatis核心配置文件mybatis-config.xml    获取SqlSessionFactory
        SqlSessionFactory factory=
                new SqlSessionFactoryBuilder().build(inputStream);
 
        //2.获取SqlSession对象,用它来执行sql
        SqlSession sqlSession= factory.openSession();
        //3.执行方法   获取Mapper接口的代理对象
        BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
        brandMapper.add(brand);
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }

3.2.3.1 事务提交

<aside> 🌷 SqlSession sqlSession= factory.openSession();

当传入的参数为True,设置为自动提交;传入参数为false,设置为手动提交,需要在释放SQLSession之前手动提交事务:

sqlSession.commit();

</aside>

3.2.3.2 主键返回

使用两个属性useGeneratedKeys和keyProperty;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>

获取id的方法:

brandMapper.add(brand);
Integer id = brand.getId();
System.out.println(id);

3.2.4 修改

Mapper接口

void update (Brand brand);

Mapper.xml

<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>

编写测试方法

@Test
    public void testUpdate()throws IOException{
        //接收参数
        int status=1;
        String companyName="苹果手机";
        String brandName="苹果";
        String description="手机中贵族";
        int ordered=100;
        int id=1;
 
        //封装对象
        Brand brand=new Brand();
        brand.setStatus(status);
        brand.setId(id);
 
        String url="mybatis-config.xml";
        InputStream inputStream= Resources.getResourceAsStream(url);
        //1.加载mybatis核心配置文件mybatis-config.xml    获取SqlSessionFactory
        SqlSessionFactory factory=
                new SqlSessionFactoryBuilder().build(inputStream);
 
        //2.获取SqlSession对象,用它来执行sql
        SqlSession sqlSession= factory.openSession();
        //3.执行方法   获取Mapper接口的代理对象
        BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
        brandMapper.update(brand);
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }

3.2.5 删除

3.2.5.1 删除一个

Mapper接口

void deleteById(int id);

Mapper.xml

<delete id="deleteById">
    delete from tb_brand where id=#{id};
</delete>