zoukankan      html  css  js  c++  java
  • 迷你版mybatis

    public class BootStrap {
        public static void start(){
            MySqlSession sqlSession = new MySqlSession();//外层使用sqlSession,生成Mapper的代理,
            //TestMapper是一个接口,所以是一个动态代理,
            TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
            //Mapper去查询语句,里面调用的是Mapper代理的invoke方法,invoke方法里面调用sqlSession的查询数据库方法,
            //sqlSession的查询数据库方法调用的是Executor的方法,
            Test test = testMapper.selectByPrimaryKey(1);
            System.out.println(test);
        }
    
        public static void main(String[] args){
            start();
        }
    }
    public class MySqlSession {
        private Executor executor = new SimpleExecutor();
    
        public <T> T selectOne(String statement, Object parameter) {
            return executor.query(statement,parameter);
        }
    
        public <T> T getMapper(Class<T> clazz) {//clazz是一个接口,
            return (T) Proxy.newProxyInstance(clazz.getClassLoader(),
                    new Class[]{clazz}, new MapperProxy(this, clazz));
            //new MapperProxy里面传进去的是接口和SqlSession
    
            //jdk动态代理时候,new MapperProxy是代理(实现类的方法前后加内容),
            //new MapperProxy的形参是接口的实现类。
            //mybatis没有传实现类进去,使用的是sqlSession来实现真正查询数据库操作。
    
            //public class Advice implements InvocationHandler1 {
                //People people;//接口,传进来实例
                //public Advice(People people) {
                //    this.people = people;
                //}
               // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               //     before();//前置增强
               //     Object value = method.invoke(people,args);//被代理方
                ///    after();//后置增强
                //    return value;
               // }
            //}
    
            //public class MyTest {
              //  public static void main(String[] args) {
               //     People proxyObject = (People) Proxy1.newProxyInstance(MyTest.class.getClassLoader(),
                //            new Class<?>[] { People.class }, new Advice(new Jack()));
            
        }
    }
    public class MapperProxy<T> implements InvocationHandler {
        private final MySqlSession sqlSession;
        private final Class<T> mapperInterface;
    
        public MapperProxy(MySqlSession sqlSession, Class<T> mapperInterface) {
            this.sqlSession = sqlSession;//接口和sqlSession,
            this.mapperInterface = mapperInterface;
        }
    
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getDeclaringClass().getName().equals(TestMapperXml.nameSpace)) {
                String sql = TestMapperXml.methodSqlMapping.get(method.getName());
                System.out.println(String.format("SQL [ %s ], parameter [%s] ", sql, args[0]));
                return sqlSession.selectOne(sql, String.valueOf(args[0]));
            }
            return null;
        }
    }
    public interface Executor {
        <E> E query(String statement, Object parameter);
    }
    public class SimpleExecutor implements Executor {
    
        public <E> E query(String sql, Object parameter) {
            try {
                Connection conn = getConnection();
                PreparedStatement pstmt;
                pstmt = conn.prepareStatement(String.format(sql, Integer.parseInt(String.valueOf(parameter))));
                ResultSet rs = pstmt.executeQuery();
                Test test = new Test();
                while (rs.next()) {
                    test.setId(rs.getInt(1));
                    test.setName(rs.getString(2));
                }
                return (E) test;
            }
            return null;
        }
    
        public Connection getConnection() throws SQLException {
            String driver = "com.mysql.cj.jdbc.Driver";
            String url = "jdbc:mysql://localhost:3306/upgrade?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
            String username = "root";
            String password = "123456";
            Connection conn = null;
            try {
                Class.forName(driver); //classLoader,加载对应驱动
                conn = DriverManager.getConnection(url, username, password);
            }
            return conn;
        }
    }
    public class CachingExecutor implements Executor {
        private GpConfiguration configuration;
        private SimpleExecutor delegate;
        private Map<String,Object> localCache = new HashMap();
    
        public CachingExecutor(SimpleExecutor delegate) {
            this.delegate = delegate;
        }
    
        public CachingExecutor(GpConfiguration configuration) {
            this.configuration = configuration;
        }
    
        public <E> E query(MapperRegistory.MapperData mapperData, Object parameter)
                throws Exception {
            //初始化StatementHandler --> ParameterHandler --> ResultSetHandler
            StatementHandler handler = new StatementHandler(configuration);
            Object result = localCache.get(mapperData.getSql());
            if( null != result){
                System.out.println("缓存命中");
                return (E)result;
            }
            result =  (E) delegate.query(mapperData,parameter);
            localCache.put(mapperData.getSql(),result);
            return (E)result;
        }
    }
    public interface TestMapper {
        Test selectByPrimaryKey(Integer userId);
    }
    public class TestMapperXml {
        public static final String nameSpace = "com.gupaoedu.mybatis.my.TestMapper";
        public static final Map<String, String> methodSqlMapping = new HashMap<String, String>();
        static {
            methodSqlMapping.put("selectByPrimaryKey", "select * from test where id = %d");
        }
    }
    一级缓存是在update,delete时候会去更新缓存。

    事务:都是用spring来管理事务的。
    
     <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property value="jdbc:mysql://localhost:3306/upgrade?useSSL=false" name="url"/>
                    <property name="username" value="root"/>
                    <property name="password" value=""/>
                </dataSource>
            </environment>
        </environments>

  • 相关阅读:
    分布式缓存技术之Redis_03分布式redis
    Spring 二、400行代码手写初体验Spring V1.0版本
    Spring 一、各级架构与依赖关系
    Java正则表达式基础学习
    JAVA开发:SpringBoot多数据源配置
    Spring 单例模式实现源码分析
    Spring 使用的设计模式用哪些
    Spring之@Autowired和@Resource
    Spring的优缺点
    MySQL支持的事物隔离级别以及悲观锁和乐观锁原理和应用场景
  • 原文地址:https://www.cnblogs.com/yaowen/p/11945150.html
Copyright © 2011-2022 走看看