• 模拟实现MyBatis中通过SQL反射实体类对象功能


    话不多说,直接上干货!

    package cn.test;
    
    import java.lang.reflect.Method;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.Timestamp;
    
    import org.junit.Test;
    
    import cn.core.domain.User;
    
    
    public class UseMyBatis {
        
        /**
         * 模拟MyBites根据sql动态创建对象.
         * @throws Exception
         */
        @Test
        public void simulation() throws Exception{
            //className应该是传参或者是读取配置文件读出来的一个指定类型,这里为了测试直接先写死了。
            String className="cn.core.domain.User";
            //加载驱动,下面是jdbc的一段代码
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn=DriverManager.getConnection("jdbc:mysql://192.168.1.68/base", "root", "root");
            String sql="select * from base_user where user_id=?";
            PreparedStatement ps=conn.prepareStatement(sql);
            ps.setString(1, "00a8ea6b8b524205bc0af1c3249abe54");
            ResultSet rs=ps.executeQuery();
            //循环获取每行数据
            while (rs.next()) {
                //每一行就表示一个对象,通过反射将实体类创建出来
                Object object=Class.forName(className).newInstance();
                //通过ResultSetMetaData这个对象获取查询语句的原始列名,列总数以及列的类型
                ResultSetMetaData data=rs.getMetaData();
                //获取列总数
                int count=data.getColumnCount();
                //循环得到列名和列类型
                for (int i = 1; i <= count; i++) {
                    String column=data.getColumnName(i);//获取列名
                    String typeName=data.getColumnTypeName(i);//获取列类型
                    String setMethodName=bulidSetMethod(column);//获取具体实体类中的set方法名
                    //根据列类型去获取列数据,具体参考数据库的类型将和rs.getXXX对应上去取值即可
                    if("VARCHAR".equals(typeName)){
                        String value=rs.getString(column);//取值
                        //通过方法名进行反射得到具体的方法对象
                        Method method=object.getClass().getMethod(setMethodName,String.class);
                        //执行这个方法并对应的字段去赋值
                        method.invoke(object, value);
                    }else if("DATETIME".equals(typeName)){//操作同上,只不过类型换成了时间类型
                        Timestamp value=rs.getTimestamp(column);
                        Method method=object.getClass().getMethod(setMethodName,Timestamp.class);
                        method.invoke(object, value);
                    }
                    //将数据库的类型都列出来,剩余的和上述差不多就不一一写出来了....
                }
                //下面这块就到了我们实际运用的过程了   这块可以根据业务需要 返回会单个object或者是list
                User user=(User)object;
                System.out.println(user);
            }
            
            
        }
        
        
        /**
         * 将列名转换成对应的set方法名.
         * @param columnName 列名
         * @return set方法名
         */
        public String bulidSetMethod(String columnName){
            String c1="set";
            String c2=columnName.substring(0,1).toUpperCase();
            String c3=columnName.substring(1);
            return c1+c2+c3;
        }
        
        
    }

    OK,java中所有的持久化框架底层全是jdbc去实现的,那么通过jdbc模拟一个MyBites主要是通过java反射的机制去实现的,通过反射sql的列名得到具体的set方法名,通过执行set方法给字段注入具体的值,所以框架本身并不难,只要想通了其中的点,其实实现起来也就几行代码而已。

  • 相关阅读:
    java编程规范
    Servlet生命周期
    BBS
    Hibernate主键自增策略
    MyBatis举例以及连接数据库过程
    myBatis框架的配置部分
    持续集成
    2017-02-23 .NET Core Tools转向使用MSBuild项目格式
    记录表TABLE中 INDEX BY BINARY_INTEGER 的作用
    什么是 BIND 变量?
  • 原文地址:https://www.cnblogs.com/mycifeng/p/7244246.html
Copyright © 2020-2023  润新知