SpringBoot整合Mybatis(小白也秒懂)

SpringBoot整合Mybatis

创建数据库和表

-- 删除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, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1);

创建项目

目录结构

在这里插入图片描述

导入pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
<!--        日志依赖-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yml配置

server:
  port: 8888

spring:
  application:
    name: mybatis_test
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_test?useSSL=false&serverTimezone=UTC
    username: root
    password: 1234
mybatis:
  mapper-locations: classpath:dao/*.xml
  map-underscore-to-camel-case: true

这里主要是配置数据源和mybatis的配置

mapper-locations:xml扫描,多个目录用逗号或者分号分隔(告诉 Dao所对应的 XML 文件位置)

map-underscore-to-camel-case:驼峰命名法转换

创建对应实体类

@Data
public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;
}

创建数据层Dao类

@Mappre
public interface BrandDao {
    
}

@Repository和@Mapper的区别

  • @Repository和@Mapper都是作用在dao层的接口,使其生成代理对象Bean。
  • @Repository:需要在添加配置地址@MapperScannerConfigurer来使用,单独使用会报错
  • @Mapper:只需要在dao类上使用就行,若有多个Mapper在启动类上加MapperScan(“mapper所在的包”)就行

创建对应的Dao对应的xml文件

resources包下创建路径与Dao一样的包,这里要注意创建多级包的时候不要用“.”的方式例如:com.mybatistest.dao。而是要用“/”的方式,例如com/mybatistest/dao,创建好包后再创建与Dao类同名的xml文件如:BrandDao.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.example.mybatistest.dao.BrandDao">
    
</mapper>

这里的mapper标签表示对应的命名空间

  • namespace属性:填入对应的Dao地址

使用mybatis进行增删改查

查询方法
  1. 查询所有
    在BrandDao中编写方法

        /**
         * 查询所有
         * @return
         */
        List<Brand> selectAll();
    

    在BrandDao.xml中编写对应的sql语句,这里可以使用mybatisX插件来自动生成,生成方法:安装好插件并重启后选中方法名,按住 alt+enter。

    在BrandDao.xml中编写条件查询所有的sql语句

    <?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.example.mybatistest.dao.BrandDao">
        <!--    查询所有对象-->
        <select id="selectAll" resultMap="brandResultMap">
            select *
            from tb_brand;
        </select>
        
        <resultMap id="brandResultMap" type="com.example.mybatistest.domain.Brand">
            <result column="brand_name" property="brandName"/>
            <result column="company_name" property="companyName"/>
        </resultMap>
    </mapper>
    

    select标签代表查询

    • id属性:Dao对应的方法名
    • resultMap属性:要使用哪个resultMap标签的内容

    resultMap标签来定义字段和属性的映射关系的方式,在domain实体类属性名与表中的列名不一致的时候可以使用

    • id属性:唯一性的名称,以此名称用来被使用
    • type属性:用来指定哪个domain实体类
    • column属性:代表数据库表的列名
    • property属性:代表domain实体类中的属性名

    一个result标签代表一组映射关系

    在测试类中测试

     @Test
        void testSelectAll(){
            List<Brand> brands = brandDao.selectAll();
            System.out.println(brands);
        }
    

    运行结果

    [Brand(id=1, brandName=三只松鼠, companyName=三只松鼠股份有限公司, ordered=5, description=好吃不上火, status=0), Brand(id=2, brandName=华为, companyName=华为技术有限公司, ordered=100, description=华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界, status=1), Brand(id=3, brandName=小米, companyName=小米科技有限公司, ordered=50, description=are you ok, status=1)]
    
  2. 根据id查询

    在BrandDao中添加对应方法

    	 /**
         * 根据id查询
         * @param id
         * @return
         */
        Brand selectById(int id);
    

    在xml中添加对应的sql语句

    <!--    根据id查询对象-->
        <select id="selectById" resultMap="brandResultMap" parameterType="int">
            select *
            from tb_brand
            where id = #{id};
        </select>
    

    parameterType属性:ParameterType 来指定参数类型。只不过该属性都可以省略。

    mybatis提供了两种参数占位符

    • #{} :执行SQL时,会将 #{} 占位符替换为?,将来自动设置参数值。#{} 底层使用的是 PreparedStatement(安全)

    • ${} :拼接SQL。底层使用的是 Statement(不安全),会存在SQL注入问题。

    编写测试方法

    	@Test
        void testSelectById(){
            int id = 2;
            Brand brand = brandDao.selectById(id);
            System.out.println(brand);
        }
    

    运行结果

    查id为2的数据

    Brand(id=2, brandName=华为, companyName=华为技术有限公司, ordered=100, description=华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界, status=1)
    
  3. 固定条件个数的多条件查询

    我们在开发中经常会遇到多条件查询,例如有好几个输入框,根据用户输入的数据进行查询

    在BandDao中编写方法

    	 /**
         * 固定条件个数的多条件查询
         * @param brand
         * @return
         */
        List<Brand> selectByCondition(Brand brand);
    

    在xml文件中添加对应的sql语句

    <!--    多条件查询-->
        <select id="selectByCondition" resultMap="brandResultMap">
            select *
            from tb_brand
            where status = #{status}
            and brandName like #{brandName}
            and company_name like #{companyName};
        </select>
    

    编写测试方法

        @Test
        void testSelectCondition(){
            Brand brand = new Brand();
            brand.setStatus(1);
            brand.setBrandName("%小米%");
            brand.setCompanyName("%小米科技有限公司%");
            List<Brand> brands = brandDao.selectByCondition(brand);
            System.out.println(brands);
        }
    

    运行结果

    [Brand(id=3, brandName=小米, companyName=小米科技有限公司, ordered=50, description=are you ok, status=1)]
    
  4. 动态条件个数的多条件查询

    上面多条件是固定条件个数的,而在实际情况下,往往不确定客户会输入几个查询条件,以下是动态条件个数的多条件查询

    该功能有多个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现

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

      List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName,@Param("brandName") String brandName);
      
    • 将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和实体类属性名保持一致。

      List<Brand> selectByCondition(Brand brand);
      
    • 将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和map集合中键的名称一致。

      List<Brand> selectByCondition(Map map);
      

    在BrandDao中编写方法

       /**
         * 动态条件个数的多条件查询
         * @param brand
         * @return
         */
        List<Brand> selectByConditions(Brand brand);
    

    在xml文件中添加对应的sql语句

    <!--    动态多条件查询-->
        <select id="selectByConditions" resultMap="brandResultMap">
            select *
            from tb_brand
            <where>
            <if test="status != null">
                and status = #{status}
            </if>
            <if test="brandName != null and brandName != ''">
                and brand_name like #{brandName}
            </if>
            <if test="companyName != null and companyName != ''">
                and company_name like #{companyName}
            </if>
            </where>
        </select>
    

    以上语句用where标签代替了where关键字可以在status有传入数据的时候拼接sql语句时忽略前面的and。

    if标签来判断字段有没有输入参数,有的话就拼接sql语句,没有则不拼接

    测试方法

        @Test
        void testSelectConditions(){
            Brand brand = new Brand();
            Brand brand2 = new Brand();
            Brand brand3 = new Brand();
            brand.setStatus(1);
            brand2.setBrandName("%小米%");
            brand3.setCompanyName("%小米科技有限公司%");
            List<Brand> brands1 = brandDao.selectByConditions(brand);
            List<Brand> brands2 = brandDao.selectByConditions(brand2);
            List<Brand> brands3 = brandDao.selectByConditions(brand3);
            System.out.println(brands1);
            System.out.println(brands2);
            System.out.println(brands3);
        }
    

    模拟用户输入的三种条件情况

    运行结果

    [Brand(id=2, brandName=华为, companyName=华为技术有限公司, ordered=100, description=华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界, status=1), Brand(id=3, brandName=小米, companyName=小米科技有限公司, ordered=50, description=are you ok, status=1)]
    [Brand(id=3, brandName=小米, companyName=小米科技有限公司, ordered=50, description=are you ok, status=1)]
    [Brand(id=3, brandName=小米, companyName=小米科技有限公司, ordered=50, description=are you ok, status=1)]
    
  5. 动态单条件查询

    在查询时只能选择 品牌名称当前状态企业名称 这三个条件中的一个,但是用户到底选择哪儿一个,我们并不能确定。这种就属于单个条件的动态SQL语句。

    这种需求需要使用到 choose(when,otherwise)标签 实现, 而 choose 标签类似于Java 中的switch语句。

    在BrandDao中编写方法

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

    在xml文件中添加sql语句

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

    这里使用choosewhen标签来选择输入的数据再进行sql语句的拼接。

    测试方法

    运行结果


增加方法
  1. 在BrandDao中编写方法

    /**
     * 增加数据
     * @param brand
     * @return
     */
    int add(Brand brand);
    
  2. 在xml文件中添加sql语句

    <!--    增加对象-->
        <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>
    

    useGeneratedKeys属性:是够获取自动增长的主键值。true表示获取

    keyProperty属性:指定将获取到的主键值封装到哪儿个属性里

  3. 编写测试方法

    @Test
    void testAdd(){
        Brand brand = new Brand();
        brand.setBrandName("魅族");
        brand.setCompanyName("魅族科技有限公司");
        brand.setStatus(1);
        brand.setOrdered(100);
        brand.setDescription("轻易不说完美");
        int add = brandDao.add(brand);
        if(add > 0){
            System.out.println("添加成功");
        }else {
            System.out.println("添加失败");
        }
    
    }
    

修改方法
  1. 在BandDao中编写方法

    /**
     * 修改数据
     * @param brand
     * @return
     */
    int update(Brand brand);
    
  2. 在xml文件中添加sql语句

    <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 and status != ''">
                status = #{status}
            </if>
        </set>
        where id = #{id};
    </update>
    

    这里使用set标签代替了set关键字,该标签可以用于动态包含需要更新的列,忽略其它不更新的列。使用if标签来判断哪些字段需要被修改,这里要注意不要忽略了if标签内sql的最后一个逗号。

  3. 编写测试方法

    @Test
    void testUpdate(){
        Brand brand = new Brand();
        brand.setBrandName("魅蓝");
        brand.setDescription("年轻,无所畏惧");
        brand.setId(5);
        int update = brandDao.update(brand);
        if(update > 0){
            System.out.println("修改成功");
        }else {
            System.out.println("修改失败");
        }
    }
    

删除方法
  1. 单个数据删除
    在BandDao中编写方法

    /**
     * 根据id删除数据
     * @param id
     * @return
     */
    int deleteById(int id);
    

    在xml文件中添加sql语句

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

    编写测试方法

    @Test
    void testDeleteById(){
        int i = 5;
        int i1 = brandDao.deleteById(i);
        if(i1 > 0){
            System.out.println("删除成功");
        }else {
            System.out.println("删除失败");
        }
    }
    
  2. 批量删除

    在BandDao中编写方法

    /**
     * 批量删除
     * @param ids
     * @return
     */
    int deleteAll(int[] ids);
    

    在xml文件中添加sql语句

    <delete id="deleteAll">
        delete from tb_brand where id
        in
        <foreach collection="array" item = "id" separator="," open="(" close=")">
            #{id}
        </foreach>
        ;
    </delete>
    

    这里使用foreach标签来循环遍历数组

    collection属性:

    mybatis会将数组参数,封装为一个Map集合。

    • 默认:array = 数组
    • 可以使用@Param注解改变map集合的默认key的名称

    item属性:本次迭代获取到的元素。

    separator属性:集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。

    open属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一

    close属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次

    假如数组中的id数据是{1,2,3},那么拼接后的sql语句就是:

    delete from tb_brand where id in (1,2,3);
    

    编写测试方法:

        @Test
        void testDeleteAll(){
            int[] arr = {1,2,3};
            int i = brandDao.deleteAll(arr);
            System.out.println(i);
        }
    }
    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值