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的更多相关文章

  1. ASP.NET Core管道深度剖析(2):创建一个“迷你版”的管道来模拟真实管道请求处理流程

    从<ASP.NET Core管道深度剖析(1):采用管道处理HTTP请求>我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但 ...

  2. 自用迷你版的Deferred

    啥也不说贴代码,项目用 /** * 迷你版的deferred */ function Deferred(func) { if (this instanceof Deferred === false) ...

  3. 迷你版jQuery——zepto核心源码分析

    前言 zepto号称迷你版jQuery,并且成为移动端dom操作库的首选 事实上zepto很多时候只是借用了jQuery的名气,保持了与其基本一致的API,其内部实现早已面目全非! 艾伦分析了jQue ...

  4. 迷你版Deferred

    直接贴代码: /** * 迷你版的deferred */ function Deferred(func) { if (this instanceof Deferred === false) { ret ...

  5. 写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)

    前些时间在看创智博客韩顺平的Smarty模板引擎教程,再结合自己跟李炎恢第二季开发中CMS系统写的tpl模板引擎.今天就写一个迷你版的Smarty引擎,虽然说我并没有深入分析过Smarty的源码,但是 ...

  6. 迷你版 smarty --模板引擎和解析

    http://blog.ipodmp.com/archives/php-write-a-mini-smarty-template-engine/ 迷你版Smarty模板引擎目录结构如下: ① 要开发一 ...

  7. 一个用 C 语言写的迷你版 2048 游戏,仅仅有 500个字符

    Jay Chan 用 C 语言写的一个迷你版 2048 游戏,仅仅有 487 个字符. 来围观吧 M[16],X=16,W,k;main(){T(system("stty cbreak&qu ...

  8. (转)金蝶KIS迷你版、标准版在查询数量金额明细账时提示“发生未知错误,系统当前操作被取消,请与金蝶公司联系”

    金蝶KIS迷你版.标准版在查询数量金额明细账时提示“发生未知错误,系统当前操作被取消,请与金蝶公司联系” 2013-07-10 12:17:51|  分类: 金蝶专题|举报|字号 订阅       金 ...

  9. 直播的本质(创业者应该要从商业模式的右边开始思考,你为用户创造了什么价值?找客户并不难,但要想办法让客户不离不弃;PC端功能的丰富很重要,因为手机版通常只是一个迷你版)

    我想稍微给直播这件事浇点冷水. 的确,直播现在越来越火,YouTube凭着良好的基础建设平台前段时间也做起了直播,Facebook Live最近也加入了变脸.预定直播时间和双人录制的功能,更不用说国内 ...

随机推荐

  1. 【mysql报错】[Err] 1248 - Every derived table must have its own alias

    当我运行一条联合查询的sql语句时报如下错误: [Err] 1248 - Every derived table must have its own alias,大概意思是每一张派生表必须要有自己的别 ...

  2. MySQL基础之自连接用法简介

    MySQL系列之自连接简介,MySQL自连接操作,没有特定的关键字,所谓自连接指的是同一个表不同实例之间的join操作 引用https://www.w3resource.com的图示: 特征: 自连接 ...

  3. 拎壶学python3-----(5)pycharm解决运行时少库的问题

    有时候我们运行的时候会出现如下现象 no module named requests怎么办呢? 点击设置: 安装成功后会显示如下: 怎么进行安装呢? 然后退出再运行: 发现已经没有缺少requests ...

  4. Do Deep Nets Really Need to be Deep?

    url: https://arxiv.org/pdf/1312.6184.pdf year: NIPS2014 浅网络学习深网络的函数表示, 训练方法就是使用深网络的 logits(softmax i ...

  5. make 命令与 Makefile

    make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建.虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发.ma ...

  6. oracle学习笔记(九) SQL常用函数说明以及使用

    SQL常用函数说明以及使用 以下补充以下常用的函数,更多的请看oracle函数API文档 to_char to_char(8.58,'9.99') to_char(8.50,'9.00') to_ch ...

  7. Wpf Prism.Unity 7

    Prism.Unity 中UnityBootStrapper已经不用了,可以继承PrismApplication 1.Install-package Prism.Unity -v 7.2.0.1367 ...

  8. 最近的项目系之3——core3.0整合Senparc

    1.前言 既然是.net下微信开发,自然少不了Senparc,可以说这个框架的存在, 至少节省了微信相关工作量的80%.事实上,项目开始前,还纠结了下是Java还是core,之所以最终选择core,除 ...

  9. 这篇文章带你彻底理解synchronized

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  10. SpringBoot(一):构建第一个SpringBoot工程

    1.项目格式如下: 1.启动类: package com.monkey01.springbootstart; import org.springframework.boot.SpringApplica ...