MyBatis框架Dao代理

一、Dao开发

首先创建Dao接口

package com.md.dao;
import com.md.domain.Student;
import java.util.List;

/**
 * @author MD
 * @create 2020-08-05 14:18
 */
public interface StudentDao {
    List<Student> selectStudents();
    int insertStudent(Student student);
}

然后创建Dao接口的实现类

public class StudentDaoImpl implements StudentDao

1. 实现接口中的select方法

先在StudentDao.xml中写对应的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.md.dao.StudentDao">

    <select id="selectStudents" resultType="com.md.domain.Student">
      select id,name,eamil,age from student
    </select>


    <insert id="insertStudent">
        insert into student values(#{id},#{name},#{email},#{age})
    </insert>

</mapper>

然后在实现类中写具体的方法

public List<Student> selectStudents() {
    // 工具类
	SqlSession session = MyBatisUtil.getSqlSession();
	List<Student> studentList = session.selectList("com.md.dao.StudentDao.selectStudents");
	session.close();
	return studentList;
}

在测试类中写

@Test
    public void testSelectStudent(){
        StudentDao dao = new StudentDaoImpl();

        List<Student> studentList = dao.selectStudents();
        studentList.forEach(stu -> System.out.println(stu));
    }

需要注意:

  1. dao对象,类型是StudentDao,而这个接口的全限定名称是:com.md.dao.StudentDao正好和类型是StudentDao.xml中的namespace是一样的
  2. 方法名称,selectStudents,这个方法的名称正是mapper文件中的id值 selectStudents
  3. 通过dao中方法的返回值也是可以确定MyBatis要调用的SqlSession的方法
    • 如果返回的是list,那就说明调用的是selectList()方法
    • 如果返回的是int、或是其他,看mapper文件中的标签 <insert>,<update>
    • 就会调用SqlSession的insert、update方法
  4. mybatis的动态代理,mybatis根据dao的方法调用,获取执行sql语句信息,mybatis根据你的dao接口,创建一个到接口的实现类,并创建这个类的对象,完成SqlSession调用方法,访问数据库

2. 实现接口中insert方法

 @Override
    public int insertStudent(Student student) {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        int nums = sqlSession.insert("com.md.dao.StudentDao.insertStudent",student);

        // 注意提交事务
        sqlSession.commit();

        sqlSession.close();
        return nums;
    }

测试类

 int i = dao.insertStudent(new Student(1005,"李白","li@qq.com",30));
        System.out.println("成功插入:"+i+" 条数据");

3. 实现接口中 update 方法

public int updateStudent(Student student) {
	SqlSession session = MyBatisUtil.getSqlSession();
	int nums = session.insert(
	"com.md.dao.StudentDao.updateStudent",student);
	session.commit();
	session.close();
	return nums;
}

测试:

public void testUpdate() throws IOException {
	Student student = new Student();
	student.setId(1006);
	student.setAge(28);
	int nums = studentDao.updateStudent(student);
	System.out.println(" 使用 Dao 修改数据:"+nums);
}

4. 实现接口中 delete 方法

public int deleteStudent(int id) {
	SqlSession session = MyBatisUtil.getSqlSession();
	int nums = session.insert(
		"com.md.dao.StudentDao.deleteStudent",1006);
	session.commit();
	session.close();
	return nums;
}

测试:

@Test
public void testDelete() throws IOException {
	int nums = studentDao.deleteStudent(1006);
	System.out.println(" 使用 Dao 修改数据:"+nums);
}

二、Dao开发分析

在前面例子中自定义 Dao 接口实现类时发现一个问题:

Dao 的实现类其实并没有干什么实质性的工作,而且代码还是千篇一律,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的

所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式

Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代
理实现的

三、Dao代理实现CURD

首先就是删除Dao接口的实现类

1. 使用getMapper获取代理对象

只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao接口类的 class 值

还是直接使用工具类获取获取SqlSession

 /**
         * 使用mybatis的动态代理机制, 使用SqlSession.getMapper(dao接口.class)
         * getMapper能获取dao接口对于的实现类对象。
         */

        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

这样的话就无需再写实现类了,使用dao接口.class就行

上面使用传统Dao的方式就可以修改成这样

select

  @Test
    public void testSelectStudent(){

        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        // 调用dao方法,执行数据库操作
        List<Student> studentList = dao.selectStudents();
        studentList.forEach(stu -> System.out.println(stu));
    }

insert

@Test
    public void testInsertStudent(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        int i = dao.insertStudent(new Student(1006,"王昭君","wzj@qq.com",30));

        // 注意提交事务
        sqlSession.commit();
        System.out.println("成功插入:"+i+" 条数据");
    }

这样就更加的方便了

四、总结

1. 什么是动态代理?

mybatis帮你创建dao接口的实现类,在实现类中调用SqlSession的方法执行sql语句

2. 使用动态代理的方式

  1. 获取SqlSession对象,SqlSessionFactory.openSession(),只不过我们可以直接使用工具类
  2. 使用getMapper方法获取某个接口的对象,sqlSession.getMapper(接口.class);
  3. 调用接口的方法,调用那个方法就执行了mapper文件中的那个sql语句

3. 使用动态代理的要求

  1. dao接口和mapper文件放在一个目录中
  2. dao接口和mapper文件名称一致
  3. mapper文件中的namespace的值是dao接口的全限定名称
  4. mapper文件中的<select>、<insert>、<update>、<delete>等的id值是接口中的方法名
  5. dao接口中不要使用重载的方法,不要使用同名的,不同参数的方法

具体的如下:

目录结构

dao接口:

package com.md.dao;

public interface StudentDao {
    List<Student> selectStudents();
    int insertStudent(Student student)

}

mapper文件

<?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.md.dao.StudentDao">

    <select id="selectStudents" resultType="com.md.domain.Student">
      select id,#{age})
    </insert>

</mapper>

这样就ok了

相关文章

1.pom.xml引入依赖 &lt;dependency&gt; &lt;gro...
&lt;?xml version=&quot;1.0&quot; encoding=&a...
准备工作 ① 创建数据库&amp;数据表 ## 创建数据库 CREA...
MyBatis逆向工程是指根据数据库表结构自动生成对应的实体类、...
MyBatis获取参数值的两种方式:${}和#{} ${}的本质就是字符串...
resultMap作用是处理数据表中字段与java实体类中属性的映射关...