案例27---写出高复用性的sql:单表的11个Update接口--MyBatis

一:背景介绍

项目开发中。我们使用的是MyBatis,在MyBatis的xml文件里,两个表的更新功能,写了足足11个更新接口,毫无复用的思想
在这里插入图片描述

可以实现功能,但是没有复用的思想,没有面向对象的思想,这样的代码没有灵魂,且不易扩展,不易维护。

二:思路&方案

一个表使用只需要写一个可以复用的接口就可以完成所有需求。
我们需要准备一个使用MyBatis的maven项目。大家需要提前准备好Mysql数据库。

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration mybatis的核心配置文件-->
<configuration>
<!--引入外部配置文件-->
    <properties resource="db.properties"/>
    
    <!--配置-->
    <settings>
        <!--标准日志工厂设置-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--显示的开启全局缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
<!--可以给实体类取别名-->
    <typeAliases>
        <!--可以指定一个包名,MyBatis会在包名下面搜索需要的Java Bean-->
        <package name="org.example.pojo"/>
    </typeAliases>

    <!--environments 后面的s表示这是一个复数,可以编写多套环境  default表示默认的环境为development-->
    <environments default="development">
        <!--编写一套环境 名称为configuration-->
        <environment id="development">
            <!--jdbc的事务管理-->
            <transactionManager type="JDBC"/>
            <!--配置数据库相关数据-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <!--userSSL是一个按权连接 &amp是一个转移符 等同于and  CharacterEncoding=utf-8可以保证输入数据库的数据不乱码-->
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

<!--绑定接口-->
    <mappers>
        <mapper class="org.example.dao.UserCourseGroupConfigurationMapper"/>
    </mappers>

</configuration>

public class MybatisUtils {


    private  static SqlSessionFactory sqlSessionFactory;

    //静态代码块:一旦初始化就加载
    static{

        try {
            //使用Mybatis第一步:获取sqlSessionFactory对象
            //获取资源,直接读到mybatis-config.xml
            String resource = "mybatis-config.xml";
            //需要用到输入流(InputStream) 把resource类加载进来
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //通过build把输入流加载进来
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    public static SqlSession getSqlSession() {
        //openSession中有自动commit(提交)事务的方法,加上true就能实现
        return sqlSessionFactory.openSession(true);

    }
}

三:过程

通用的更新语句

    <update id="updateCourseGroupConfiguration">
            update arpro_user_course_group_configuration
            <trim prefix="SET" suffixOverrides=",">
                <if test="reviseParam.infoId != null">info_id = #{reviseParam.infoId}</if>
                <if test="reviseParam.courseId != null">course_id = #{reviseParam.courseId}</if>
                <if test="reviseParam.classId != null">class_id = #{reviseParam.classId}</if>
                <if test="reviseParam.groupId != null">group_id = #{reviseParam.groupId}</if>
                <if test="reviseParam.type != null">type = #{reviseParam.type}</if>
                <if test="reviseParam.isDelete != null">is_delete = #{reviseParam.isDelete}</if>
                <if test="reviseParam.remark != null">remark = #{reviseParam.remark}</if>
                <if test="reviseParam.isMostLike != null">is_like = #{reviseParam.isLike}</if>
            </trim>
            where is_delete = 0
            <if test="conditionParam.infoId != null"> and info_id = #{conditionParam.infoId}</if>
            <if test="conditionParam.courseId != null">and course_id = #{conditionParam.courseId}</if>
            <if test="conditionParam.classId != null">and class_id = #{conditionParam.classId}</if>
            <if test="conditionParam.groupId != null">and group_id = #{conditionParam.groupId}</if>
            <if test="conditionParam.isMostLike != null">and is_like = #{conditionParam.isLike}</if>
            <if test="conditionParam.type != null">and type = #{conditionParam.type}</if>
    </update>

可以覆盖到的8个更新接口

    <update id="updateGroupRelationship">
        UPDATE arpro_user_course_group_configuration
        set group_id = #{newGroupId}
        WHERE
            group_id = #{oldGroupId} and
            type = #{type}
    </update>
    
    <update id="updateGroupIsDelete">
        UPDATE arpro_user_course_group_configuration
        SET is_delete=1
        WHERE class_id = #{classId}
          AND course_id = #{courseId}
    </update>

    <update id="updateGroupIsDeleteByCourseId">
        UPDATE arpro_user_course_group_configuration
        SET is_delete=1
        WHERE  course_id = #{courseId}
    </update>

    <update id="updateGroupRelationshipByClassIdAndCourseId">
        UPDATE arpro_user_course_group_configuration
        set group_id = #{groupCourseModel.newGroupId} ,is_like = #{isLike}
        WHERE
            type = #{groupCourseModel.type} and class_id = #{groupCourseModel.classId} and course_id = #{groupCourseModel.courseId} and info_id =#{groupCourseModel.infoId}
    </update>
    
        <update id="updateCourseIsLike" parameterType="com.tfjy.arprobackend.model.GroupCourseModel">
        UPDATE arpro_user_course_group_configuration
        set  is_like = #{isLike}
        where group_id = #{groupId} and type = #{type}
    </update>

    <update id="updateUserCourseIsLike">
        UPDATE arpro_user_course_group_configuration
        set  is_like = 1
        where info_id = #{infoId} and type = #{type} and group_id != #{groupId}  and is_delete = 0
    </update>
    
    <update id="updateUserCourseNotLike">
        UPDATE arpro_user_course_group_configuration
        set  is_like = 0
        where info_id = #{infoId} and type = #{type} and group_id = #{groupId}  and is_delete = 0
    </update>


    <update id="updateGroupRelation">
        UPDATE arpro_user_course_group_configuration
        set group_id = #{newGroupId} ,info_id = #{newInfoId}
        WHERE
            type = 1 and class_id = #{classId} and course_id = #{courseId} and info_id = #{oldInfoId}
    </update>


暂时无法覆盖的一个接口

    <update id="updateGroupIsDeleteByUserId">
        update `arpro_user_course_group_configuration` set is_delete =1 WHERE course_id=#{courseAndStudentInfoModel.courseId} AND class_id=#{courseAndStudentInfoModel.classId} AND
        info_id IN
        <foreach item="student" collection="studentList" open="(" separator="," close=")">
            #{student}
        </foreach>
    </update>

主函数:

    @Test
    public void test(){
        //获取数据库连接
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserCourseGroupConfigurationMapper userCourseGroupConfigurationMapper = sqlSession.getMapper(UserCourseGroupConfigurationMapper.class);

        //进行更新操作
        UserCourseGroupConfigurationPojo reviseParam = new UserCourseGroupConfigurationPojo();
        UserCourseGroupConfigurationPojo conditionParam = new UserCourseGroupConfigurationPojo();
        //假删除某个课的某个班的所有信息
        reviseParam.setIsDelete(1);
        conditionParam.setCourseId(BigInteger.valueOf(223667994));
        conditionParam.setClassId(BigInteger.valueOf(56496292));
        //进行调用
        userCourseGroupConfigurationMapper.updateCourseGroupConfiguration(reviseParam,conditionParam);

    }

四:总结

不要做没有思想的芦苇,不要写不能复用的代码。

五:升华

你的代码被复用的次数越多,你的价值就越大。

代码复用和维护性:
将常用的 SQL 查询或操作抽象为可复用的代码块,可以避免在多个地方重复编写相同的查询逻辑。这样一来,代码复用性大大提高,同时当需要修改查询逻辑时,只需要修改一个地方即可,而不必在多个地方修改,提高了代码的维护性。

减少重复性工作:
通过复用 SQL 代码,可以避免重复性工作,提高开发效率。尤其是在大型项目或者多个功能模块中,经常会遇到需要多次使用相同或类似的查询逻辑,复用 SQL 代码可以减少开发人员重复编写相同代码的工作量。

降低出错的概率:
复用的 SQL 代码通常经过充分测试和验证,可以减少出错的概率。一旦复用的 SQL 查询逻辑经过验证是正确的,后续的使用也不太可能出现错误。

提高代码的可读性:
将常用的 SQL 查询抽象为具有描述性的函数、视图或存储过程,使得代码更加清晰和易于理解。代码的可读性对于维护和团队合作至关重要。

灵活性:
可复用的 SQL 代码可以在不同的场景中灵活应用,通过参数化或配置化的方式,可以根据不同的需求调整查询逻辑。

总的来说,具有复用性的 SQL 可以减少重复性工作,提高代码的维护性和可读性,降低出错的概率,并且在开发中提供更高的灵活性和效率。因此,在项目开发中,对于经常使用的 SQL 查询或操作,推荐将其抽象为可复用的代码块。

写在最后:
性能优化: 复用的 SQL 代码可以经过优化和测试,以确保其在性能方面的表现良好。在复用 SQL 代码时,可以考虑使用索引、优化查询语句和减少数据库的访问次数,从而提高查询性能。

安全性考虑: 当编写具有复用性的 SQL 时,应该注意安全性方面的考虑。确保输入参数被正确验证和处理,以防止 SQL 注入等安全问题。

文档化: 对于复用的 SQL 代码,建议进行文档化,说明其功能、使用方法和参数。文档化能够帮助其他开发人员更好地理解和使用这些代码,降低学习成本。

版本控制: 如果复用的 SQL 代码是在团队项目中使用的,建议将其纳入版本控制系统,以便跟踪代码的变更和历史记录。

灵活参数传递: 在设计复用的 SQL 代码时,考虑支持灵活的参数传递方式。可以使用默认参数、可选参数、命名参数等方式来满足不同场景的需求。

不要过度复用: 尽管复用性是一个好处,但也不要过度复用 SQL 代码。过度复用可能会导致代码可读性降低,难以维护。对于仅在少数地方使用的简单查询,可以直接在代码中编写,而不必非要抽象为复用的代码块。

综上所述,具有复用性的 SQL 代码能够提高代码的效率、可维护性和可读性,但也需要关注性能、安全性和合理的使用范围。根据实际需求,灵活地使用复用性的 SQL 代码,可以使得开发过程更加高效和便捷。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Circ.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值