MyBatis学习(三)MyBatis基于动态代理方式的增删改查

1、前言

上一期讲到MyBatis-Statement版本的增删改查、可以发现、这种代码写下来冗余的地方特别多、写一套没啥、如果涉及到多表多查询的时候就容易出现问题。故、官方推荐了一种方法、即MyBatis基于动态代理方式的增删改查、它是一种基于接口开发、Mapper动态的对SQL进行寻找。通过具体概念请点击此处 查阅、这里不过多解释、代码中有详细的注释。


项目骨架如图所示:

2、前期准备

1、编写conf.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--  通过 environments 的 default值 和 environment 的 id 来指定mybatis运行时的数据库环境  -->
    <environments default="development">
        <!--    开发环境(本机)、environment可以有多套    -->
        <environment id="development">
            <!--  事务提交方式
                  JDBC:利用JDBC处理事务(commit rollback close)
                  MANAGED:将事务交给其他组件托管(Spring、jobss),默认情况下会关闭连接。
              -->
            <transactionManager type="JDBC"/>
            <!--   数据源类型
                   POOLED:使用数据库连接池
                   UNPOOLED:传统的JDBC模式(消耗性能、不推荐)
                   JNDI:从tomcat中获取内置数据库连接池
                     -->
            <dataSource type="POOLED">
                <!-- 配置数据库信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/xiao?serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--   加载映射文件     -->
        <mapper resource="com/feng/mapper/studentMapper.xml"/>
    </mappers>
</configuration>

2、创建实体类和对应的表(entity)

package com.feng.entity;

public class Student {
    private int stuNo;
    private String stuName;
    private int stuAge;
    private String graName;

    public int getStuNo() {
        return stuNo;
    }

    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public int getStuAge() {
        return stuAge;
    }

    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }

    public String getGraName() {
        return graName;
    }

    public void setGraName(String graName) {
        this.graName = graName;
    }

    public Student(int stuNo, String stuName, int stuAge, String graName) {
        this.stuNo = stuNo;
        this.stuName = stuName;
        this.stuAge = stuAge;
        this.graName = graName;
    }
    public Student() {
    }

    @Override
    public String toString() {
        return '{'+"stuNo=" + stuNo +
                ", stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                ", graName='" + graName + '\'' +
                '}';
    }
}

3、Mapper文件的编写

一个Mapper对应一个xml、动态代理方式中、mapper和对应的xml关系紧密、故两者放在同一文件夹下。

package com.feng.mapper;

import com.feng.entity.Student;

import java.util.List;

// 操作mybatis的接口
public interface StudentMapper {
    /*
    a. 约定
     1、方法名和mapper.xml文件中标签的id值相同
     2、方法的输入参数和mapper.xml文件中标签的parameterType类型一致
     3、方法的返回值和mapper.xml文件中标签的resultType类型一致
    b. 实现
      1、namespace的值就是接口的全类名 (实现接口和xml的映射)
      2、根据接口的方法名、找到mapper.xml中的SQL标签(方法名 = SQL标签Id值)
      习惯:SQL映射文件(mapper.xml) 和接口放在同一个包中、注意修改conf.xml加载mapper文件的路径
      以上、可以通过接口的方法定位 ---> SQL语句
     */
    Student queryStudentByStuNo(int stuNo);
    // 查询全部
    List<Student> queryAllStudents();
    // 增加
    void addStudent(Student student);
    // 删除
    void deleteStudentByStuNo(int stuNo);
    // 修改
    void updateStudentByStuNo(Student student);
}

<?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">
<!--namespace:该mapper.xml映射文件的唯一标识-->
<mapper namespace="com.feng.mapper.StudentMapper">
    <!--  通过 namespace.id来定位该sql  -->
    <!--  各种标签的id;
    parameterType:输入参数的类型;
    resultType:查询的返回结果的类型(具体对象映射到路径)
    -->
    <select id="queryStudentByStuNo" parameterType="int" resultType="com.feng.entity.Student">
        select * from student where stuno = #{stuNo}
    </select>

    <select id="queryAllStudents" resultType="com.feng.entity.Student">
        select * from student
    </select>

    <insert id="addStudent" parameterType="com.feng.entity.Student">
        insert into student(stuno,stuname,stuage,graname) values(#{stuNo},#{stuName},#{stuAge},#{graName})
    </insert>

    <update id="updateStudentByStuNo" parameterType="com.feng.entity.Student">
        update student set stuname=#{stuName},stuage=#{stuAge},graname=#{graName} where stuno=#{stuNo}
    </update>

    <delete id="deleteStudentByStuNo" parameterType="int">
        delete from student where stuno = #{stuNo}
    </delete>
</mapper>

4、编写测试类进行测试

(注:Mybatis约定了一个输入参数对应一个输出参数、且不能出现多个、故改动代码逻辑、采用对象的方式对返回值进行约定。)

package com.feng.test;

import com.feng.entity.Student;
import com.feng.mapper.StudentMapper;
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.Reader;
import java.util.List;

public class Test {
    // 1、查询单个学生
    public static void queryStudentByStuNo() throws IOException {
        // conf.xml ---->  reader
        Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
        // reader ---> SqlSession
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sessionFactory.openSession();

        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        Student student = studentMapper.queryStudentByStuNo(1);// 接口中的方法->SQL语句
        System.out.println(student);
        session.close();
    }
    // 2、查询全部学生
    public static void queryAllStudents() throws IOException {
        Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

        SqlSession session = sessionFactory.openSession();

        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.queryAllStudents();
        System.out.println(students);
        session.close();
    }

    // 3、增加学生
    public static void addStudent() throws IOException {
        Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

        SqlSession session = sessionFactory.openSession();

        Student student = new Student(3, "柴犬", 25, "六年级");
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        studentMapper.addStudent(student);
        session.commit();   // 提交事务

        System.out.println("增加成功!");
        session.close();
    }

    // 4、修改学生
    public static void updateStudentByStuNo() throws IOException {
        Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

        SqlSession session = sessionFactory.openSession();
        Student student = new Student();
        // 修改那个人, where stuNo = 2
        student.setStuNo(2);
        // 修改成啥样子
        student.setStuName("三哈");
        student.setStuAge(25);
        student.setGraName("一年级");

        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        studentMapper.updateStudentByStuNo(student);
        session.commit();   // 提交事务
        System.out.println("修改成功!");
        session.close();
    }

    // 5、删除学生
    public static void deleteStudentByStuNo() throws IOException {
        Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

        SqlSession session = sessionFactory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        studentMapper.deleteStudentByStuNo(3);
        session.commit();   // 提交事务
        System.out.println("删除成功");
        session.close();
    }
    public static void main(String[] args) throws IOException {
        deleteStudentByStuNo();
        queryAllStudents();
    }
}

5、测试结果

posted @ 2021-02-18 10:13  Frank_7  阅读(111)  评论(0编辑  收藏  举报