美文网首页
扩展jdk动态代理:手搭mybaits(Mapper映射)

扩展jdk动态代理:手搭mybaits(Mapper映射)

作者: 小2斗鱼 | 来源:发表于2017-08-15 15:12 被阅读0次

    mybaits的资源定位,解析,注册实际上都和springIOC容器的初始化过程大同小易。最关键的一点就是Mapper文件的映射原理。和Hibernate不同的是mybaits只从数据库映射到pojo,是单向的。

    mybaits基本原理

    基本原理

    仿照mybaits实现最简单的mapper映射

    模拟已经解析完成的xml

    package eproxy;
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class MapperXML {
        static final String nameSapce="eproxy.UserMapper";
        static Map<String,String> map=new ConcurrentHashMap<String,String>();
        static{
            map.put("findById", "SELECT USERNAME,SEX,ADDRESS FROM USER WHERE ID=%d");
            
            
        }
        
    
    }
    
    

    第一步:创建SqlSession

    package eproxy;
    
    import java.lang.reflect.Proxy;
    
    public class MySqlSession {
        private final Executor executor=new SimpleExecutor();
        
        public <T> T  selectOne(String statement, Object parameter){
            return executor.query(statement, parameter);
        }
        
        @SuppressWarnings("unchecked")
        public <T> T getMapper(Class<T> type){
            
            return(T)Proxy.newProxyInstance(MySqlSession.class.getClassLoader(), 
                    new Class[]{type}, new MapperProxy<T>(type,this));
            
        }
    
    }
    

    第二步:创建MyProxyMapper代理类

    package eproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class MapperProxy<T> implements InvocationHandler {
        private final Class<T>  mapperinterface;
        private final MySqlSession sqlSession;
        
        public MapperProxy(Class<T> mapperinterface, MySqlSession sqlSession) {
            this.mapperinterface= mapperinterface;
            this.sqlSession=sqlSession;
            
        }
          //核心代码
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if(method.getDeclaringClass().getName().equals(MapperXML.nameSapce)){
                String sql = MapperXML.map.get(method.getName());
                System.out.println(String.format("sql[%s],paramters[%s]", sql,args[0]));
                //存在硬编码
                return sqlSession.selectOne(sql, args[0]);
            }else{
                throw new Exception("name space is not exists");
            }
        }
    
    }
    
    

    第三步:创建Executor

    package eproxy;
    
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    
    
    
    public class SimpleExecutor implements Executor {
    
        @Override
        public <T> T query(String statement, Object parameter) {
            User user=null;
            try {
                Connection con = getConection();
                PreparedStatement ps = con
                        .prepareStatement(String.format(statement, Integer.parseInt(parameter.toString())));
                ResultSet rs = ps.executeQuery();
                // 硬编码
                user= new User();
                while (rs.next()) {
                    user.setUsername(rs.getString(1));
                    user.setSex(rs.getString(2));
                    user.setAddress(rs.getString(3));
                }
                
    
            } catch (SQLException e) {
                e.printStackTrace();
    
            }
            return (T) user;
    
        }
    
        private Connection getConection() throws SQLException {
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                
                e.printStackTrace();
            }
            Connection connection = DriverManager.
                    getConnection("jdbc:mysql://localhost:3306/mybaits?characterEncoding=UTF8","root","admin");
            
            return connection;
        }
    
    }
    
    
    结构

    相关文章

      网友评论

          本文标题:扩展jdk动态代理:手搭mybaits(Mapper映射)

          本文链接:https://www.haomeiwen.com/subject/zftvrxtx.html