用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 ...
最新文章
- 三星a5009Android6.0,三星A5009原版系统刷机包_三星A5009最新升级包线刷包和root
- Spring事务管理 与 SpringAOP
- opengl 大作业_「陪玩时光」糕妈:说说年糕的小学生活,先从陪作业和家长群聊起...
- Android版哆啦A梦连连看游戏源码完整版
- OpenGL学习之路(二)
- rabbitmq使用_Spring Boot中使用RabbitMQ
- Qt工作笔记-Qt creator如何生成dll,以及如何移植到vs上
- 线程实现的方式、多线程模型
- php如何从获取数据,如何从​​获取值并保存到php的数据库
- 在计算机网络GAN代表什么,图解 生成对抗网络GAN 原理 超详解
- (二)XGBoost之DART booster
- 小白初上手HTML+CSS 仿写小米官网logo动画
- markdown写html笔记,为知笔记 用markdown语言记漂亮的笔记
- python_操作MySQL 初解 之__类方法调用并 增-删-改-查
- 炉石一直显示连接服务器,炉石传说无法连接战网服务器怎么办 处理方法详解...
- REW声学测试(三):生成测试信号
- Mongodb访问控制
- python不支持的函数string_Python字符串string常用方法和函数
- 互联网未来30年发展的大趋势,专家:竞争会更激烈!
- java多人聊天室实现(可群聊私聊/添加好友/发送文件)
热门文章
- 呼吸灯代码linux,ESP32 开发笔记(三)源码示例 3_LEDC_PWM 使用LEDC实现LED呼吸灯
- Git 合并子模块改动没有出现 ‘merge following commits not found’
- Opencv学习笔记(六)图像形态学处理
- Ubuntu下U盘只读文件系统,图标上锁,提示无法修改
- dorado7.x UploadAction存在的诡异问题
- Elasticsearch进行and,or多条件组合DSL结构化查询
- 文档管理是什么?都有哪些?
- 集群智能-蚁群优化算法
- homestead 安装mysql8_Homestead 安装其它的PHP版本
- python中ln函数如何表示_Python math库 ln(x)运算的实现及原理