轻量级Myjdbc框架

  源码地址:https://github.com/beijing-penguin/Myjdbc

  MVC项目中的具体使用方式,https://github.com/beijing-penguin/ucenter-web-manage.git

  我为什么要写这个Myjdbc?

  毕业后的一段时间一直在用hibernate,和mybatis框架,后来感觉这种框架太繁琐,比如,现在要用java读取客户给的一个excel表格,读取里面的数据后插入到数据库,这样一个小的需求,我都需要配置hibernate文件、配置mybatis的文件,对我来说,太麻烦了,因为我是懒人,不喜欢太多的东西。

  我记得有一次用hibernate框架管理多数据源的时候,出现一个问题,当第一个数据源的连接提交后,第二个提交就会报错,当时查过一些办法,但是任然很难快定位问题的根本原因。并且做开发以来,所用过第三方JDBC框架或多或少的会在某些业务上面变得有些很不灵活,或者说某个地方我需要去查很多资料才能用好这个框架,其次框架本身出现bug,也很难调试和改变源码。总之有关数据库的操作,已经不是一个框架能够很好地去解决的问题了,它需要的是一种思想,需要结合某种特定高度灵活的框架,作为底层基础,来适应不同的需求。于是基于要做好一个高度灵活可扩展易调试的框架或者是理顺一个开发这种变态业务的思想,也并非易事。。于是本人便开始了Myjdbc的研究之旅。

  聊聊我的Myjdbc

  我很高兴,我有一天在群里告知各位群友后,能够得到某些群友的反馈,说想研究一下(或者看看)我的框架。其实,如果说我的框架是需要"研究"后才能用的话,那么说明,我设计失败了。jdbc的框架,有那么多的人封装多,为什么我还要造轮子,我是个懒人,我更加不想造轮子,我想创新的是一个开发思想,或者说我只想快速开发,完成项目,然后喝着饮料,玩着手机坐在公司潇潇洒洒,即便出现bug,我也能秒秒钟定位问题的根本原因,并解决。那么为此MyJdbc诞生了,一个只属于自己框架,也是属于每个人自己的框架。。框架功能:数据库连接与数据库操作(增删改查),提供多数据源管理和多数据源下的弱事务操作(提交和回滚)。框架优点:轻量级高度灵活可扩展,可复用的组件,简单易用,可自行定义其他功能,非常方便的调试。框架缺点:1,不支持动态sql,2,暂时不支持分表分库,正在开发中......

  Myjdbc如何使用及有哪些特点

  建议,开发时,尽量拷贝源码到项目中使用。上线后稳定下来,可以考虑打包成Myjdbc.jar

  要了解清楚怎么去调试和如何使用,首先请看我设计的目录结构

  

anno里是注解类,

config是全局的jdbc的配置,任何配置都可以在这里定义,比如是否在执行sql前打印sql日志?

core包,就是封装了原始的jdbc操作,且任何操作类的方法都只有3个参数,

  JDBCProxy.java是一个动态代理类,使用方式可以如下面这段代码这么设计,当然,你可以改变代理类中的任何源码及设计来符合你的需求。

@Controller
@RequestMapping("/user")
public class LoginController {
  private LoginService loginService = JDBCProxy.getInstance().getTarget(LoginService.class);

   @RequestMapping("/login")
    public String login(User user,HttpSession session,HttpServletRequest req) throws Exception{
        User u = loginService.login(user);

      

    }
}
package com.dc.module.system.service;

import java.util.List;
import java.util.Map;

import org.dc.jdbc.anno.Transactional;
import org.dc.jdbc.helper.DBHelper;

import com.dc.commons.config.Configure;
import com.dc.commons.entity.User;

public class LoginService {
    
    private DBHelper accountDBHelper = new DBHelper(Configure.accSource);
    
    public User login(User user) throws Exception{
        User u = accountDBHelper.selectOne("$login.getOneUser",User.class,user);
        return u;
    }
}

 

        

比如下面这段DeleteOper.java的源码,

/**
 * 删除操作
 * @author dc
 * @time 2015-8-17
 */
public class DeleteOper extends OperSuper{
    private static DeleteOper deleteOper = new DeleteOper();
    public static DeleteOper getInstance(){
        return deleteOper;
    }
	public  int delete(Connection conn,String sql,Object[] params) throws Exception{
		return super.preparedAndExcuteSQL(conn, sql, params);
	}
}

如果我封装的这段代码还不满足你的公司的项目需求,请自行写个方法,但是有且只有3个参数,如果3个参数不够,请及时给我反馈,并说明原因。

entity包,是作为sql元素相关信息的临时媒介。比如可以用来保存sql字符串和这个字符串所对象参数数组。

因为java语法并不支持执行一个方法,返回两个参数,就像这样的形式Object sql,param = getUser()这样的形式(lua语言支持)。

hepler包,就相当于最表面的应用级的工具,可以理解为view层。作为将底层方法透明可见的一种方式

init包。则为jdbc在前可以选择性执行init初始化的操作工具类在这个包下,比如需要加载xml文件中定义好的sql文件

utils包下面,目前主要定义的有反射获取方法名,java类型匹配及转化等工具。

 

使用案例如下面这段代码

 

package test;

import java.io.File;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dc.jdbc.config.JDBCConfig;
import org.dc.jdbc.core.ConnectionManager;
import org.dc.jdbc.helper.DBHelper;
import org.dc.jdbc.init.LoadSqlUtil;
import org.junit.Before;
import org.junit.Test;

import com.alibaba.druid.util.JdbcUtils;

public class JDBCTest {
	private static DBHelper accDBHelper = new DBHelper(Configure.accSource);
	private static DBHelper testDBHelper = new DBHelper(Configure.testSource);
	@Before
	public void initJdbc(){
		try {
			JDBCConfig.isPrintSqlLog = true;
			LoadSqlUtil.loadSql("D:\\Git\\MyJdbc\\target\\classes\\test\\sql");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	@Test
	public void select(){
		try {
			ConnectionManager.isTransaction.set(false);
			/*start*/
			Map<String,Object> map = testDBHelper.selectOne("select * from user limit 1");
			List<Map<String,Object>> mapList = testDBHelper.selectList("select * from user");
			/*end*/
			Map<String,Object> map_WithParam1 = testDBHelper.selectOne("select * from user where name=? and age=? limit 1","dc",20);
			User user = testDBHelper.selectOne("select name,age from user where name=? and age=? limit 1",User.class,"dc",20);
			//只返回年龄,如数据的该字段没查到则返回的数据为null,那么用Integer类型接受即可,不然会报NullPointerException
			//int age = testDBHelper.selectOne("select age from user where name=? and age=? limit 1",Integer.class,"dc",20);
			Integer age = testDBHelper.selectOne("select age from user where name=? and age=? limit 1",Integer.class,"dc",20);
			String name = testDBHelper.selectOne("select name from user where name=? and age=? limit 1",String.class,"dc",20);
			Map<String,Object> map_WithParam1_1 = testDBHelper.selectOne("select * from user where name=? and age=? limit 1",new Object[]{"dc",20});
			
			//传入Map
			Map<String,Object> mapParams = new HashMap<String, Object>();
			mapParams.put("name", "dc");
			mapParams.put("age", 12);
			Map<String,Object> map_WithParam1_2 = testDBHelper.selectOne("select * from user where name=#{name} and age=#{age} limit 1",mapParams);
			Map<String,Object> map_WithParam1_2_1 = testDBHelper.selectOne("$user.getOneUser",mapParams);
			
			//传入对象,也可以对象和Map一起作为参数传入方法
			User userObj = new User();
			userObj.setName("dc");
			userObj.setAge(12);
			Map<String,Object> map_WithParam1_3 = testDBHelper.selectOne("select * from user where name=#{name} and age=#{age} limit 1",userObj);
			List<Map<String,Object>> mapList_withParam1 = testDBHelper.selectList("select * from user");
			List<User> mapList_withParam1_1 = testDBHelper.selectList("select name,age from user",User.class);
			List<String> mapList_withParam1_2 = testDBHelper.selectList("select name from user",String.class);
			List<Integer> mapList_withParam1_3 = testDBHelper.selectList("select name from user",Integer.class);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			ConnectionManager.closeConnection();
		}
	}
	@Test
	public void insert(){
		//开启事务
		ConnectionManager.isTransaction.set(true);
		try {
			testDBHelper.insert("insert into user(name,age) values(?,?)", "dc",12);
			//提交
			ConnectionManager.commit();
		} catch (Exception e) {
			e.printStackTrace();
			ConnectionManager.rollback();
		}finally{
			ConnectionManager.closeConnection();
		}
	}
}

 

转载于:https://www.cnblogs.com/momo-note/p/5397485.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、SBORM 介绍 1、目前只考虑支持 mysql; 2、基于spring jdbc的上层封装,底层jdbc操作基于JdbcTemplate,对于使用spring jdbc的人会有一点价值,比较简洁的封装可以节省很多重复劳动,具体节省多少可以看看example; 3、实现一套简单的ORM(直接使用spring rowmapper,insert自己实现),可以基于对象进行crud和相对复杂(感觉比hibernate强大一点)的sql操作; 4、基于对象指定查询的字段,大部分时候可以忘掉表结构进行业务开发; 5、支持简单的数据库路由,读写分离(半自动,需要指定取writer还是reader,默认规则reader采用随机的方式,当然也可以手动指定); 6、支持简单的分表,主要是针对一定规则的分表,比如百分表、千分表,也可以自己指定分表后缀; 7、简单的单表查询(比如所有条件是and或者or结构),基本实现0sql代码编写(类似HibernateTemplate selectByExample、findByCriteria、find等方法); 8、简单的单表排序支持,支持多个排序条件组合; 9、对于复杂的sql查询,提供获取jdbctemplate实例进行操作,类似spring jdbc的常规用法; 10、提供Entity代码生成接口,Entity并非简单的pojo(尽可能不要去修改此类),引入字段常量类,方便查询的时候指定选择字段,从而更好实现查询条件的封装; 二、为什么写SBORM? 1、hibernate:过于臃肿,使用不够灵活,优化难(其实主要是因为很少用),HQL感觉就是个渣,在 mysql几乎一统天下的背景下,跨数据库级别的兼容吃力不讨好。Hibernate的对象化关联处理确实挺强大,但是使用起来坑太多,有多少人敢在项目 中大范围使用真不知道,屠龙刀不是人人都提的起啊。 2、mybatis:轻量级,基于xml的模式感觉不利于封装,代码量不小,基于xml维护也麻烦(个人观点, 现在注解模式貌似也挺不错),感觉mybatis更适合存在dba角色的年代,可以远离代码进行sql调优,复杂的查询拼装起来也更加优雅(java基本 就是if else ...),但是对于查询业务简单但是数据库集群环境的场景有点憋屈(其实对mybatis使用也不多,瞎评论^_^)。 3、spring jdbc:小巧,灵活,足够优秀,个人比较喜欢使用,但是代码量偏大,原生的接口重复劳动量大,比如insert、mapper之类的; SBORM只是针对spring jdbc的一些不方便的地方,做了一些封装,更加简化日常的开发工作,基于spring jdbc的RowMapper自动实现对象映射,也勉强算的上叫ORM,只是大部分功能已经由spring jdbc实现了。 平时不太喜欢使用hibernate和mybatis,主要是使用spring jdbc,写这个东西的出发点主要是平时使用spring jdbc觉 得比较麻烦,重复性的代码偏多,一方面通过自动mapper降低返回结果处理工作量,另一方面参考hibernate对象化查询条件的模式,写了一个 QueryBudiler,使得更多简单的单表查询可以通过对象组织查询、更改逻辑,避免过多去写相似性的SQL语句,减少DAO接口量。 三、一些亮点 1、Entity的设计:很多人看了也许会说,这个不是POJO,不是纯粹的Java Bean,显得很另类。但是有多人在开发过程中(特别是在写sql的时候),经常要去看看表结构设计?还有多少次因为改了表某个字段,还得遍历去查找哪些 sql使用了这个字段?多少次看到在代码中直接传入字段名作为查询参数感到别扭?如果将表结构字段都用java对象去描述,能够解决这些问题,就不必要在 乎是不是POJO了,后面看example的时候应该能体会这么做的一些好处,至少我觉得是挺方便的,将大部分查询脱离表结构设计。 2、简单的数据库路由:如果分库结构不是太复杂(比如简单的读写分离、或者多个库集成),BaseDao可以自 动进行路由(比如读写分离,根据业务模式指定读、写库),如果非默认的路由规则,也可以通过手动设置的模式,进行数据库路由。数据库路由直接由 Entity指定,所有的路由都是根据Entity识别,也就是说查询也是围绕Entity展开的,避免类似使用spring jdbc的时候,各种 template实例跳来跳去,硬编码引入,写一个业务还得看看到底该用哪个template,尤其是多个数据库共用一个template实例的时候。 3、QueryBuilder:单表查询基本上都可以实现零Sql(除非查询条件特别复杂的),更新、删除等操作也可以通过QueryBuilder进行批量处理,不局限于根据主键来处理。 4、分表操作的支持:对于分表操作和常规的使用没有区别,只是指定分表规则,mybatis好像也可以通过制定参数实现分表处理,没搞清楚hibernate对这个是怎么处理的(hibernate好像是bean和表一对一绑定的)? 标签:sborm

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值