目录

  • 一、背景介绍
  • 二、MyBatis概念
  • 三、MyBatis好处
  • 四、思路&方案
  • 五、前期准备
  • 1、引入pom依赖
  • 2、在db.properties配置文件中添加连接数据库的语句
  • 3、MyBatis配置文件
  • 4、编写通用Update语句
  • 5、数据库连接文件
  • 4、MyBatis配置类
  • 六、代码编写
  • 1、Mapper编写
  • ①、接口
  • ②、通用mapper
  • ③、实体pojo
  • ④、junit测试编写
  • 2 、测试结果
  • ①、没执行代码之前的数据库表数据
  • ②、执行成功后,数据库中type=1的数据不见了
  • ③、然后使用course_id=315282991842590721修改后的数据进行查询
  • 七、总结


一、背景介绍

  在项目开发的过程中,我们编写sql语句的时候通常不会考虑到我要编写的sql语句之前是不是有人写过或者是不是可以复用别人的sql语句。而是直接我用了什么业务就直接写一个对应的sql语句。甚至有的时候我们自己写了之后都不清楚了。这样就没有使代码进行复用,也会带来代码带以维护的问题。

【项目实战典型案例】27.单表的11个Update接口--MyBatis_mysql


下边的例子中,给大家展示了如何编写可复用、可扩展、维护成本低的SQL语句。

二、MyBatis概念

  MyBatis是一种基于Java语言的持久层框架,它提供了将SQL语句与Java对象进行映射的功能,简化了数据库操作的开发。 MyBatis 的核心思想是将 SQL 语句与 Java 代码分离,使开发者可以专注于业务逻辑的开发而不用过多关注数据库操作。 MyBatis是一款轻量级框架,不依赖任何其他框架,可以与任何Java应用程序集成使用。

三、MyBatis好处

使用MyBatis框架的好处如下:

  1. 简化了数据库操作:MyBatis将SQL语句与Java对象进行映射,开发者可以仅仅通过Java代码就能够完成SQL语句的编写。
  2. 提高了系统的可维护性:MyBatis的SQL语句是统一管理的,开发者只需修改映射文件即可完成数据层代码的维护。
  3. 提升了系统的性能:MyBatis使用了SQL语句的预编译,从而能够大幅提高SQL语句的执行效率。
  4. 灵活性高:MyBatis允许开发者自定义SQL语句和映射关系,开发者可以根据实际需求进行灵活的配置。
  5. 支持事务处理:MyBatis支持事务处理,开发者可以根据需要进行事务的控制。
  6. 易于集成:MyBatis是基于Java语言开发的持久层框架,可以与任何Java应用程序进行集成。

四、思路&方案

  1. 编写通用的sql语句,使其满足百分之九十的sql语句
  2. 让代码的复用性更高。减少后期代码的维护成本

五、前期准备

代码环境:Java MyBatis maven项目,Mysql

1、引入pom依赖

需要引入mysql、mybatis、junit三个依赖即可。

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

2、在db.properties配置文件中添加连接数据库的语句

driver=com.mysql.jdbc.Driver
url=jdbc:mysql:服务器IP:3306/wzill?useSSL=false&;useUnicode=true;CharacterEncoding=UTF-8
username=数据库账号
password=数据库密码

3、MyBatis配置文件

实体类包的路径和接口mapper的路径需要改成自己的路径

【项目实战典型案例】27.单表的11个Update接口--MyBatis_mybatis_02

<?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>
      <!--<typeAlias type="com.wangsiqi.pojo.User" alias="User"/>-->
        <!--可以指定一个包名,MyBatis会在包名下面搜索需要的Java Bean-->
        <package name="com.wangsiqi.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="com.wangsiqi.dao.UserCourseGroupConfigurationMapper"/>
    </mappers>
</configuration>

4、编写通用Update语句

<update id="updateUser">
        update user
        <trim prefix="SET" suffixOverrides=",">
            <if test="userPojo.uid != null">uid = #{userPojo.uid}</if>
            <if test="userPojo.id != null">id = #{userPojo.id}</if>
            <if test="userPojo.name != null">name = #{userPojo.name}</if>
            <if test="userPojo.age != null">age = #{userPojo.age}</if>
            <if test="userPojo.username != null">username = #{userPojo.username}</if>
            <if test="userPojo.password != null">password = #{userPojo.password}</if>
            <if test="userPojo.email != null">email = #{userPojo.email}</if>
            <if test="userPojo.phone != null">phone = #{userPojo.phone}</if>
            <if test="userPojo.addr != null">addr = #{userPojo.addr}</if>
            <if test="userPojo.state != null">state = #{userPojo.state}</if>
        </trim>
        where state = 2
        <if test="conditionParam.addr != null"> and addr = #{conditionParam.addr}</if>
        <if test="conditionParam.phone != null">and phone = #{conditionParam.phone}</if>
        <if test="conditionParam.name != null">and name = #{conditionParam.name}</if>
        <if test="conditionParam.age != null">and age = #{conditionParam.age}</if>
        <if test="conditionParam.username != null">and username = #{conditionParam.username}</if>
        <if test="conditionParam.password != null">and password = #{conditionParam.password}</if>
    </update>

5、数据库连接文件

先进行数据库的连接

【项目实战典型案例】27.单表的11个Update接口--MyBatis_mysql_03


【项目实战典型案例】27.单表的11个Update接口--MyBatis_sql_04

4、MyBatis配置类

//sqlSessionFactory(获取资源) 必然是构建 sqlSession
//该工具类的作用时读取配置文件 获取sqlSessionFactory工厂
public class MybatisUtils {
    private  static  SqlSessionFactory sqlSessionFactory; //该代码的作用是提升作用域 可以让getSqlSession方法使用sqlSessionFactory
    static{ //静态代码块:一旦初始化就加载

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

    }
    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句

    public static SqlSession getSqlSession() { //该方法会返回一个SqlSession类
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//        return sqlSession;
        return sqlSessionFactory.openSession(true);//openSession中有自动commit(提交)事务的方法,加上true就能实现

    }

}

以上就是我们所需的基本环境啦,接下来就可以进行代码的编写啦~!

六、代码编写

1、Mapper编写

①、接口

public interface UserCourseGroupConfigurationMapper {
    void updateCourseGroupConfiguration(@Param("reviseParam")UserCourseGroupConfigurationPojo reviseParam, @Param("conditionParam")UserCourseGroupConfigurationPojo conditionParam);
}

②、通用mapper

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

③、实体pojo

@Data
public class UserCourseGroupConfigurationPojo {
    /**
     * 主键id
     */
    private BigInteger id;

    /**
     * 信息id是用户表的关联键
     */
    private BigInteger infoId;

    /**
     * 课程id
     */
    private BigInteger courseId;

    /**
     * 班级id
     */
    private BigInteger classId;

    /**
     * 分组id
     */
    private BigInteger groupId;

    /**
     * 我学的课还是我教的课
     */
    private Integer  type;

    /**
     * 是否删除 0 否 1是
     */
    private Integer isDelete;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 备注
     */
    private String remark;

    /**
     * 分组名称
     */
    private String groupName;

    /**
     * 分组顺序
     */
    private Integer sequence;

    /**
     * 是否是默认分组
     */
    private Integer isDefault;

    /**
     * 是否为我喜欢分组 0其他分组,1特别关注分组
     */
    private Integer isMostLike;

    public BigInteger getId() {
        return id;
    }

    public void setId(BigInteger id) {
        this.id = id;
    }

    public BigInteger getInfoId() {
        return infoId;
    }

    public void setInfoId(BigInteger infoId) {
        this.infoId = infoId;
    }

    public BigInteger getCourseId() {
        return courseId;
    }

    public void setCourseId(BigInteger courseId) {
        this.courseId = courseId;
    }

    public BigInteger getClassId() {
        return classId;
    }

    public void setClassId(BigInteger classId) {
        this.classId = classId;
    }

    public BigInteger getGroupId() {
        return groupId;
    }

    public void setGroupId(BigInteger groupId) {
        this.groupId = groupId;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }


    public Integer getIsDelete() {
        return isDelete;
    }

    public void setIsDelete(Integer isDelete) {
        this.isDelete = isDelete;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public Integer getSequence() {
        return sequence;
    }

    public void setSequence(Integer sequence) {
        this.sequence = sequence;
    }

    public Integer getIsDefault() {
        return isDefault;
    }

    public void setIsDefault(Integer isDefault) {
        this.isDefault = isDefault;
    }

    public Integer getIsMostLike() {
        return isMostLike;
    }

    public void setIsMostLike(Integer isMostLike) {
        this.isMostLike = isMostLike;
    }
}

④、junit测试编写

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

        //进行更新操作
        UserCourseGroupConfigurationPojo reviseParam = new UserCourseGroupConfigurationPojo();
        UserCourseGroupConfigurationPojo conditionParam = new UserCourseGroupConfigurationPojo();
        //假删除某个课的某个班的所有信息
        /*reviseParam.setIsDelete(0);
        conditionParam.setCourseId(BigInteger.valueOf(223667994));
        conditionParam.setClassId(BigInteger.valueOf(56496292));*/
        //reviseParam是修改后的数据
        reviseParam.setCourseId(new BigInteger("315282991842590721"));
        //conditionParam是修改条件
        conditionParam.setCourseId(new BigInteger("315282991842590720"));
        conditionParam.setType(1);
        //进行调用
        userCourseGroupConfigurationMapper.updateCourseGroupConfiguration(reviseParam,conditionParam);
    }
}

2 、测试结果

①、没执行代码之前的数据库表数据

【项目实战典型案例】27.单表的11个Update接口--MyBatis_SQL_05


【项目实战典型案例】27.单表的11个Update接口--MyBatis_java_06

②、执行成功后,数据库中type=1的数据不见了

【项目实战典型案例】27.单表的11个Update接口--MyBatis_mybatis_07

③、然后使用course_id=315282991842590721修改后的数据进行查询

【项目实战典型案例】27.单表的11个Update接口--MyBatis_mybatis_08

七、总结

  通过以上分析,更加认识到了面向对象的思想是多么的伟大。我们一直都说做软件设计要使用面向对象的思想:可复用、可扩展、可维护,可是真的做起来没有做到知行合一。