Java簡易ORMフレームワークに基づく実装(一)
ORMのフルネームはObject Relational Mapping、すなわちオブジェクト関係マッピングです.その実現思想は,リレーショナル・データベースにおけるテーブルのデータをオブジェクトにマッピングし,オブジェクトの形で示すことであり,開発者はデータベースに対する操作をこれらのオブジェクトに対する操作に変換することができる.そのため,開発者がオブジェクト向けの考え方でデータベースの操作を容易にすることを目的としている.
仕事のニーズに基づいて、ormフレームワークを自分で書き換える必要がある場合があります.ormコア技術はjava反射メカニズム、汎用などです.
データベーステーブルとjava beanのマッピングは、データベース列名を介してbeanにマッピングされる属性名です.
データベーステーブルtb_users
JAvaエンティティbeanクラス
テストクラス
データベースのカラム名とbean属性名だけでマッピングするのは簡単で、データベースのカラム名とbean属性名が一致しない場合、
エイリアスによる解決
たとえばbeanではdepart、データベースではdepartment
仕事のニーズに基づいて、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);