1.User类
import com.jfinal.plugin.activerecord.Model;
/**
* user model.
*/
@SuppressWarnings("serial")
public class User extends Model<User> {
public static final User dao = new User();
}
2. configPlugin(Plugins me)这里实例化一个ActiveRecordPlugin类,将数据库表明与实体类的映射保存到ActiveRecordPlugin类中
@Override
public void configPlugin(Plugins me) {
C3p0Plugin cp = new C3p0Plugin(Util.JDBC, Util.USER, Util.PASSWORD);
me.add(cp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(cp);
me.add(arp);
arp.addMapping("user", User.class);//将user(数据库表名)与User(模型类)映射关系保存到arp中
}
3.ActiveRecordPlugin类
将表-类映射封装到TableInfo中,并 用一个 List<TableInfo> tableMappings 保存
public ActiveRecordPlugin addMapping(String tableName, Class < ? extends Model < ? >> modelClass) {
tableMappings.add( new TableInfo(tableName, modelClass));
return this;
}
系统启动时用TableInfoBuilder类来实现表中具体元素和类的映射
public boolean start() {
if (isStarted)
return true;
if (dataSourceProvider != null)
dataSource = dataSourceProvider.getDataSource();
if (dataSource == null)
throw new RuntimeException( "ActiveRecord start error: ActiveRecordPlugin need DataSource or DataSourceProvider");
DbKit.setDataSource(dataSource); //设置数据库的具体实现(这里用的是mysql)使用了工厂设计模式
isStarted = true;
return TableInfoBuilder.buildTableInfo(tableMappings); //去实现具体的映射
}
4.TableInfoBuilder类
把数据库表的每个字段以及类型 映射到类
class TableInfoBuilder {
static boolean buildTableInfo(List <TableInfo > tableMappings) {
boolean succeed = true;
Connection conn = null;
try {
conn = DbKit.getDataSource().getConnection();
} catch (SQLException e) {
throw new ActiveRecordException(e);
}
TableInfoMapping tim = TableInfoMapping.me(); //最终保存表与类的映射,单例
for (TableInfo mapping : tableMappings) { //遍历之前保存映射的List
try {
TableInfo tableInfo = doBuildTableInfo(mapping, conn); //从数据库中读取到表的所有字段及类型,封装到TableInfo类中
tim.putTableInfo(mapping.getModelClass(), tableInfo);// 最终保存表与类的映射
} catch (Exception e) {
succeed = false;
System.err.println( "Can not build TableInfo, maybe the table " + mapping.getTableName() + " is not exists.");
throw new ActiveRecordException(e);
}
}
DbKit.close(conn);
return succeed;
}
/**
* 从数据库中读取到表的所有字段及类型,封装到TableInfo类中
*
**/
private static TableInfo doBuildTableInfo(TableInfo tableInfo, Connection conn) throws SQLException {
TableInfo result = tableInfo; //保存类的所有属性及类型
String sql = DbKit.getDialect().forTableInfoBuilderDoBuildTableInfo(tableInfo.getTableName());
Statement stm = conn.createStatement();
ResultSet rs = stm.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
for ( int i = 1; i < =rsmd.getColumnCount(); i ++) {
String colName = rsmd.getColumnName(i); //取得列表标题(类属性)
String colClassName = rsmd.getColumnClassName(i); //属性的type
if ( "java.lang.String".equals(colClassName)) {
// varchar, char, enum, set, text, tinytext, mediumtext, longtext
result.addInfo(colName, java.lang.String. class);
}
else if ( "java.lang.Integer".equals(colClassName)) {
// int, integer, tinyint, smallint, mediumint
result.addInfo(colName, java.lang.Integer. class);
}
else if ( "java.lang.Long".equals(colClassName)) {
// bigint
result.addInfo(colName, java.lang.Long. class);
}
// else if ("java.util.Date".equals(colClassName)) { // java.util.Data can not be returned
// java.sql.Date, java.sql.Time, java.sql.Timestamp all extends java.util.Data so getDate can return the three types data
// result.addInfo(colName, java.util.Date.class);
// }
else if ( "java.sql.Date".equals(colClassName)) {
// date, year
result.addInfo(colName, java.sql.Date. class);
}
else if ( "java.lang.Double".equals(colClassName)) {
// real, double
result.addInfo(colName, java.lang.Double. class);
}
else if ( "java.lang.Float".equals(colClassName)) {
// float
result.addInfo(colName, java.lang.Float. class);
}
else if ( "java.lang.Boolean".equals(colClassName)) {
// bit
result.addInfo(colName, java.lang.Boolean. class);
}
else if ( "java.sql.Time".equals(colClassName)) {
// time
result.addInfo(colName, java.sql.Time. class);
}
else if ( "java.sql.Timestamp".equals(colClassName)) {
// timestamp, datetime
result.addInfo(colName, java.sql.Timestamp. class);
}
else if ( "java.math.BigDecimal".equals(colClassName)) {
// decimal, numeric
result.addInfo(colName, java.math.BigDecimal. class);
}
else if ( "[B".equals(colClassName)) {
// binary, varbinary, tinyblob, blob, mediumblob, longblob
// qjd project: print_info.content varbinary(61800);
result.addInfo(colName, byte[]. class);
}
else {
int type = rsmd.getColumnType(i);
if (type == Types.BLOB) {
result.addInfo(colName, byte[]. class);
}
else if (type == Types.CLOB || type == Types.NCLOB) {
result.addInfo(colName, String. class);
}
else {
result.addInfo(colName, String. class);
}
// core.TypeConverter
// throw new RuntimeException("You've got new type to mapping. Please add code in " + TableInfoBuilder.class.getName() + ". The ColumnClassName can't be mapped: " + colClassName);
}
}
rs.close();
stm.close();
return result;
}
}
5.TableInfo类
保存着类的所有属性
columnTypeMap //map保存着类的属性以及属性的数据类型
modelClass
//类的具体class类(User.class)
private String tableName;//表名
private String primaryKey;//主键
private String secondaryKey = null;
@SuppressWarnings( "unchecked")
private Map <String, Class < ? >> columnTypeMap = DbKit.containerFactory.getAttrsMap(); // new HashMap<String, Class<?>>();
private Class < ? extends Model < ? >> modelClass;