用Java实现自己的数据库OR映射框架
OR框架翻译过来就是对象关系映射框架,一提起OR框架,马上就会想起大名鼎鼎的Hibernate,Ibatis,以及其他的一些对象关系映射框架,并惊叹它的神奇。在惊叹之余,不免会产生兴趣一探他们的实现原理。下面我们就一起来实现一个简单的OR框架。
首先,我们为什么要使用OR框架?虽然现在OOA,OOP的思想已经成为软件编程的主流思想,但是关系型数据库依然是最主流、效率最高的数据库。所以问题来了,如何将我们面向对象思想程序中产生的数据持久化到关系型数据库中呢?当然了,方法很多,最直接的就是使用sql语言将数据依照他们的关系存到数据库当中,但是这样实现起来非常麻烦,为了实现一个简单的功能,常常需要我们写上几百行的代码,费时又费力;也可以使用流行ORM框架,例如Hibernate,Ibatis等,事实上,大多数的中小型公司的确是使用Hibernate作为自己的首选。Hibernate是一个非常优秀的OR框架,它对JDBC进行了轻量级的封装,使我们可以随心所欲的使用面向对象的思想来操纵数据库。下面,我们就来探究一下如何实现一个简单的OR框架,完成与Hibernate相同的功能。
为了说明实现的中心思想,我们先略去细枝末节。对实现做出以下规则:
- VO对象的类名要对映数据库的表名,例:VO对象类名为User.java,则数据库表则为user;
- VO对象的成员变量名对映数据库表的字段名,例:User中的成员变量为id,name,birthday,则数据库user表中字段名称也必须为id,name,birthday;
- VO对象中成员变量的类型与数据库表中字段类型的对应关系为(我们使用的数据库为MYSQL数据库,请根据实际情况自定义规则):Integer对映int(8),Long对应int(16),Float对应float(10,2),Double对应double(16,4),Date对应timestamp,String对应text。
- VO对象中必须包括一个Integer类型的成员变量id,数据库中相映的字段名为id,类型为int(8),主键,自动增长。
这里我们只贴一些关键性的代码,整体项目我已经长传到csdn,大家可以另行下载。
首先我们建一个VO类:
package com.zzb;
import java.util.Date;
public class User {
private Integer id;
private Float value;
private String name;
private Date date;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Float getValue() {
return value;
}
public void setValue(Float value) {
this.value = value;
}
}
这个类有一个Integer类型的id,另外还有其他三个成员变量,以及相应的get/set方法,是一个标准的POJO。
根据我们的OR对应规则,数据库中对映的表名为user,表中的字段名和字段类型为
id int(8) auto_increment primary key
name text
value float(8,2)
date timestamp
然后,我们需要一个通用的DAO类,通用DAO包括5个方法(列出的方法为主要方法,并且方法体已省略),代码如下:
public class BaseDAO {
public int add(Object o) throws Exception{}
public int update(Object o) throws Exception{}
public int delete(Object o) throws Exception{}
public List query(Object o) throws Exception{}
}
类中的四个方法分别对对象进行增、改、删、查四个操作。
接下来是我们的核心类,这个类的主要任务就是根据对象的增删改查四种情况产生对应的SQL语句,然后通过SQL语句进行数据库操作,从而完成OR映射。代码如下:
public class StandardSQL {
public String add(Object o) throws Exception{}
public String update(Object o) throws Exception{}
public String delete(Object o) throws Exception{}
public String query(Object o) throws Exception{}
}
- add方法负责产生一个insert语句,运行add(user),则返回字符串:insert into user(name, value, date ) values('****', ****, '**********' );
- update方法负责产生一个update语句,运行update(user),则返回字符串:update user set name='****', value=***, date='*********' where id=*;
- delete方法负责产生一个delete语句,运行delete(user),返回字符串:delete from user where id=*;
- query方法负责产生一个query语句,运行query(user),返回字符串:select name, value, id, date from user where name like '%****%';
- 另外,为了方便建表,我们还需要一个create方法,用来产生建表语句,将user作为参数传入后返回字符串:create table if not exists user(id int(8) auto_increment, name text, value float(8,2), date timestamp, primary key(id))
以上就是我们核心类要完成的功能。
接下来,我们写一个连接数据库的类,对连接操作简单封装一下:
package com.zzb;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DB {
public Connection getConnection(){
Connection conn =null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/business", "root", "123");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public void releaseConnection(ResultSet rs,Statement stat,Connection conn){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
这里我的数据库名是business,用户名,密码分别是root和123,大家根据自己的情况自行修改,并且不要忘了引入mysql的jdbc。
最后我们建立一个test类测试一下是否成功。
package com.zzb;
import java.util.Date;
import java.util.List;
import org.junit.Test;
public class TestDB {
BaseDAO dao = new BaseDAO();
@Test
public void testcreate() throws Exception{
StandardSQL standardSQL = new StandardSQL();
String sql = standardSQL.create(new User());
System.out.println(sql);
dao.executeUpdate(sql);
}
@Test
public void testadd() throws Exception{
User user = new User();
user.setName("xiaohong");
user.setValue((float)45.60);
user.setDate(new Date());
dao.add(user);
}
@Test
public void testupdate() throws Exception{
User user = new User();
user.setId(1);
user.setName("xiaowang");
user.setValue((float)90.88);
user.setDate(new Date());
dao.update(user);
}
@Test
public void testquery() throws Exception{
User user = new User();
user.setName("xiaowang");
List<User> list = dao.query(user);
for(User u: list){
System.out.print(u.getId()+" ");
System.out.print(u.getName()+" ");
System.out.println(u.getDate());
}
}
@Test
public void testdel() throws Exception{
User user = new User();
user.setId(1);
dao.delete(user);
}
}
test类有5个方法,分别测试建表、插入、修改、查询、删除五个操作。
写到这里,我们已经看出,所谓的OR映射就是通过java的对象,使用反射得到对象的信息,然后产生SQL语句,再使用JDBC对数据库进行操作。在这个程序当中,我们没有做事务处理,没有使用连接池,没有做多表的映射,可移植性也做的不好,只是将一个简单的java对象持久化到数据库相应的表中,但作为一个练习,已经阐明了如何去实现自己的OR框架,希望各位看官读完以后能有所启发。写的不好,权当是抛砖引玉,欢迎各看官指点。
项目下载地址: 源码下载
用Java实现自己的数据库OR映射框架相关推荐
- MyBatis是持久化层框架(SQL映射框架)-操作数据库
MyBatis是持久化层框架(SQL映射框架)-操作数据库 1.环境搭建 1).创建一个java工程: 2).创建测试库,测试表,以及封装数据的javaBean,和操作数据库的dao接口 创建表:自己 ...
- 【MyBatis】Mybatis的java对象名和数据库表名不同怎么办?
java对象名 和 数据库表名 不同怎么办? 提问: 我想请教一下,在使用mybatis的注解的时候,如果出现java对象名和数据库表名不同的时候,如何写mapper. 比如,UserAccount是 ...
- 入门JAVA第十六天 数据库
一 .数据库技术学习内容与方法 1.1学习内容 1 Oracle 数据库 目前最好的关系型数据库 基本的CRUD命令. SQL语句.select(R),update(U),detele(D),inse ...
- java读取纯真IP数据库qqwry.dat的源代码
java读取纯真IP数据库QQwry.dat的源代码,要运行此程序必须有 到网上下载QQwry.dat,下载地址 http://www.cz88.net/down/ 由于太大,我这里就不提供了. ...
- java.sql.Types,数据库字段类型,java数据类型的对应关系
原文地址为: java.sql.Types,数据库字段类型,java数据类型的对应关系 以下转自:http://kummy.itpub.net/post/17165/172850 本文在原文基础上有增 ...
- Java EE :MySQL数据库MavenMybatis框架 知识汇总
目录 一.MySQL基础 01 - 数据库相关概念 1.1 什么是数据库? 1.2 什么是数据库管理系统? 1.3 常见的数据库管理系统 1.4 SQL 02 - MySQL 2.1 MySQL安装 ...
- 数据库decimal对应java什么类型_数据库类型和java类型对应关系 | 学步园
类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java.lang.String 12 CHAR N CHAR java. ...
- maven java项目 配置双数据库(多数据库配置)
前言 为什么要配置双数据库或者多数据库. 当你需要从两个或多个数据库进行获取数据库表的数据或者插入数据,每个数据库的数据库驱动(driver),url路径,用户名(username).密码(passw ...
- IDEA使用mybatis实现generator自动生成MSSQLSERVER数据库表映射
IDEA使用mybatis实现generator自动生成MSSQLSERVER数据库表映射,generatorConfig.xml文件中配置如下内容: <?xml version="1 ...
最新文章
- 为Linux用ISO制作U盘启动及基本原理
- TLE5012的使用和3线SPI通信(SSC)说明
- [Python]理解 if __name__ == ‘__main__‘
- EF修改对象里面的值。。。(对象字段多的时候)
- [阿里云]I+的一些探索
- python疑问5:位置参数,默认参数,可变参数,关键字参数,命名关键字参数区别...
- spring boot项目Intellij 打包
- 最短路中部分点只能从中任意选取K个问题
- 【汇编优化】之arm32汇编优化
- 北京联通光猫 F427 路由改桥接的方法
- 据说学编程的计算这题不超1分钟!
- !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtm...
- Java 平衡二叉树和AVL
- eclipse汉化完成常见问题的解决方案
- 计算机桌面设置上时间表,如何在电脑桌面设置显示星期
- Word恢复忘记保存的文件(打开任意.asd文件)
- [转]XXX无法访问。你可能没有权限使用网络资源
- 怎么把计算机隐藏文件显示出来,怎么把隐藏的文件夹显示出来
- 基于机智云平台的智能花盆
- AMBA协议之AXI协议——中文翻译
热门文章
- suricata之linux编译
- 歪嘴一笑百媚生,b站鬼畜无颜色,分析“歪嘴战神”那该死的魅力
- 2020年山西职称英语计算机,山西2020年起推行职称“电子证书”
- 给你的MuseUI应用添加字体、样式
- 社恐福音?这款 AI 教练应用可助力克服社交焦虑! #FACING IT
- SQL还原后:目录名称无效
- R-GAT实现基于方面级情感分析
- java犀牛书_一起来啃犀牛书:正则表达式
- ARIS流程平台简介(二)
- RabbitMQ work quene(工作队列模型) 1对n