昨天写的O/R mapping中间件,用了下感觉效果不错,开源了贡献给大家吧。
有兴趣的可以在我的blog里面一起讨论。
--------------------------
删除了很多对其他包的引用,现在应该是最小可用的版本了。
索性opensource,LGPL协议,欢迎大家试用。这玩意最大的优点,就是只是一个工具,而不是框架,所以与标准的JDBC和preparedstatement结合的很顺畅,能大幅度降低jdbc写法的工作量,
不过个人还是建议,写入用orm,读取在合适的时候稍微用一下绑定数据的DTO的代码,所以提供了GenericSelect类和GenericUpdate的rawSql函数,方便大家自己拼where的sql,真遇到复杂的select查询,大家还是别指望了,其实hibernate甚至nutzDAO也都指望不上的。
这个工具包,彻底贯彻了读写分离的思想,如果实现读取,需要继承GenericReader,如果实现写入,继承GenericWriter。
而且闲的蛋疼,把自动创建表和数据库也加上了。具体代码参考GenericCreator。
刚刚有更新了,修改了几个bug
依赖的包,主要是为了支持mysql和连接池,如果不用的话也可以删掉,修改SysDbInst的代码就行:
c3p0-0.9.2.1 cos-26Dec2008 guava-15.0 mchange-commons-java-0.2.3.4 mysql-connector-java-5.1.18-bin
下面贴一个具体的实现:代码在github的com.kami.console包下面.
关于最麻烦的Select操作,可以参考如下:
新建一个继承了BaseReader的对象,具体如何在自己的DAO用这个工具可以参考find(TestTable t)的实现,这个find(TestTable t)只是一个例子,无任何实际意义。在这里面也可以随意添加findByXXX的方法。
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.kami.console; import com.kamike.db.SysDbInst; import com.kamike.db.generic.BaseReader; import com.kamike.db.generic.GenericSelect; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author THiNk */ public class TestTableReader extends BaseReader<TestTable> { public TestTableReader(String dbName) { super(dbName); } @Override public GenericSelect<TestTable> createSelect() { return new TestTableSelect(); } @Override public GenericSelect<TestTable> createSelect(TestTable t) { return new TestTableSelect(t); } public long count(T t) { GenericSelect<TestTable> select = createSelect(); ResultSet rs = null; PreparedStatement ps = null; Connection conn = null; long ret = 0; try { conn = SysDbInst.getInstance().getDatabase().getSingleConnection(); ps = conn.prepareStatement(select.countSQL(select.rawSql(dbName)+ "where t.count=? "), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ps.setLong(1, t.getCount());//这里的查询参数的绑定,只能自己动手,丰衣足食了。 rs = ps.executeQuery(); ret = select.count(rs); } catch (Exception e) { ret =0; System.out.println(this.getClass().getName() + e.toString()); } finally { try { if (rs != null) { rs.close(); rs = null; } if (ps != null) { ps.close(); ps = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException ex) { Logger.getLogger(BaseReader.class.getName()).log(Level.SEVERE, null, ex); } } return ret; } @Override public ArrayList<TestTable> find(TestTable t) { GenericSelect<TestTable> select = createSelect(); ResultSet rs = null; PreparedStatement ps = null; Connection conn = null; ArrayList<TestTable> ret = null; try { conn = SysDbInst.getInstance().getDatabase().getSingleConnection(); ps = conn.prepareStatement(select.rawSql(dbName) + "where t.count=? ", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ps.setLong(1, t.getCount());//这里的查询参数的绑定,只能自己动手,丰衣足食了。 rs = ps.executeQuery(); ret = select.fetch(rs); } catch (Exception e) { ret = new ArrayList<>(); System.out.println(this.getClass().getName() + e.toString()); } finally { try { if (rs != null) { rs.close(); rs = null; } if (ps != null) { ps.close(); ps = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException ex) { Logger.getLogger(BaseReader.class.getName()).log(Level.SEVERE, null, ex); } } return ret; } }
然后是实体对象定义:
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.kami.console; import com.kamike.db.generic.FieldLength; import com.kamike.db.generic.FieldName; import com.kamike.db.generic.Id; import com.kamike.db.generic.TableName; import java.util.Date; /** * * @author THiNk */ @TableName("test_table") public class TestTable { @Id @FieldName("id") @FieldLength(64) private String id; @FieldName("count") private long count; @FieldName("name") @FieldLength(255) private String name; @FieldName("ready") private boolean ready; @FieldName("create_date") private Date createDate; /** * @return the id */ public String getId() { return id; } /** * @param id the id to set */ public void setId(String id) { this.id = id; } /** * @return the count */ public long getCount() { return count; } /** * @param count the count to set */ public void setCount(long count) { this.count = count; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the ready */ public boolean isReady() { return ready; } /** * @param ready the ready to set */ public void setReady(boolean ready) { this.ready = ready; } /** * @return the createDate */ public Date getCreateDate() { return createDate; } /** * @param createDate the createDate to set */ public void setCreateDate(Date createDate) { this.createDate = createDate; } }
然后要实现GenericSelect需要的几个对象new的方法,重载一下GenericSelect。。万恶的Java半吊子泛型。。
/* * 就写一个new。。不过两个构造器,有参的无参的都要这么实现,还有调用父类的构造器 */ package com.kami.console; import com.kamike.db.generic.GenericSelect; /** * * @author THiNk */ public class TestTableSelect extends GenericSelect<TestTable> { public TestTableSelect(TestTable t) { super(t); } public TestTableSelect() { super(); } @Override public TestTable create() { return new TestTable(); } }
然后就是调用了。
//查询测试 TestTableReader tts=new TestTableReader("kamike"); TestTable template=new TestTable(); template.setCount(500); ArrayList<TestTable> testList=tts.find(template);
JWT 中间件 JSON Web Token(JWT) 是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。 对于有效的令牌,它将用户存储进上下文,并调用下一个处理程序。 对于无效的令牌,它发送”401 - Unauthorized”的响应。 对于空的或无效的Authorization头,它发送”400 - Bad Request”。 使用 e.Use(middl
调用中间件的形式为: func( name string, args []reflect.Value, context Context, next NextInvokeHandler) (results []reflect.Value, err error) { ... results, err = next(name, args, context)
介绍 Laravel 中间件提供了一种方便的机制来过滤进入应用的 HTTP 请求。例如,Laravel 内置了一个中间件来验证用户的身份认证。如果用户没有通过身份认证,中间件会将用户重定向到登录界面。但是,如果用户被认证,中间件将允许该请求进一步进入该应用。 当然,除了身份认证以外,还可以编写另外的中间件来执行各种任务。例如:CORS 中间件可以负责为所有离开应用的响应添加合适的头部信息;日志中间
本文将介绍 Lavas 中间件的用法。 如果您想在进入路由组件之前,执行某些统一处理,就可以考虑使用中间件了。在同构应用中,中间件可以运行在客户端,服务端或者两者兼具的场景内。在实现中 Lavas 参考了 Nuxt 的实现,通过 vue-router 的路由钩子让中间件顺序执行。 对于开发者,如果想要使用中间件,需要完成以下两步: 将编写的中间件放在项目根目录 /middlewares 文件夹下,
中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出 激活:添加到Django配置文件中的MIDDLEWARE_CLASSES元组中 使用中间件,可以干扰整个处理过程,每次请求中都会执行中间件的这个方法 验证用户是否登陆示例 在应用中创建AdminLoginMiddleware.py文件 from django.shortcuts import
中间件是为应用提供通用服务和功能的软件。数据管理、应用服务、消息传递、身份验证和 API 管理通常都要通过中间件。 Kafka Kafka提供分布式、高吞吐、可扩展的消息队列服务。 Elasticsearch Elasticsearch是一个基于Lucene的实时分布式的搜索与分析引擎。
Web框架 GoJavaNode.jsPHPPython.NETRustLuaSwift 名称 描述 Gin 一个有着更好性能的 HTTP 网络框架,支持类似于 Martini 的 API,通过以下插件实现:authz或 gin-casbin Beego 一个 Go 语言的开源、高性能网络框架,通过以下插件实现:plugins/authz Caddy 快速、跨平台的有自动HTTPS的HTTP/2
中间件 Middleware is a function, which is called before route handler. Middleware functions have access to request and response objects, so they can modify them. They can also be something like a barrier