封装JDBC:实现简单ORM框架lfdb
作者:Vinkn 来自http://www.cnblogs.com/Vinkn/
一、简介
框架就是一组可重用的构件,LZ自己写的姑且就叫微型小框架:lfdb。LZ也对其他的ORM框架没有什么了解,现在只会一个Hibernate,还是勉强会,什么懒加载,什么二级缓存这些太高级了,平时也没用到,但是用了就要明白个所以然,自己揣摩着模仿写个小框架,但是没有研究过Hibernate是怎么写的,也不清楚系统的架构,凭借自己的感觉写的,很多地方理解上有错,很多代码写得也很垃圾,还没很多东西没有考虑到,比如当个表的映射关系,数据库外键的关联等等。希望各位大神给与一点点指点。
二、结构
1、Configuration:配置文件类,加载并解析配置文件,生成实例化的SessionFactory。
2、SessionFactory:接口,加载数据库驱动,生成Session放入SessionPool(池)中,提供Session。
>>具体实现:SessionFactoryImpl
3、Session:接口,提供事务管理,包含对象的增删改查,以及sql执行。
>>具体实现:SessionImpl
4、SQLBuilder:接口,创建增删改差的sql语句。可以针对不同的数据库设计不同的实现。
>>具体实现:Mysql SQLBuilder
三、使用
一个东西,要想明白他的原理,必须先要知道怎么使用:
- 创建Configuration对象:构造时加载配置文件。
- 使用Configuration对象创建一个SessionFactory对象:configuration.buildSessionFactory()。
- 获取Session。
- 使用session执行操作。
- 关闭session。
代码如下:
public static void main(String[] args) { //生成配置对象 Configuration configuration=new Configuration("dbtest/test/config.xml"); //生成Session工厂 SessionFactory sessionFactory=configuration.buildSessionFactory(); //获取Session Session session=sessionFactory.getSession(); Student student=new Student(); student.setSex("男"); student.setSname("德玛西亚"); student.setCollege("超神学院"); student.setSno("1212121"); //执行事务 session.add(student); //关闭Session session.colse(); }
四、实现
1、 Configuration类实现
/** * Configuration:参数配置类 * * @author ZWQ * @version 1.0 * <p> * 通过该类使用配置文件建立SessionFactory。 * </p> * **/ public class Configuration { //数据库驱动 private String driver = ""; //连接url private String url = ""; //用户名 private String user = ""; //密码 private String password = ""; //Session池初始大小 private int initsize = 5; //Session池最大大小 private int maxsize = 10; /** * 默认构造方法,使用项目根目录src下面的lfdb.config.xml文件 */ public Configuration() { initConfig("lfdb.config.xml"); } /** * 带参构造方法,使用项目自定义的.xml文件 * <p> * 根目录下使用为Configuration configuration=new Configuration("config.xml"); * </p> * <p> * 具体包下面使用为Configuration configuration=new Configuration("demo/config.xml"); * </p> * * @param configFile * :String 需要使用的lfdb配置文件 */ public Configuration(String configFile) { initConfig(configFile); } private void initConfig(String configFile) { try { // 获取配置文件输入流 InputStream configInputStream = getClass().getClassLoader().getResourceAsStream(configFile); if (configInputStream == null) { System.out.println(">>>>>>>配置文件未找到"); new FileNotFoundException(); } // XML文件解析 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setIgnoringComments(true); dbf.setIgnoringElementContentWhitespace(true); DocumentBuilder db = dbf.newDocumentBuilder(); System.out.println(">>>>>>>解析配置文件..."); Document document = db.parse(configInputStream); Element root = document.getDocumentElement(); NodeList config = root.getChildNodes(); // 读取配置参数内容 for (int i = 0; i < config.getLength(); i++) { Node node = config.item(i); String nodeName = node.getNodeName(); if (nodeName.equalsIgnoreCase("driver")) { driver = node.getFirstChild().getNodeValue().trim(); } else if (nodeName.equalsIgnoreCase("url")) { url = node.getFirstChild().getNodeValue().trim(); } else if (nodeName.equalsIgnoreCase("user")) { user = node.getFirstChild().getNodeValue().trim(); } else if (nodeName.equalsIgnoreCase("password")) { password = node.getFirstChild().getNodeValue().trim(); } else if (nodeName.equalsIgnoreCase("initsize")) { initsize = Integer.parseInt(node.getFirstChild().getNodeValue().trim()); } else if (nodeName.equalsIgnoreCase("maxsize")) { maxsize = Integer.parseInt(node.getFirstChild().getNodeValue().trim()); } } System.out.println(">>>>>>>配置文件解析完成"); } catch (Exception e) { e.printStackTrace(); new RuntimeException(); } } /** * 建立一个SessionFactory * * @return SessionFactory 返回一个SessionFactory的实例 * **/ public SessionFactory buildSessionFactory() { return new SessionFactoryImpl(this); }
2、 SessionFactoryImpl类实现
public class SessionFactoryImpl implements SessionFactory { // Session池 LinkedList<Session> sessionPool = new LinkedList<Session>(); // 与Configuration中参数相对应 private String driver; private String url; private String user; private String password; private int initsize; private int maxsize; // 当前Session池最大大小 private int currentsize; // 通过Configuration构造,并加载驱动,初始化Session池 public SessionFactoryImpl(Configuration configuration) { driver = configuration.getDriver(); url = configuration.getUrl(); user = configuration.getUser(); password = configuration.getPassword(); initsize = configuration.getInitsize(); maxsize = configuration.getMaxsize(); loadDriver(); for (int i = 0; i < initsize; i++) { createSession(); } } // 创建Session,放入Session池 private void createSession() { if (currentsize < maxsize) { try { Connection connection = DriverManager.getConnection(url, user, password); //当前只支持MySql语句的生成 SQLBuilder sqlBuilder = new MysqlSQLBuilder(); sessionPool.addLast(new SessionImpl(connection, sqlBuilder, sessionPool)); currentsize++; } catch (Exception e) { System.out.println(">>>>>>>创建Session出错"); e.printStackTrace(); } } else { System.out.println(">>>>>>>已超出Session配置最大容量"); } } // 加载数据库驱动 private void loadDriver() { System.out.println(">>>>>>>加载数据库驱动..."); try { // 加载数据库驱动. Class.forName(driver); System.out.println(">>>>>>>加载数据库驱动成功..."); } catch (ClassNotFoundException e) { System.out.println(">>>>>>>加载数据库驱动失败..."); e.printStackTrace(); new RuntimeException(); } } @Override public Session getSession() { synchronized (sessionPool) { if (this.sessionPool.size() > 0) { return this.sessionPool.removeFirst(); } else { createSession(); if (this.sessionPool.size() > 0) { return this.sessionPool.removeFirst(); } else { System.out.println(">>>>>>>>已经没有session"); return null; } } } } @Override public void closeSession(Session session) { sessionPool.addLast(session); session=null; } }
3、 SessionImpl类实现:部分代码
@Override public void add(Object object) { try { String sql = sqlBuilder.createAddSQL(object); Statement statement = connection.createStatement(); statement.executeUpdate(sql); } catch (Exception e) { System.out.println(">>>>>>>>添加对象失败"); e.printStackTrace(); } } @Override public <T> List<T> get(Class<T> clazz, String sql) { List<T> result = null; try { Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery(sql); BasicRowProcessor basicRowProcessor = new BasicRowProcessor(); result = basicRowProcessor.toBeanList(rs, clazz); } catch (SQLException e) { System.out.println(">>>>>>>获取结果出错"); e.printStackTrace(); } return result; }
4、 MysqlSQLBuilder类实现:部分代码
@Override public String createAddSQL(Object object) { StringBuilder sql = new StringBuilder(); StringBuilder columns = new StringBuilder(); StringBuilder values = new StringBuilder(); sql.append("insert into "); sql.append(object.getClass().getSimpleName()); try { Field[] fields = object.getClass().getDeclaredFields(); boolean firststate = false; for (Field field : fields) { field.setAccessible(true); if (field.getName().toString().toLowerCase().equals("id")) { continue; } if (firststate) { columns.append(","); values.append(","); } else { firststate = true; } String column = field.getName(); Object value = field.get(object); columns.append(column); if (field.getType() == String.class) { values.append("'"); values.append(value); values.append("'"); } else { values.append(value); } } sql.append("("); sql.append(columns); sql.append(") values("); sql.append(values); sql.append(")"); } catch (IllegalArgumentException | IllegalAccessException e) { System.out.println(">>>>>>>创建插入sql语句失败"); e.printStackTrace(); } return sql.toString(); }
五、总结
写一个框架是需要用心的事情,需要考虑到使用者的方便性,以及功能的完整性与健壮性。
这个只是一个半成品,很多地方还没有实现,bug也不少,性能就更加不要说了,写这个是为了学习,很多地方理解有误的,还望各路大神指出。
六、附件
项目文件夹:lfdb
下载地址:http://pan.baidu.com/s/1bn1Y6BX
如果有什么疑问或者建议,请联系我
文件说明:
1、lfdb源码.zip :lfdb的源代码
2、lfdb_1.2.jar :可以直接使用的jar包
3、lfdbdemo源码.zip :lfdb示例的源代码
封装JDBC:实现简单ORM框架lfdb的更多相关文章
- JDBC 利用反射技术将查询结果封装为对象(简单ORM实现)
ORM(Object Relational Mapping)对象关系映射 public class ORMTest { public static void main(String[] args) t ...
- JAVA描述的简单ORM框架
抽了点时间自己写了个ORM,主要是为了复习JAVA泛型,映射,注解方面的知识.如需代码,可前往:https://github.com/m2492565210/java_orm自行下载 框架的类结构如下 ...
- 常见ORM框架及JDBC操作工具类
在Java 程序里面去连接数据库,最原始的办法是使用JDBC 的API.我们先来回顾一下使用JDBC 的方式,我们是怎么操作数据库的. // 注册JDBC 驱动 Class.forName(" ...
- mybatis(一)常见ORM框架及JDBC操作工具类
转载:https://www.cnblogs.com/wuzhenzhao/p/11075569.html 在Java 程序里面去连接数据库,最原始的办法是使用JDBC 的API.我们先来回顾一下 ...
- PHP ORM框架与简单代码实现(转)
对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据 ...
- 重学 Java 设计模式:实战中介者模式「按照Mybaits原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同龄人的差距是从什么时候拉开的 同样的幼儿园.同样的小学.一样 ...
- 简单实用的Android ORM框架TigerDB
TigerDB是一个简单的Android ORM框架,它能让你一句话实现数据库的增删改查,同时支持实体对象的持久化和自动映射,同时你也不必关心表结构的变化,因为它会自动检测新增字段来更新你的表结构. ...
- 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
文件夹 [SSH进阶之路]一步步重构容器实现Spring框架--从一个简单的容器開始(八) [SSH进阶之路]一步步重构容器实现Spring框架--解决容器对组件的"侵入 ...
- .Net Core 简单定时任务框架封装
有段日子没有更新,写点东西冒个泡 .这篇文章过来讲个小东西,也是大家在日常开发中也经常需要面临的问题:后台定时任务处理.估计大家看到这句就已经联想到 QuartZ 等类似第三方类库了,不好意思,后边的 ...
随机推荐
- 关于HttpsURLConnection的连接问题
本地测试好的项目拿到服务器上后,通过SSL连接,将Http改成Https,并指定了服务器的IP,结果连接失败.查了资料后发现,直接指定IP,SSL是无法定位连接的,实际上应该指定服务器端配置好的Hos ...
- Android手机应用程序开发环境配置(Eclipse+Java+ADT)
参考: Java手机游戏开发实例简明教程 http://dev.10086.cn/blog/?uid-82940-action-viewspace-itemid-1772 Eclipse下载: htt ...
- Linux cat命令详解
本文主要内容源自网络,参考资料如下: 华夏名网,linux cat命令详解,http://www.sudu.cn/info/html/edu/20070101/290711.html 命令格式:cat ...
- 任意轴算法 ( Arbitrary Axis Algorithm )
已知三维空间中任意单位向量,求以该向量为Z轴的local正交坐标系: 如上图,每个模型都有自己local 坐标系,已知其中一个朝向求另外两个方向. 在autodesk中采用的是Arbitrary Ax ...
- zoj 3757 Alice and Bob and Cue Sports 月赛A 模拟
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3757 题意:根据所给的台球规则,按照每次的结果计算最终两人的得分 ...
- Goole音乐搜索
本博文的主要内容有 .Goole音乐搜索的介绍 1.Goole音乐搜索的介绍 https://zh.wikipedia.org/wiki/%E8%B0%B7%E6%AD%8C%E9%9F%B3% ...
- 关于日历控件My97DatePicker 在IE6下出现“无法打开站点,已终止操作”
1.My97DatePicker 官方:http://www.my97.net2.在IE6下出现“无法打开站点,已终止操作”的解决办法(转): .这是一个绝对有效的方法,但是会丢失跨越iframe的特 ...
- linux创建用户,指定组
本博客不再更新 该文章新链接移步:http://it.lovepet.vip/archives/7/ 一.创建用户: 1.使用命令 useradd 例:useradd test——创建用户test ...
- HTTP 返回时间 概念 TTFB..
课外学习部分: 什么是TTFB呢? 1.TTFB (Time To First Byte),是最初的网络请求被发起到从服务器接收到第一个字节这段时间,它包含了 TCP连接时间,发送HTTP请求时间和获 ...
- hadoop实例
一篇讲得很好的hadoop实例,非常适合初学者学习hadoop. 本文转载自:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.ht ...