迷你版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>


迷你版mybatis的更多相关文章
- ASP.NET Core管道深度剖析(2):创建一个“迷你版”的管道来模拟真实管道请求处理流程
从<ASP.NET Core管道深度剖析(1):采用管道处理HTTP请求>我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但 ...
- 自用迷你版的Deferred
啥也不说贴代码,项目用 /** * 迷你版的deferred */ function Deferred(func) { if (this instanceof Deferred === false) ...
- 迷你版jQuery——zepto核心源码分析
前言 zepto号称迷你版jQuery,并且成为移动端dom操作库的首选 事实上zepto很多时候只是借用了jQuery的名气,保持了与其基本一致的API,其内部实现早已面目全非! 艾伦分析了jQue ...
- 迷你版Deferred
直接贴代码: /** * 迷你版的deferred */ function Deferred(func) { if (this instanceof Deferred === false) { ret ...
- 写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)
前些时间在看创智博客韩顺平的Smarty模板引擎教程,再结合自己跟李炎恢第二季开发中CMS系统写的tpl模板引擎.今天就写一个迷你版的Smarty引擎,虽然说我并没有深入分析过Smarty的源码,但是 ...
- 迷你版 smarty --模板引擎和解析
http://blog.ipodmp.com/archives/php-write-a-mini-smarty-template-engine/ 迷你版Smarty模板引擎目录结构如下: ① 要开发一 ...
- 一个用 C 语言写的迷你版 2048 游戏,仅仅有 500个字符
Jay Chan 用 C 语言写的一个迷你版 2048 游戏,仅仅有 487 个字符. 来围观吧 M[16],X=16,W,k;main(){T(system("stty cbreak&qu ...
- (转)金蝶KIS迷你版、标准版在查询数量金额明细账时提示“发生未知错误,系统当前操作被取消,请与金蝶公司联系”
金蝶KIS迷你版.标准版在查询数量金额明细账时提示“发生未知错误,系统当前操作被取消,请与金蝶公司联系” 2013-07-10 12:17:51| 分类: 金蝶专题|举报|字号 订阅 金 ...
- 直播的本质(创业者应该要从商业模式的右边开始思考,你为用户创造了什么价值?找客户并不难,但要想办法让客户不离不弃;PC端功能的丰富很重要,因为手机版通常只是一个迷你版)
我想稍微给直播这件事浇点冷水. 的确,直播现在越来越火,YouTube凭着良好的基础建设平台前段时间也做起了直播,Facebook Live最近也加入了变脸.预定直播时间和双人录制的功能,更不用说国内 ...
随机推荐
- SQLserver无法删除数据库 "XXXX",因为该数据库当前正在使用。
问题描述: 有时候删除库的时候,会显示无法删除数据库,因为该数据库当前正在使用. 解决方法: 方法一: EXEC msdb.dbo.sp_delete_database_backuphistory @ ...
- C语言--计算程序执行时间
C语言–计算程序执行时间1. gettimeofday精度1us #include<stdio.h>#include<sys/time.h> int main(){ /* 定义 ...
- Python的定时执行
最近手把手教妹子写Python,被一篇博客误导了,这里记录一下. 妹子需要的是一个定时闹钟,到点往钉钉群里推个消息.她一顿搜索猛如虎,参照着其他人的博客,搞了一个while: target_time ...
- Java 类加载机制(阿里)-何时初始化类
(1)阿里的面试官问了两个问题,可以不可以自己写个String类 答案:不可以,因为 根据类加载的双亲委派机制,会去加载父类,父类发现冲突了String就不再加载了; (2)能否在加载类的时候,对类的 ...
- vue项目中引入iconfont
背景 对于前端而言,图标的发展可谓日新月异.从img标签,到雪碧图,再到字体图标,svg,甚至svg也有了类似于雪碧图的方案svg-sprite-loader.雪碧图没有什么好讲的了,只是简单地利用了 ...
- Spring MVC的常用注解(一)
概述 Spring从2.5版本开始引入注解,虽然版本不断变化,但是注解的特性一直被延续下来并不断进行扩展,这里就来记录一下Spring MVC中常用的注解,本文记录@Controller.@Reque ...
- 分布式服务防雪崩熔断器(Hystrix),实现服务降级
Hystrix是什么? hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与hystrix本身的功能不谋而合,因此Netflix团队将该框架命名 ...
- JavaScript初探 五
JavaScript 初探 七 JavaScript 数据类型 基本的值类型 字符串(String) 数 字(Number) 布尔值(Boolean) 对 象(Object) 函 数(Function ...
- rust 高级话题
目录 rust高级话题 前言 零大小类型ZST 动态大小类型DST 正确的安装方法 结构体 复制和移动 特征对象 引用.生命周期.所有权 生命周期 错误处理 交叉编译 智能指针 闭包 动态分派和静态分 ...
- Vysor
官网:http://www.vysor.io/ Vysor用 PC远程控制投影安卓手机/平板工具 Vysor 是一个免费的google浏览器插件. 它可以让你在pc上控制你的Android手机.平板等 ...