Mybatis传统方式实现Dao层与接口代理方式实现dao

1.传统方式实现dao层

1.Dao 层传统实现方式

分层思想:控制层(controller)、业务层(service)、持久层(dao)。

调用流程:控制层→业务层→持久层→DB

2.环境准备

在mybatis项目中持久层就不再叫dao,而是叫做mapper(只是换了名字)

mapper层:

package Mybatis2.mapper.impl;

import mybatis1.bean.Student;

import java.util.List;

/*
    持久层接口
 */
public interface StudentMapper {
    //查询全部
    public abstract List<Student> selectAll();

    //根据id查询
    public abstract Student selectById(Integer id);

    //新增数据
    public abstract Integer insert(Student stu);

    //修改数据
    public abstract Integer update(Student stu);

    //删除数据
    public abstract Integer delete(Integer id);
}

package Mybatis2.mapper.impl;

import mybatis1.bean.Student;

import java.util.List;

/*
    持久层实现类
 */
public class StudentMapperImpl implements StudentMapper {

    /*
        查询全部
     */
    @Override
    public List<Student> selectAll() {
        return null;
    }

    /*
        根据id查询
     */
    @Override
    public Student selectById(Integer id) {
        return null;
    }

    /*
        新增功能
     */
    @Override
    public Integer insert(Student stu) {
        return null;
    }

    /*
        修改功能
     */
    @Override
    public Integer update(Student stu) {
        return null;
    }

    /*
        删除功能
     */
    @Override
    public Integer delete(Integer id) {
        return null;
    }
}

service层:

package Mybatis2.service;

import mybatis1.bean.Student;

import java.util.List;

/*
    业务层接口
 */
public interface StudentService {
    //查询全部
    public abstract List<Student> selectAll();

    //根据id查询
    public abstract Student selectById(Integer id);

    //新增数据
    public abstract Integer insert(Student stu);

    //修改数据
    public abstract Integer update(Student stu);

    //删除数据
    public abstract Integer delete(Integer id);
}

package Mybatis2.service;

import Mybatis2.mapper.impl.StudentMapper;
import Mybatis2.mapper.impl.StudentMapperImpl;
import mybatis1.bean.Student;

import java.util.List;

/*
    业务层实现类
 */
public class StudentServiceImpl implements StudentService {

    //创建持久层对象
    private StudentMapper mapper = new StudentMapperImpl();

    @Override
    public List<Student> selectAll() {
        return mapper.selectAll();
    }

    @Override
    public Student selectById(Integer id) {
        return mapper.selectById(id);
    }

    @Override
    public Integer insert(Student stu) {
        return mapper.insert(stu);
    }

    @Override
    public Integer update(Student stu) {
        return mapper.update(stu);
    }

    @Override
    public Integer delete(Integer id) {
        return mapper.delete(id);
    }
}

 controller层:

package Mybatis2.controller;

import Mybatis2.service.StudentService;
import Mybatis2.service.StudentServiceImpl;
import mybatis1.bean.Student;
import org.junit.Test;

import java.util.List;

/*
    控制层测试类
 */
public class StudentController {
    //创建业务层对象
    private StudentService service = new StudentServiceImpl();

    //查询全部功能测试
    @Test
    public void selectAll() {
        List<Student> students = service.selectAll();
        for (Student stu : students) {
            System.out.println(stu);
        }
    }

    //根据id查询功能测试
    @Test
    public void selectById() {
        Student stu = service.selectById(3);
        System.out.println(stu);
    }

    //新增功能测试
    @Test
    public void insert() {
        Student stu = new Student(4,"赵六",26);
        Integer result = service.insert(stu);
        System.out.println(result);
    }

    //修改功能测试
    @Test
    public void update() {
        Student stu = new Student(4,"赵六",16);
        Integer result = service.update(stu);
        System.out.println(result);
    }

    //删除功能测试
    @Test
    public void delete() {
        Integer result = service.delete(4);
        System.out.println(result);
    }
}

3.mapper层功能实现

package Mybatis2.mapper.impl;

import mybatis1.bean.Student;
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;
import java.util.List;

/*
    持久层实现类
 */
public class StudentMapperImpl implements StudentMapper {

    /*
        查询全部
     */
    @Override
    public List<Student> selectAll() {
        List<Student> list = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.执行映射配置文件中的sql语句,并接收结果
            list = sqlSession.selectList("StudentMapper.selectAll");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //6.返回结果
        return list;
    }

    /*
        根据id查询
     */
    @Override
    public Student selectById(Integer id) {
        Student stu = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.执行映射配置文件中的sql语句,并接收结果
            stu = sqlSession.selectOne("StudentMapper.selectById",id);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //6.返回结果
        return stu;
    }

    /*
        新增功能
     */
    @Override
    public Integer insert(Student stu) {
        Integer result = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.执行映射配置文件中的sql语句,并接收结果
            result = sqlSession.insert("StudentMapper.insert",stu);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //6.返回结果
        return result;
    }

    /*
        修改功能
     */
    @Override
    public Integer update(Student stu) {
        Integer result = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.执行映射配置文件中的sql语句,并接收结果
            result = sqlSession.update("StudentMapper.update",stu);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //6.返回结果
        return result;
    }

    /*
        删除功能
     */
    @Override
    public Integer delete(Integer id) {
        Integer result = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.执行映射配置文件中的sql语句,并接收结果
            result = sqlSession.delete("StudentMapper.delete",id);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //6.返回结果
        return result;
    }
}

4.LOG4J的使用

在日常开发过程中,排查问题时难免需要输出 MyBatis 真正执行的 SQL 语句、参数、结果等信息,我们就可以借助 LOG4J 的功能来实现执行信息的输出

使用步骤

1.导入 jar 包:log4j-1.2.17.jar

2.修改核心配置文件:MyBatisConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心根标签-->
<configuration>
    <!--引入数据库连接的配置文件-->
    <properties resource="jdbc.properties"/>
    <!--配置LOG4J:以下name和value是固定写法-->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>

    <!--起别名-->
    <typeAliases>
        <typeAlias type="mybatis1.bean.Student" alias="student"/>
        <!--<package name="mybatis.bean"/>
      如果bean包下有很多Javabean都需要起别名,就可以使用package,指定一个包名
      这样的话,就自动给这个包下所有的类添加别名,别名是类名的小写名字
      -->
</typeAliases>

        <!--每一个environment标签都是一个具体的连接数据库的环境 ,default:设置默认使用的环境的id-->
    <environments default="mysql">
        <!--environment配置数据库环境  id属性唯一标识-->
        <environment id="mysql">
            <!-- transactionManager事务管理。  type属性,采用JDBC默认的事务-->
            <transactionManager type="JDBC"/>
            <!-- 设置数据源的类型,以下表示使用数据库连接池缓存数据库连接-->
            <dataSource type="POOLED">
                <!-- property获取数据库连接的配置信息 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--mappers引入映射配置文件-->
    <mappers>
        <!-- mapper 引入指定的映射配置文件   resource属性指定映射配置文件的名称 -->
        <mapper resource="StudentMapper.xml"/>
    </mappers>
</configuration>

3.在 src 下编写 LOG4J 配置文件 : log4j.properties (配置文件名字也是固定写法)

# Global logging configuration
# ERROR WARN INFO DEBUG
# 日志的四个级别,从高到低:ERROR(错误信息) WARN(警告信息) INFO(普通信息) DEBUG(调试信息,推荐使用)
# stdout:输出到控制台
log4j.rootLogger=DEBUG, stdout
# Console output...  输出格式
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2.接口代理方式实现dao

传统方式实现Dao层,既要写接口,还要写实现类而Mybatis框架可以帮助我们省略编写Dao层接口实现类的步骤程序员只需要编写接口,由Mybatis框架根据接口的定义来创建该接口的动态代理对象

1.接口代理方式实现规则

1.映射配置文件中的名称空间必须和Dao层接口的全类名相同(Mapper.xml文件中的namespace与mapper接口的全限定名相同)

2.映射配置文件中的增删改查标签的id属性必须和Dao层接口的方法名相同

3.映射配置文件中的增删改查标签的parameterType属性必须和Dao层接口方法的参数相同

4.映射配置文件中的增删改查标签的result Type属性必须和Dao层接口方法的返回值相同

2.代码实现

1.删除 mapper 层接口的实现类

2.修改映射配置文件

3.修改 service 层接口的实现类,采用接口代理方式实现功能(因为现在没有持久层实现类了,所

以业务层无法直接调用,需要自己实现并且调用代理接口方式的MapperImpl)

修改映射配置文件:

<!-- 将命名空间修改为StudentMapper全路径名-->

<mapper namespace="Mybatis2.mapper.StudentMapper">

修改service层接口的实现类:

package Mybatis2.service;

import Mybatis2.mapper.StudentMapper;
import mybatis1.bean.Student;
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;
import java.util.List;

/*
    业务层实现类
 */
public class StudentServiceImpl implements StudentService {

    @Override
    public List<Student> selectAll() {
        List<Student> list = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            list = mapper.selectAll();

        } catch (Exception e) {

        } finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return list;
    }

    @Override
    public Student selectById(Integer id) {
        Student stu = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            stu = mapper.selectById(id);

        } catch (Exception e) {

        } finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return stu;
    }

    @Override
    public Integer insert(Student stu) {
        Integer result = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            result = mapper.insert(stu);

        } catch (Exception e) {

        } finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return result;
    }

    @Override
    public Integer update(Student stu) {
        Integer result = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            result = mapper.update(stu);

        } catch (Exception e) {

        } finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return result;
    }

    @Override
    public Integer delete(Integer id) {
        Integer result = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            result = mapper.delete(id);

        } catch (Exception e) {

        } finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return result;
    }
}

3.源码分析

分析动态代理对象如何生成的

通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper() 方法最终获取

到 org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,

而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,帮助我们生成了代理实现类对象。从

而可以进行相关持久化操作。

分析方法是如何执行的

跟踪mapper.insert方法,代码打断点,然后调试跟踪

代码执行到insert之后,进入方法的执行,然后就进入到了invoke方法(动态代理执行方法,都会执行invoke)

在invoke中调用了mapperMethod.execute()方法

这个方法中通过 switch 语句根据操作类型来判断是新增、修改、删除、查询操作,

最后一步回到了 MyBatis 最原生的 SqlSession 方式来执行增删改查

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用Mybatis-Plus进行通用DAO封装的示例代码: 1. 首先,我们需要引入Mybatis-Plus依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> ``` 2. 接着,我们需要定义一个基础的Mapper接口,用于封装通用的增删改查操作: ```java import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface MyBaseMapper<T> extends BaseMapper<T> { } ``` 3. 然后,我们需要定义一个基础的Service接口,用于封装通用的增删改查操作: ```java import com.baomidou.mybatisplus.extension.service.IService; public interface MyBaseService<T> extends IService<T> { } ``` 4. 最后,我们需要定义一个基础的ServiceImpl实现,用于实现通用的增删改查操作: ```java import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; public abstract class MyBaseServiceImpl<M extends MyBaseMapper<T>, T> extends ServiceImpl<M, T> implements MyBaseService<T> { } ``` 通过以上代码实现,我们可以很方便地使用Mybatis-Plus进行通用DAO封装。接下来,我们只需要定义具体的Mapper和Service接口,继承以上基础接口即可,如: ```java public interface UserMapper extends MyBaseMapper<User> { } public interface UserService extends MyBaseService<User> { } public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, User> implements UserService { } ``` 这样,我们就可以通过UserService接口,调用Mybatis-Plus提供的通用方法,实现对User表的增删改查操作了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值