迷你版mybatis

时间:2019-11-27
本文章向大家介绍迷你版mybatis,主要包括迷你版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>

原文地址:https://www.cnblogs.com/yaowen/p/11945150.html