zoukankan      html  css  js  c++  java
  • MyBatis学习存档(4)——进行CRUD操作

    使用MyBatis进行数据库的CRUD操作有2种方式:一种如之前所说的接口+xml,而另一种是通过对接口上的方法加注解(@Select @Insert @Delete @Update)

    但是通常情况下不建议使用注解进行操作,原因在于MyBatis最强大的特性在于其动态sql,若使用注解则无法使用动态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.mapper.UsersMapper" >
      <resultMap id="BaseResultMap" type="com.pojo.Users" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="name" property="name" jdbcType="VARCHAR" />
        <result column="password" property="password" jdbcType="VARCHAR" />
      </resultMap>
      <sql id="Base_Column_List" >
        id, name, password
      </sql>
      <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select 
        <include refid="Base_Column_List" />
        from users
        where id = #{id,jdbcType=INTEGER}
      </select>
      <update id="updateByPrimaryKeySelective" parameterType="com.pojo.Users" >
        update users
        <set >
          <if test="name != null" >
            name = #{name,jdbcType=VARCHAR},
          </if>
          <if test="password != null" >
            password = #{password,jdbcType=VARCHAR},
          </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
      </update>
      <update id="updateByPrimaryKey" parameterType="com.pojo.Users" >
        update users
        set name = #{name,jdbcType=VARCHAR},
          password = #{password,jdbcType=VARCHAR}
        where id = #{id,jdbcType=INTEGER}
      </update>
    </mapper>
    UsersMapper.xml
    package com.mapper;
    
    import org.apache.ibatis.annotations.Select;
    
    import com.pojo.Users;
    
    public interface UsersMapper {
        @Select("select id, name, password from users where id = #{id}")
        Users selectByPrimaryKey(Integer id);
    
        int updateByPrimaryKeySelective(Users record);
    }
    UsersMapper.java

    依旧以之前反向生成的UsersMapper为例,为显得简洁些,仅保留了2个方法:selectByPrimaryKey和updateByPrimaryKeySelective

    打上注解的方法selectByPrimaryKey,其注解效果和xml中的一致,但updateByPrimaryKeySelective方法却无法打上注解,原因无它,该方法使用了动态sql,而注解中无法使用动态sql

    二、接口+xml

    为了之后好举例,此处重新创建了一个名为student的表,并反向生成了映射文件和实体类,并进行了些许改动

    2.1 创建student表并反向生成映射文件和实体类

    sql语句如下:

    CREATE TABLE student(id INT PRIMARY KEY identity(1,1), name VARCHAR(20), class VARCHAR(20));

    反向生成步骤不再多说

    2.2 更改映射文件和实体类

    反向生成后会发现实体类Student报错了,点开发现在class处报错——class是java的关键字

    所以我们应当将class改成clazz,这样就不会报错了

    仅仅更改实体类是不够的,还需将映射xml中对应的字段进行修改

    最后对接口及xml进行一定的更改,最终结果如下

    package com.mapper;
    
    import com.pojo.Student;
    
    public interface StudentMapper {
        //通过id删除学生
        int deleteById(Integer id);
        //添加学生
        int insertStudent(Student record);
        //通过id查找学生
        Student selectById(Integer id);
    }
    StudentMapper.java
    <?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.mapper.StudentMapper" >
      <resultMap id="BaseResultMap" type="com.pojo.Student" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="name" property="name" jdbcType="VARCHAR" />
        <result column="class" property="clazz" jdbcType="VARCHAR" />
      </resultMap>
      <sql id="Base_Column_List" >
        id, name, class
      </sql>
      <!-- 通过id查找学生 -->
      <select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select 
        <include refid="Base_Column_List" />
        from student
        where id = #{id,jdbcType=INTEGER}
      </select>
      <!-- 通过id删除学生 -->
      <delete id="deleteById" parameterType="java.lang.Integer" >
        delete from student
        where id = #{id,jdbcType=INTEGER}
      </delete>
      <!-- 添加学生 -->
      <insert id="insertStudent" parameterType="com.pojo.Student" >
        insert into student (name, class)
        values (#{name,jdbcType=VARCHAR}, #{clazz,jdbcType=VARCHAR})
      </insert>
    </mapper>
    StudentMapper.xml
    package com.pojo;
    
    public class Student {
        private Integer id;
    
        private String name;
    
        private String clazz;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    
        public String getClazz() {
            return clazz;
        }
    
        public void setClazz(String clazz) {
            this.clazz = clazz == null ? null : clazz.trim();
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + ", clazz=" + clazz + "]";
        }
    }
    Student.java

    2.3 对数据库进行CRUD操作

    1、首先添加一个学生,代码如下:

    package com.test;
    
    import java.io.InputStream;
    
    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 com.mapper.StudentMapper;
    import com.pojo.Student;
    
    public class TestInsert {
        
        public static void main(String[] args) throws Exception {
            //mybatis的核心配置文件
            String resource = "mybatis-config.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            InputStream  is = Resources.getResourceAsStream(resource);
            //构建SqlSession的工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            //开启SqlSession
            SqlSession session = factory.openSession();
            //通过映射接口执行操作
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            //new一个名叫张三 一年1班的学生
            Student stu = new Student();
            stu.setName("张三");
            stu.setClazz("一年1班");
            try {
                mapper.insertStudent(stu);
                //提交
                session.commit();
            } catch (Exception e){
                //回滚
                session.rollback();
                System.out.println("添加失败");
            } finally {
                session.close();
            }
            System.out.println("添加成功");
        }
    
    }

    结果:可以从日志中看到sql语句及传入的参数,最后输出“添加成功”

    在数据库里查看下添加的结果:确实多了一条数据

    为了之后方便操作,在此可以多添加几条数据:

    2、查询指定id的学生,代码如下:

    package com.test;
    
    import java.io.InputStream;
    
    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 com.mapper.StudentMapper;
    import com.pojo.Student;
    
    public class TestSelect {
        
        public static void main(String[] args) throws Exception {
            //mybatis的核心配置文件
            String resource = "mybatis-config.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            InputStream  is = Resources.getResourceAsStream(resource);
            //构建SqlSession的工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            //开启SqlSession
            SqlSession session = factory.openSession();
            //通过映射接口执行操作
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            Student student = mapper.selectById(1);
            System.out.println(student);
            session.close();
        }
    
    }

    结果如下:

    3、删除指定id的学生,代码如下:

    package com.test;
    
    import java.io.InputStream;
    
    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 com.mapper.StudentMapper;
    
    public class TestDelete {
        
        public static void main(String[] args) throws Exception {
            //mybatis的核心配置文件
            String resource = "mybatis-config.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            InputStream  is = Resources.getResourceAsStream(resource);
            //构建SqlSession的工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            //开启SqlSession
            SqlSession session = factory.openSession();
            //通过映射接口执行操作
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            try {
                mapper.deleteById(5);
                //提交
                session.commit();
            } catch (Exception e){
                //回滚
                session.rollback();
                System.out.println("删除失败");
            } finally {
                session.close();
            }
            System.out.println("删除成功");
        }
    
    }

    结果如下:

    现在再看数据库中的数据,发现id为5的学生已经不见了:

    4、更改指定id的学生姓名

    此时,StudentMapper里并没有update相关的方法,所以需要手动添加方法。现在接口中定义updateStudentById方法,然后在xml中编写相应的节点:使用update节点,id与方法名一致,传入参数类型为Student类,节点内为sql语句

    package com.mapper;
    
    import com.pojo.Student;
    
    public interface StudentMapper {
        //通过id删除学生
        int deleteById(Integer id);
        //添加学生
        int insertStudent(Student record);
        //通过id查找学生
        Student selectById(Integer id);
        //更改指定id学生的姓名
        int updateStudentById(Student student);
    }
    StudentMappe.java
    <?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.mapper.StudentMapper" >
      <resultMap id="BaseResultMap" type="com.pojo.Student" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="name" property="name" jdbcType="VARCHAR" />
        <result column="class" property="clazz" jdbcType="VARCHAR" />
      </resultMap>
      <sql id="Base_Column_List" >
        id, name, class
      </sql>
      <!-- 通过id查找学生 -->
      <select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select 
        <include refid="Base_Column_List" />
        from student
        where id = #{id,jdbcType=INTEGER}
      </select>
      <!-- 通过id删除学生 -->
      <delete id="deleteById" parameterType="java.lang.Integer" >
        delete from student
        where id = #{id,jdbcType=INTEGER}
      </delete>
      <!-- 添加学生 -->
      <insert id="insertStudent" parameterType="com.pojo.Student" >
        insert into student (name, class)
        values (#{name,jdbcType=VARCHAR}, #{clazz,jdbcType=VARCHAR})
      </insert>
      <!-- 更改指定id学生的姓名 -->
      <update id="updateStudentById" parameterType="com.pojo.Student">
        update student set name = #{name} where id = #{id}
      </update>
    </mapper>
    StudentMapper.xml

    编写测试类,先从数据库中查询获得需要修改的学生信息,再更改其姓名,最后提交

    package com.test;
    
    import java.io.InputStream;
    
    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 com.mapper.StudentMapper;
    import com.pojo.Student;
    
    public class TestUpdate {
        
        public static void main(String[] args) throws Exception {
            //mybatis的核心配置文件
            String resource = "mybatis-config.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            InputStream  is = Resources.getResourceAsStream(resource);
            //构建SqlSession的工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            //开启SqlSession
            SqlSession session = factory.openSession();
            //通过映射接口执行操作
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            Student student = mapper.selectById(4);
            System.out.println(student);
            student.setName("赵六");
            try{
                mapper.updateStudentById(student);
                //提交
                session.commit();
            } catch (Exception e){
                //回滚
                session.rollback();
                System.out.println("更改失败");
            }
            System.out.println("更改成功");
            session.close();
        }
    
    }

    结果和数据库如下:

      5、现更改需求:更改指定id学生所在的班级

    又多了一个update的需求,需要再新增一个方法吗?并不需要,只需在updateStudentById方法对应的映射sql中进行更改就可以了,这时就可以用到动态sql了

    <!-- 更改指定id学生的姓名 -->
      <update id="updateStudentById" parameterType="com.pojo.Student">
        update student
        <set>
          <if test="name != null">
              name = #{name} ,
          </if>
          <if test="clazz != null">
              class = #{clazz} ,
          </if>
        </set>
        where id = #{id}
      </update>

    将update节点改为上述,再编写测试类

    package com.test;
    
    import java.io.InputStream;
    
    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 com.mapper.StudentMapper;
    import com.pojo.Student;
    
    public class TestUpdate {
        
        public static void main(String[] args) throws Exception {
            //mybatis的核心配置文件
            String resource = "mybatis-config.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            InputStream  is = Resources.getResourceAsStream(resource);
            //构建SqlSession的工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            //开启SqlSession
            SqlSession session = factory.openSession();
            //通过映射接口执行操作
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            Student student = new Student();
            student.setId(4);
            student.setClazz("三年1班");
            System.out.println(student);
            try{
                mapper.updateStudentById(student);
                //提交
                session.commit();
            } catch (Exception e){
                //回滚
                session.rollback();
                System.out.println("更改失败");
            }
            System.out.println("更改成功");
            session.close();
        }
    
    }

    先new一个Student,再set它的id和class,此时name为null,执行update操作

    可以看见执行的sql为update student SET class = ? where id = ? 

    如果我们将name的值set为aaa,再看执行的sql语句:

    可以看见执行的sql为update student SET name = ? , class = ? where id = ? 

    这就是动态sql,除了if外,还有choose (when, otherwise),trim (where, set),foreach,这些节点的使用方式与JSTL标签的使用类似

    三、动态sql

    3.1 if

    最简单的节点,只需配置test属性即可,test内为布尔表达式,为true时if语句块中的sql语句才会存在,且不会对sql进行任何变动,因此有时会出现多逗号、and、or、where的情况,通常与对应的节点使用,如set、where等

    3.2 choose (when, otherwise)

    choose节点下有2个子节点when和otherwise,when节点中有1个属性test,和if的类似

    该节点的语法与if...else if...else类似

    <choose>
       <when test="表达式1">
          sql语句1
       </when>
       <when test="表达式2">
          sql语句2
       </when>
       <otherwise>
          sql语句3
       </otherwise>
    </choose>

    例如上述例子,当表达式1为true时,有且仅有sql语句1会被执行,不会有2和3;当表达式1、2都不满足时,就会执行sql语句3

    3.3 trim

    有4个属性:prefix、suffix、prefixOverrides、suffixOverrides。它可以更灵活地去除多余关键字,可以替代where和set

    以2.5中的sql语句为例,可变更如下,效果是一样的:

      <!-- 更改指定id学生的姓名 -->
      <update id="updateStudentById" parameterType="com.pojo.Student">
        update student
        <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">    
          <if test="name != null">name = #{name},</if>
          <if test="clazz != null">class = #{clazz},</if>
        </trim>
      </update>

    3.4 foreach

    用于迭代一个集合,通常用于in条件,其属性如下:

    item:集合名称(传入的变量名)

    index:指定迭代次数的名称

    collection:必须指定,表示传入的集合是什么类型的

    list

    array

    map-key

    open:语句的开始

    separator:每次循环的分割符

    close:语句的结束

  • 相关阅读:
    常用的正则表达式
    VScode格式化代码,开启ESlint代码检测方法,eslint代码配置
    git 常用的操作
    vscode 格式化的时候自动添加分号怎么去除
    echarts渐变色实现方法
    echart 柱状图 数值较小的时候,文字显示不全
    iview的Modal在提交表单时确认按钮loading状态冲突问题解决方案
    vue.js动态获取菜单
    12.18 webSocket消息推送
    12.18 微信模板消息推送
  • 原文地址:https://www.cnblogs.com/s1165482267/p/8038590.html
Copyright © 2011-2022 走看看