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>