单表的更新接口有9个之多
一:背景介绍
本篇博客是对项目开发中出现的单表的更新接口有9个之多的问题进行的总结并进行的改进。目的是将经历转变为自己的经验。通过博客的方式分享给大家,大家一起共同进步和提高。
在项目开发过程中,出现了对单表的更新接口出现了9个之多,虽然这些接口能够满足功能需要,但是没有丝毫的复用思想,以及后续对于接口的维护的工作量又很大。所以不是一个很好的设计。
那么我们如何对这个问题进行优化和解决,我们可以通过一个接口来替换调绝大多数的接口,通过使用mybatis的动态SQL实现。
下面是实现的例子。
环境准备
准备一个java 的maven项目并集成mybatis使用mysql数据库
引入pom依赖
由于我将mapper的xml文件写在了java的目录中,所以配置了maven的构建
<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> <!-- 项目打包时会将java目录中的*.xml文件也进行打包 --> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
配置数据库连接
这里注意将自己数据库机器的ip地址和对应的库名写对,不然无法连接自己的数据库。
mybatis配置文件
需要注意的是配置里面的实体路径的设置,和绑定的接口路径,如果路径不一致会报错。
<?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="dao.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="dao.UserCourseGroupConfigurationMapper"/> </mappers> </configuration>
Mybatis的配置类
package utils; 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 java.io.IOException; import java.io.InputStream; 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); } }
编写通用的更新语句
通过编写通用的SQL语句,可以覆盖上文提到的八个更新语句。
<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.isMostLike}</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>
可以覆盖的更新接口
<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.setGroupId(new BigInteger("369279349968338943")); conditionParam.setGroupId(new BigInteger("369279349968338944")); conditionParam.setType(0); //更新分组id userCourseGroupConfigurationMapper.updateCourseGroupConfiguration(reviseParam,conditionParam); }
通过编写通用的更新接口,可以进8个更新接口进行覆盖,相当于其他八个更新接口不用写了,用这一个通用更新接口就ok了。通过编写通用接口的方式,能够减少相当大的重复用编码的量。不仅利于后期谓语,也提高了编码效率。
四:总结
在进行开发之前一定需要做好设计工作,编写代码时考虑如何进行高复用,低维护,高扩充。以此来提高开发效率和降低维护成本。
五:升华
1.不怕不知道就怕不知道,怕就怕在根本不知道可以通过使用mybatis动态SQL的方式来让代码的可复用更强。
2. 具有复用思想,能够产生量变。