mybatis--javassist 11.26

有没有自动生成接口的实现类的方式???先自己实现

(如下自动生成AccountDao实现类的方式)

 

 1.AcountDao

package com.jiang.dao.impl;

public interface AccountDao {
     void delete();
     int update(String actno,Double balance);
     int insert(String actno);
     String selectByActno(String actno);
}

 2.TestGenerate

  1.  获取类池
  2. 制造类
  3. 制造方法
  4. 添加方法至类中
  5. 内存中生成类
  6. 类加载到JVM 返回类的字节码
  7. 创建对象
  8. 获取方法
  9. 使用方法 
    @org.junit.Test
    public void  testGenerate() throws CannotCompileException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //获取类池
        ClassPool classPool=ClassPool.getDefault();
        //制造类 类名
        CtClass ctClass = classPool.makeClass("com.jiang.dao.impl.AccountDapImpl");

        //制造方法
        String src="   public void insert(){\n" +
                "        System.out.println(\"hello javassist\");\n" +
                "    }";
        CtMethod ctMethod = CtMethod.make(src, ctClass);
        //添加方法
        ctClass.addMethod(ctMethod);
        //在内存中生成类
        ctClass.toClass();

        //类加载到JVM当中 返回类的字节码
        Class<?> aClass = Class.forName("com.jiang.dao.impl.AccountDapImpl");
        //创建对象
        Object o = aClass.newInstance();
        //获取其方法
        Method insert = aClass.getDeclaredMethod("insert");
        //调用方法insert
        insert.invoke(o);
    }

实现接口

知道有哪些方法存在

    @org.junit.Test
    //实现接口
    //知道有哪些方法名存在
    public void Testinterface() throws CannotCompileException, IllegalAccessException, InstantiationException {
        //获取类池
        ClassPool classPool = ClassPool.getDefault();
        //创建类
        CtClass ctClass = classPool.makeClass("com.jiang.dao.impl.AccountDaopImpl");
        //创接口
        CtClass anInterface = classPool.makeInterface("com.jiang.dao.impl.AccountDao");
        //将接口添加到类中
        ctClass.addInterface(anInterface);
        //实现方法:
        //创造方法:

        String src="   public void delete(){\n" +
                "        System.out.println(\" delete-ing\");\n" +
                "    }";
        CtMethod ctMethod = CtMethod.make(src, ctClass);
        //将方法添加到类中
        ctClass.addMethod(ctMethod);

        //内存中生成类,同时将生成的类加载到JVM中
        Class<?> aClass = ctClass.toClass();
        AccountDao accountDa = (AccountDao) aClass.newInstance();
        accountDa.delete();
    }

 实现接口,不知道有哪些方法

实现方法模样如下


    public void delete() {
        
    }

    public int update(String actno, Double balance) {
        return 0;
    }

 
    public int insert(String actno) {
        return 0;
    }

  
    public String selectByActno(String actno) {
        return null;
    }

动态拼接StringBuilder:

  • append  public
  • void/int/String   method.getReturnType().getName()
  • delete/update/insert/...  方法名    method.getName() java.lang.String  getSimplename string
  • ()
  • ()里面的参数 ()、(String actno,Double balance)....

两个参数方法:

method.getParameterCount()   参数个数
parameterType.getName()  参数类型
  • 加逗号  
    if (i!=parameterTypes.length-1){
        methodCode.append(",");
    }

  • return语句
     String simpleName = method.getReturnType().getSimpleName();
                    if ("void".equals(simpleName)) {
    
                    }else if ("int".equals(simpleName)) {
                        methodCode.append("return 1;");
                    }else  if ("String".equals(simpleName)) {
                        methodCode.append("return \"hello\";");
                    }
                    methodCode.append("}");

    @org.junit.Test
    //动态实现接口方法(不知道方法名等)
    public void TestInterface() throws CannotCompileException, IllegalAccessException, InstantiationException {
        //获取类池
        ClassPool pool = ClassPool.getDefault();
        //创建类
        CtClass ctClass = pool.makeClass("com.jiang.dao.impl.AccountDaoImpl");
        //创建接口
        CtClass anInterface = pool.makeInterface("com.jiang.dao.impl.AccountDao");
        //implement接口
        ctClass.addInterface(anInterface);
        //实现方法:
        //获取方法:
        Method[] methods = AccountDao.class.getDeclaredMethods();
        //System.out.println(methods.length);  4
        Arrays.stream(methods).forEach(method -> {
            try {
                //接口中的方法如下:

                //int update(String actno,Double balance);
                //void delete();
                //int insert(String actno);
                //String selectByActno(String actno);
                StringBuilder methodCode = new StringBuilder();
                methodCode.append("public");//修饰符号
                methodCode.append(" ");
                methodCode.append(method.getReturnType().getName());//返回值类型
                methodCode.append(" ");
                methodCode.append(method.getName());
                methodCode.append("(");
                //参数:
                //System.out.println(method.getParameterCount());  2 0 1 1
                //System.out.println(method.getParameterTypes());
                //System.out.println(method.getAnnotatedReturnType().getType());  int void int String
                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("{System.out.println(1111);");
                //添加return语句
                //System.out.println(method.getReturnType().getName());  java.lang.String
                //System.out.println(method.getReturnType().getSimpleName());  String

                String simpleName = method.getReturnType().getSimpleName();
                if ("void".equals(simpleName)) {

                }else if ("int".equals(simpleName)) {
                    methodCode.append("return 1;");
                }else  if ("String".equals(simpleName)) {
                    methodCode.append("return \"hello\";");
                }
                methodCode.append("}");
                System.out.println(methodCode);

                CtMethod ctMethod = CtMethod.make(methodCode.toString(),ctClass);
                ctClass.addMethod(ctMethod);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        Class<?> aClass = ctClass.toClass();
        AccountDao accountDao = (AccountDao) aClass.newInstance();
        accountDao.insert("aaa");
        accountDao.delete();
        accountDao.update("aaa",1000.00);
        accountDao.selectByActno("aaa");
    }

获取方法

1.无接口

   Object o = aClass.newInstance();
        //获取其方法
        Method insert = aClass.getDeclaredMethod("insert");
        //调用方法insert
        insert.invoke(o);

2. 有接口,直接接口调方法

  Class<?> aClass = ctClass.toClass();
        AccountDao accountDa = (AccountDao) aClass.newInstance();
        accountDa.delete();

Mybatis自带的自动生成接口实现类方法

SqlSession sqlSession = MybatisTool.getSession();
CarMapper carMapper =sqlSession.getMapper(CarMapper.class);

使用mybatis自带方法

结构

 1.CarMapper

package com.jiang.mapper;

import com.jiang.pojo.T_Car;

import java.util.List;

//一般使用mybatis来生产的话,不叫Dao 而是Mapper
public interface CarMapper {
    //持久化层 专门做增删改查
    int insert(T_Car car);
    //Long 防止null异常
    int deleteByid(Long id);

    int update(T_Car car);

    T_Car selectByid(Long id);

    List<T_Car> selectAll();

}

 2.T_Car

package com.jiang.pojo;

import java.util.Objects;

public class T_Car {
    //如果你认为这个属性不能为null,那么就用long,因为它默认初值为0,如果这个字段可以为null,那么就应该选择Long。
    private Long id;
    private String car_num;
    private String brand;
    private Double guide_price;
    private String produce_time;
    private String car_type;

    @Override
    public String toString() {
        return "T_Car{" +
                "id=" + id +
                ", car_num='" + car_num + '\'' +
                ", brand='" + brand + '\'' +
                ", guide_price='" + guide_price + '\'' +
                ", produce_time='" + produce_time + '\'' +
                ", car_type='" + car_type + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        T_Car t_car = (T_Car) o;
        return Objects.equals(id, t_car.id) && Objects.equals(car_num, t_car.car_num) && Objects.equals(brand, t_car.brand) && Objects.equals(guide_price, t_car.guide_price) && Objects.equals(produce_time, t_car.produce_time) && Objects.equals(car_type, t_car.car_type);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, car_num, brand, guide_price, produce_time, car_type);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getcar_num() {
        return car_num;
    }

    public void setcar_num(String car_num) {
        this.car_num = car_num;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getGuide_price() {
        return guide_price;
    }

    public void setGuide_price(Double guide_price) {
        this.guide_price = guide_price;
    }

    public String getProduce_time() {
        return produce_time;
    }

    public void setProduce_time(String produce_time) {
        this.produce_time = produce_time;
    }

    public String getCar_type() {
        return car_type;
    }

    public void setCar_type(String car_type) {
        this.car_type = car_type;
    }

    public T_Car() {
    }

    public T_Car(Long id, String car_num, String brand, Double guide_price, String produce_time, String car_type) {
        this.id = id;
        this.car_num = car_num;
        this.brand = brand;
        this.guide_price = guide_price;
        this.produce_time = produce_time;
        this.car_type = car_type;
    }
}

3.MybatisTool(获取sqlsession) 

package com.jiang.utils;

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;

public class MybatisTool {

    public static ThreadLocal<SqlSession> local = new ThreadLocal();
    private MybatisTool(){}
    private static SqlSessionFactory sessionFactory;
    static {
        try {
            //该处容易出错,记得指定环境 ****
            sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("Config.xml"),"one");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSession(){
        SqlSession session = local.get();
        if (session==null) {
            SqlSession sqlSession = sessionFactory.openSession();
            session=sqlSession;
            local.set(session);
        }
        return session;
    }
    public static void close(SqlSession session){
        if (session!=null) {
            session.close();
            local.remove();
        }
    }
}


4.Mapper.xml

<?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.jiang.mapper.CarMapper">
    <insert id="insert" >
        insert into t_car values(null,#{num},#{brand},#{guide_price},#{produce_time},#{car_type})
    </insert>

    <delete id="deleteByid">
        delete from t_car where id=#{id}
    </delete>

    <update id="update">
        update t_car set car_num=#{num},brand=#{brand},guide_price=#{guide_price},produce_time=#{produce_time},car_type=#{car_type} where id=#{id}
    </update>

    <select id="selectByid" resultType="com.jiang.pojo.T_Car">
        select id,car_num as num,brand,guide_price,produce_time,car_type from t_car where id=#{id}
    </select>

    <select id="selectAll" resultType="com.jiang.pojo.T_Car">
        select id,car_num as num,brand,guide_price,produce_time,car_type from t_car
    </select>
</mapper>

测试

关键几个点:

  • sqlsession是用来获取Mapper.xml中的sql语句和其返回值类型(参照自己写的)
  • sqlsession.getMapper(传入想实现的接口)
package com.jiang.Test;

import com.jiang.mapper.CarMapper;
import com.jiang.pojo.T_Car;
import com.jiang.utils.MybatisTool;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class Test {
    @org.junit.Test
    public void TestInsert(){
        SqlSession sqlSession = MybatisTool.getSession();
        CarMapper carMapper =sqlSession.getMapper(CarMapper.class);
        T_Car car=new T_Car(null,"1000","宝马",1010.00,"2022-11-22","motuo");
        int i = carMapper.insert(car);
        sqlSession.commit();
        MybatisTool.close(sqlSession);
        System.out.println(i);
    }
    @org.junit.Test
    public void TestDeleteByid(){
        //实现持久化接口:
        SqlSession sqlSession=MybatisTool.getSession();
        CarMapper carMapper=MybatisTool.getSession().getMapper(CarMapper.class);
        int i = carMapper.deleteByid(37L);
        sqlSession.commit();
        MybatisTool.close(sqlSession);
    }
    @org.junit.Test
    public void TestUpdate(){
        SqlSession sqlSession=MybatisTool.getSession();
        T_Car car=new T_Car(1L,"1000","宝马",1010.00,"2022-11-22","motuo");
        CarMapper carMapper = sqlSession.getMapper(CarMapper.class);
        carMapper.update(car);
        sqlSession.commit();
        MybatisTool.close(sqlSession);
    }
    @org.junit.Test
    public void TestSelectById(){
        SqlSession sqlSession=MybatisTool.getSession();
        CarMapper carMapper = sqlSession.getMapper(CarMapper.class);
        T_Car t_car = carMapper.selectByid(1L);
        System.out.println(t_car);
        MybatisTool.close(sqlSession);
    }
    @org.junit.Test
    public void TestSelectAll(){
        SqlSession sqlSession=MybatisTool.getSession();
        CarMapper carMapper=sqlSession.getMapper(CarMapper.class);
        List<T_Car> t_carList = carMapper.selectAll();
        for (T_Car t_car : t_carList) {
            System.out.println(t_car);
        }
        MybatisTool.close(sqlSession);
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值