项目开发中。我们使用的是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是一个按权连接 &是一个转移符 等同于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 test="reviseParam.courseId != null">course_id = #{reviseParam.courseId}
<if test="reviseParam.classId != null">class_id = #{reviseParam.classId}
<if test="reviseParam.groupId != null">group_id = #{reviseParam.groupId}
<if test="reviseParam.type != null">type = #{reviseParam.type}
<if test="reviseParam.isDelete != null">is_delete = #{reviseParam.isDelete}
<if test="reviseParam.remark != null">remark = #{reviseParam.remark}
<if test="reviseParam.isMostLike != null">is_like = #{reviseParam.isLike}
</trim>
where is_delete = 0
<if test="conditionParam.infoId != null"> and info_id = #{conditionParam.infoId}
<if test="conditionParam.courseId != null">and course_id = #{conditionParam.courseId}
<if test="conditionParam.classId != null">and class_id = #{conditionParam.classId}
<if test="conditionParam.groupId != null">and group_id = #{conditionParam.groupId}
<if test="conditionParam.isMostLike != null">and is_like = #{conditionParam.isLike}
<if test="conditionParam.type != null">and type = #{conditionParam.type}
</update>
<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 代码,可以使得开发过程更加高效和便捷。