迷你版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最近也加入了变脸.预定直播时间和双人录制的功能,更不用说国内 ...
随机推荐
- Linux 部署vue项目(使用nginx)
1.部署Nginx 请参考Linux下部署nginx,此处不再重复 2.Vue项目打包 # 打包正式环境 npm run build:prod # 打包预发布环境 npm run build:stag ...
- PHP判断设备访问来源
/** * 判断用户请求设备是否是移动设备 * @return bool */ function isMobile() { //如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (is ...
- Fusionstorage的逻辑架构
Fusionstorage Fusionstorage的逻辑架构 Mdc:元数据控制,实现对分布式集群的状态控制,以及控制数据分布式规则,数据重建规则等,mdc默认部署在3个节点的zk盘上,形成mdc ...
- Nginx+keepalived(高可用主备模式)
Nginx+keepalived(高可用主备模式) 环境:centos6.7 准备:两台服务器(虚拟机).两台应用(Tomcat).Nginx.keepalived server1:192.168.2 ...
- python web框架Flask——后台登录
项目搭建 创建一个项目之后,需要在手动创建几个包(含有__init__.py文件的目录)和文件 1.在主目录下创建配置文件:config.py 2.在主目录下创建扩展文件:exts.py 3.在主目录 ...
- react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN ...
- 【微信小程序】template模板使用详解
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用. 模板的作用域: 模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs / ...
- [20191011]拆分rowid 2.txt
[20191011]拆分rowid 2.txt --//有了链接http://blog.itpub.net/267265/viewspace-2659612/=>[20191011]bash任意 ...
- 数据库 OR 运维 ____bayaim
最近一直在思考,想想未来的道路和自己努力的方向.马云曾说过现在的年轻人缺少“慢下来”,只有人慢下来才能更好思考,想好方法和目标才更靠近才成功.如果,一直不停的努力,在错误的道路越走越远,势必会浪费时间 ...
- -bash: /home/java/jdk1.8.0_221/bin/java: 权限不够
1)进入存放jdk文件的文件夹路径我这里是 usr/local/jdk/2)输入命令 chmod 777 jdk1.8.0_221/bin/java修改权限3)再次输入 java -version 成 ...