java.lang.IllegalArgumentException: argument type mismatch

梁泰
2023-12-01

问题:

19-Apr-2022 11:08:37.371 信息 [http-nio-8080-exec-5] com.alibaba.druid.pool.DruidDataSource.info {dataSource-1} inited
java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.fan.goods.dao.DBUtil.executeQuery(DBUtil.java:197)
	at com.fan.goods.dao.impl.GoodsDaoImpl.getGoodsList(GoodsDaoImpl.java:13)
	at com.fan.goods.service.GoodsServiceImpl.getGoodsList(GoodsServiceImpl.java:13)
	at com.fan.goods.servlets.GoodsServlet.getGoodsList(GoodsServlet.java:28)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.fan.goods.servlets.BaseServlet.service(BaseServlet.java:27)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:750)

这个问题是参数类型不匹配,是我这个项目的实体和数据库中表不匹配,参数不匹配,可不单单指的是名字不一样,还有类型,我做个这个项目是javaweb,那个与数据库进行交互的那个类,我写成了工具类,工具类如下:

package com.fan.goods.dao;


import com.alibaba.druid.pool.DruidDataSource;
import org.apache.commons.beanutils.ConvertUtils;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * 数据库操作的辅助类
 * 要求所有操作数据库的类都要继承该类
 * 而且这个类不允许实例化
 */
public abstract class DBUtil {

    protected Connection conn = null;
    protected PreparedStatement ps = null;
    protected ResultSet rs = null;
    private static DruidDataSource druidDataSource = null;


    /**
     * 连接数据库
     * @return  连接对象
     */
    protected Connection getConn1() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        return conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/goods?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai", "root", "FJG258775");
    }

    static{
        try {
            //读取资源文件(db.properties)
            //创建一个资源类实例对象
            Properties properties = new Properties();
            //将资源文件db.properties加载内存中,生成一个输入流对象
            InputStream inputStream = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
            //将输入流对象添加到properties对象,此时properties对象会自动读取输入流中的数据
            properties.load(inputStream);
            //创建Druid数据源对象
            druidDataSource = new DruidDataSource();
            //将properties对象中属性自动添加到druid对象中
            druidDataSource.configFromPropety(properties);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接数据库基于数据库连接池Druid
     * @return  连接对象
     */
    protected Connection getConn() throws ClassNotFoundException, SQLException, IOException {




        //从druid中获取连接对象
        return conn = druidDataSource.getConnection();

    }



    /**
     * 释放资源方法
     */
    protected void closeAll(){
        try {
            if(rs != null){
                rs.close();
            }

            if(ps != null){
                ps.close();
            }

            if(conn != null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            conn = null;
            ps = null;
            rs = null;
        }
    }

    /**
     * 执行增、删、改操作的通用方法
     * @param sql  SQL语句
     * @param params   SQL语句中?号占位符的值,参数的顺序与SQL语句中?号占位符的值得顺序一致,类型也要一致
     *                 Object...:可变参数,数组
     * @return
     */
    protected int executeUpdate(String sql,Object... params){
        try {
            //连接数据库
            this.getConn();
            //创建预处理对象
            ps = conn.prepareStatement(sql);
            /***
             * 设置?号占位符的值
             * 先判断SQL语句中是否包含?号,如果包含才设置,如果不包含则不设置
             * 根据params参数判断SQL语句中是否包含?号占位符
             */
            if(params!=null && params.length!=0){
                //循环设置?号占位符的值
                for(int i=0;i<params.length;i++){
                    ps.setObject(i+1,params[i]);
                }
            }
            //执行SQL语句并返回结果
            return ps.executeUpdate();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            this.closeAll();
        }
        return 0;
    }

    /**
     * 使用反射封装一个方法:
     *  该方法可以自动将任意表的查询结果自动封装到对应的实体对象中,并将这些对象添加集合中返回
     *  约束条件:
     *      1.实体类中的属性的属性名必须和查询结果中的列名一致
     *      2.实体类中的属性的类型必须和查询结果中列的类型相对应
     */
    /**
     * 执行查询的通用方法,该方法可以将查询的结果自动封装到实体对象,并实体对象添加到集合中返回
     *  持久层框架中的查询映射功能都是使用类似的方式进行封装的(MyBatis,Hibernate)
     * @param cla           SQL语句中查询结果对应的实体类的字节码对象
     * @param sql           SQL语句
     * @param params        SQL语句中?号占位符的值
     * @param <T>           通用泛型,T表示任意类型
     * @return              List集合
     */
    public <T> List<T> executeQuery(Class<T> cla, String sql, Object... params){
        System.out.println("开始封装查询结果....");
        try {
            //连接数据库
            this.getConn();
            //创建预处理对象
            ps = conn.prepareStatement(sql);
            /***
             * 设置?号占位符的值
             * 先判断SQL语句中是否包含?号,如果包含才设置,如果不包含则不设置
             * 根据params参数判断SQL语句中是否包含?号占位符
             */
            if(params!=null && params.length!=0){
                //循环设置?号占位符的值
                for(int i=0;i<params.length;i++){
                    ps.setObject(i+1,params[i]);
                }
            }
            //执行查询的SQL语句,返回结果集
            rs = ps.executeQuery();

            //获得当前查询结果集的元数据(元数据等同于表的表结构)
            ResultSetMetaData rsmt = rs.getMetaData();
            //从元数据中获得列的数量
            int columnCount = rsmt.getColumnCount();
            //创建一个用于存放所有实体对象的List集合
            List<T> list = new ArrayList<>();
            //遍历结果集
            while(rs.next()){
                //创建实体对象
                T t = cla.getDeclaredConstructor().newInstance();
                //获得当前行中对应的列数据
                //使用for循环遍历所有列
                for(int i=0;i<columnCount;i++){
                    //根据列编号获得每列的数据
                    Object value = rs.getObject(i+1);
                    //获得列名(列名与实体类中的属性名一致)
                    String columnName = rsmt.getColumnName(i+1);
                    //获得属性对象
                    Field field = cla.getDeclaredField(columnName);
                    //根据列名获得方法名
                    String methodName = "set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
                    //根据方法名和属性的列名获得方法对象
                    Method method = cla.getDeclaredMethod(methodName,field.getType());
                    //调用方法
                    //ConvertUtils.convert(value,field.getType()):使用类型转换器将value转换目标类型
                    method.invoke(t, ConvertUtils.convert(value,field.getType()));

                }

                //将封装好的对象添加到list集合中
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }  finally {
            this.closeAll();
        }
        return null;
    }
}

其工具类的要求就是项目中的实体与表中的实体不仅字段名要一致而且那个类型也要一致,我错就错在那个字段名一样了,但是那个类型,我把date不小心写成data了,一直报错,一直改,后来发现是自己把那个类型弄错了,所以还是要细心了

 类似资料:

相关阅读

相关文章

相关问答