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>