ORM的全称是Object Relational Mapping,即对象关系映射。它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作。因此它的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。
有时基于工作需要,需要自己改写orm框架,orm核心技术还是java反射机制,泛型等。
package orm;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import util.JdbcUtils;
/**
*
* @author fengzb
*
* @param <T>
*/
public class Orm<T> {
/**
* 获得映射数据库后的一个装配好的实体对象bean
*
* @param sql
* @param clazz
* @return
* @throws Exception
*/
public T getBean(String sql, Class<T> clazz) throws Exception {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
String[] colNames = getColNames(rs);
T t = null;
if (rs.next()) {
t = clazz.newInstance();
callSetter(t, colNames, rs);
}
return t;
} finally {
JdbcUtils.free(rs, ps, conn);
}
}
/**
* 获得映射数据库后的装配好的实体对象bean List
*
* @param sql
* @param clazz
* @return
* @throws Exception
*/
public List<T> getBeanList(String sql, Class<T> clazz) throws Exception {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
String[] colNames = getColNames(rs);
List<T> objects = new ArrayList<T>();
while (rs.next()) {
T t = (T) clazz.newInstance(); //
callSetter(t, colNames, rs);
objects.add(t);
}
return objects;
} finally {
JdbcUtils.free(rs, ps, conn);
}
}
/**
* 获取要映射的数据库表的列名
* @param rs
* @return
* @throws Exception
*/
private String[] getColNames(ResultSet rs) throws Exception {
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
String[] colNames = new String[count];
for (int i = 1; i <= count; i++) {
colNames[i - 1] = rsmd.getColumnLabel(i);
}
return colNames;
}
/**
* 通过数据库表的列名加上‘set’,找到java bean类的set方法,利用反射机制进行装配
* @param object
* @param colNames
* @param rs
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws SQLException
*/
private void callSetter(T object, String[] colNames, ResultSet rs)
throws IllegalAccessException, InvocationTargetException,
SQLException {
Method[] ms = object.getClass().getMethods();
for (int i = 0; i < colNames.length; i++) {
String colName = colNames[i];
String methodName = "set" + colName;
for (Method m : ms) {
if (methodName.equalsIgnoreCase(m.getName())) {
m.invoke(object, rs.getObject(colName));
break;
}
}
}
}
}
数据库表和java bean的映射是通过数据库列名 映射到bean的属性名;
数据库表tb_users
CREATE
TABLE tb_user
(
userId INT NOT NULL AUTO_INCREMENT,
department VARCHAR(255),
division VARCHAR(255),
email VARCHAR(255),
employeeNo VARCHAR(255),
name VARCHAR(255),
passwordMD5 VARCHAR(255),
phone VARCHAR(255),
position VARCHAR(255),
state INT NOT NULL,
type INT NOT NULL,
PRIMARY KEY (userId)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8
java实体bean 类
package model;
public class User {
private String department;
private String division;
private String email;
private String employeeNo;
private String name;
private String passwordMD5;
private String phone;
private String position;
private int state;
private int type;
private int userId;
//get set 方法
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "User [userId=" + userId + ", department=" + department
+ ", division=" + division + ", email=" + email
+ ", employeeNo=" + employeeNo + ", name=" + name
+ ", passwordMD5=" + passwordMD5 + ", phone=" + phone
+ ", position=" + position + ", state=" + state + ", type="
+ type + "]";
}
}
测试类
package orm;
import java.util.List;
import model.User;
import org.junit.Test;
public class OrmTest {
@Test
public void ormTest() throws Exception{
Orm<User> orm = new Orm<User>();
User user= (User) orm.getBean("SELECT userId,department,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user",User.class);
System.out.println(user);
List<User> userList= orm.getBeanList("SELECT userId,department,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user",User.class);
for(User u : userList){
System.out.println(u);
}
}
}
仅仅通过数据库列名与bean属性名进行映射,比较简单,当数据库中列名与bean属性名不一致时,
可以通过别名解决
例如bean中为depart,数据库中为department
User user= (User) orm.getBean("SELECT userId ,department depart,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user",User.class);