迷你版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最近也加入了变脸.预定直播时间和双人录制的功能,更不用说国内 ...
随机推荐
- Spring核心(IoC) 入门解读
什么是IoC容器和Bean? 说到容器,就是用来装东西,那么这里边装的是什么那?是bean对象.那么你会问什么是bean?这就要从很久很久以前说起,当我们创建对象的时候,我们会new一个对象出来,但是 ...
- 面试官:你看过Redis数据结构底层实现吗?
面试中,redis也是很受面试官亲睐的一部分.我向在这里讲的是redis的底层数据结构,而不是你理解的五大数据结构.你有没有想过redis底层是怎样的数据结构呢,他们和我们java中的HashMap. ...
- 安装keepalived OpenSSL is not properly installed on your system. !!!
错误信息: configure: error: !!! OpenSSL is not properly installed on your system. !!! !!! Can not includ ...
- oracle学习笔记(二十二) REF 动态游标
动态游标 定义语法 --声明 $cursor_name$ sys_refcursor --打开动态游标 open $cursor_name$ is 查询语句; --关闭游标 close $cursor ...
- Abp vNext框架 实例程序BookStore-笔记
参考 Abp vNext框架 应用程序开发教程 创建项目和书籍列表页面 http://www.vnfan.com/helinbin/d/3579c6e90e1d23ab.html 官方源码 https ...
- MongoDB 高级教程
MongoDB 关系 MongoDB 的关系表示多个文档之间在逻辑上的相互联系. 文档间可以通过嵌入和引用来建立联系. MongoDB 中的关系可以是: 1:1 (1对1) 1: N (1对多) N: ...
- 100款机械CAD图纸,想要出图快,勤练是最有效的方式之一!
提升CAD出图效率最有效的方式就是勤加练习,所以跟着小匠每天练习3个,30天把这100个常用的CAD机械图纸练完,再看你的出图效率!贵在坚持! 100个机械CAD图纸,请收好
- Xcode修改工程文件名字
http://stackoverflow.com/questions/8262613/renaming-xcode-4-project-and-the-actual-folder
- Python的4个内置数据结构
Python提供了4个内置数据结构(内置指可以直接使用,无需先导入),可以保存任何对象集合,分别是列表.元组.字典和集合. 一.列表有序的可变对象集合. 1.列表的创建例子 list1 = []lis ...
- Debian创建.desktop文件(Create .desktop file in Debian/Gnome)
在Debian系Linux中,用于标识应用的启动文件.desktop file是位于/usr/share/applications目录下的,Gnome会将这些文件在菜单中展示为启动图标,也可以固定在d ...