【SSM】MyBatis(六.MyBatis接口代理)

1. 借助javassist编写GenerateDaoProxy类

package com.sndu.bank.utils;

import org.apache.ibatis.javassist.CannotCompileException;
import org.apache.ibatis.javassist.ClassPool;
import org.apache.ibatis.javassist.CtClass;
import org.apache.ibatis.javassist.CtMethod;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 工具类 生成Dao实现类(动态生成Dao代理类)
 */
public class GenerateDaoProxy {
    public static Object generate(SqlSession sqlSession, Class daoInterface){
        //类池
        ClassPool pool = ClassPool.getDefault();
        //制造类
        final CtClass ctClass = pool.makeClass(daoInterface.getName() + "Proxy");//实际本质就是在内存中动态生成一个代理类
        //制造接口
        CtClass ctInterface = pool.makeInterface(daoInterface.getName());
        //实现接口
        ctClass.addInterface(ctInterface);
        //实现接口中所有方法
        Method[] methods = daoInterface.getDeclaredMethods();
        Arrays.stream(methods).forEach(method -> {
            //method是抽象方法
            //将method这个抽象方法实现
            try {
                StringBuilder methodCode = new StringBuilder();
                methodCode.append("public ");
                methodCode.append(method.getReturnType().getName());
                methodCode.append(" ");
                methodCode.append(method.getName());
                methodCode.append("(");
                Class<?>[] parameterTypes = method.getParameterTypes();
                for(int i = 0; i < parameterTypes.length; i++){
                    Class<?> parameterType = parameterTypes[i];
                    methodCode.append(parameterType.getName());
                    methodCode.append(" ");
                    methodCode.append("arg" + i);
                    if(i != parameterTypes.length - 1){
                        methodCode.append(",");
                    }
                }
                methodCode.append(")");
                methodCode.append("{");
                methodCode.append("org.apache.ibatis.session.SqlSession sqlSession = com.sndu.bank.utils.SqlSessionUtil.openSession();");
                //需要知道是什么类型的sql
                //namespace必须是dao接口中的全限定名称,id必须是dao中的接口名
                String sqlId = daoInterface.getName() + "." + method.getName();
                SqlCommandType sqlCommandType = sqlSession.getConfiguration().getMappedStatement(sqlId).getSqlCommandType();
                if(sqlCommandType == SqlCommandType.INSERT){

                }
                if(sqlCommandType == SqlCommandType.DELETE){

                }
                if(sqlCommandType == SqlCommandType.UPDATE){
                    methodCode.append("return sqlSession.update(\""+sqlId+"\", arg0);");
                }
                if(sqlCommandType == SqlCommandType.SELECT){
                    String returnType = method.getReturnType().getName();
                    methodCode.append("return ("+returnType+")sqlSession.selectOne(\""+sqlId+"\", arg0);");
                }

                methodCode.append("}");
                CtMethod ctMethod = CtMethod.make(methodCode.toString(), ctClass);
                ctClass.addMethod(ctMethod);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        //创建对象
        Object obj = null;
        try {
            Class<?> clazz = ctClass.toClass();
            obj = clazz.newInstance();
        } catch (CannotCompileException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return obj;
    }
}

在这里插入图片描述
后续我们只需要写接口即可,不用写实现类。

2.使用MyBatis内置的代理功能

MyBatis内置了代理模式。在内存中生成Dao接口的代理类,然后生成代理类的实例。MyBatis能使用这种代理功能的前提是XxxxxMapper.xml中的namespace使用全限定名称,id使用类名。

代码:

private AccountDao accountDao = SqlSessionUtil.openSession().getMapper(AccountDao.class);

3.面向接口编写CRUD

在这里插入图片描述

CarMapper

package com.sdnu.mybatis.mapper;

import com.sdnu.mybatis.pojo.Car;

import java.util.List;

public interface CarMapper {
    /**
     * 增
     * @param car 汽车
     * @return
     */
    int insert (Car car);

    /**
     * 根据Id删除Car
     * @return
     */
    int deleteById(Long id);

    /**
     * 更新
     * @param car
     * @return
     */
    int update(Car car);

    /**
     * 根据id查询汽车信息
     * @param id
     * @return
     */
    Car selectById(Long id);

    /**
     * 查询所有汽车信息
     * @return
     */
    List<Car> selectAll();
}

CarMapperTest

package com.sdnu.mybatis.test;

import com.sdnu.mybatis.mapper.CarMapper;
import com.sdnu.mybatis.pojo.Car;
import com.sdnu.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void testInsert(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = new Car(null, "8888", "劳斯莱斯", 188.0, "2023-03-27", "燃油车");
        int count = mapper.insert(car);
        System.out.println(count);
        sqlSession.commit();
    };
    @Test
    public void testDeleteById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        int count = mapper.deleteById(30L);
        System.out.println(count);
        sqlSession.commit();
    };
    @Test
    public void testUpdate(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = new Car(29L, "989999998", "奔驰C", 9898.0, "2023-03-27", "燃油车");
        int count = mapper.update(car);
        System.out.println(count);
        sqlSession.commit();
    }
    @Test
    public void testSelectById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = mapper.selectById(28L);
        System.out.println(car);
    }
    @Test
    public void testSelectAll(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> list = mapper.selectAll();
        for(Car obj : list){
            System.out.println(obj);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值