<4>save
来源:互联网 发布:淘宝十大黑店 编辑:程序博客网 时间:2024/06/06 03:33
1. 前言:
看完了create操作,再看一个save操作,其实二者非常类似,最重要的初始化操作已经在Table.get即table对象初始化的时候完成了
2. Save
public voidsave(Object entity)throws DbException {
try{
beginTransaction();
createTableIfNotExist(entity.getClass());
execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(this,entity));
setTransactionSuccessful();
}finally {
endTransaction();
}
}
① createTableIfNotExist函数之前已近介绍过,没有表存在,则创建表
② qlInfoBuilder.buildInsertSqlInfo(this, entity)插入sql语句的获取
③ execNonQuery DbUtils中通用函数,用来执行sql语句(在createTableIfNotExist函数中也有介绍)
3. 插入sql语句的获取
public staticSqlInfo buildInsertSqlInfo(DbUtils db,Object entity) throwsDbException {
List<KeyValue> keyValueList = entity2KeyValueList(db,entity);
if (keyValueList.size() ==0)return null;
SqlInfo result =new SqlInfo();
StringBuffer sqlBuffer =new StringBuffer();
sqlBuffer.append("INSERT INTO ");
sqlBuffer.append(TableUtils.getTableName(entity.getClass()));
sqlBuffer.append(" (");
for (KeyValue kv : keyValueList) {
sqlBuffer.append(kv.key).append(",");
result.addBindArgWithoutConverter(kv.value);
}
sqlBuffer.deleteCharAt(sqlBuffer.length() -1);
sqlBuffer.append(") VALUES (");
int length = keyValueList.size();
for (inti = 0;i < length;i++) {
sqlBuffer.append("?,");
}
sqlBuffer.deleteCharAt(sqlBuffer.length() -1);
sqlBuffer.append(")");
result.setSql(sqlBuffer.toString());
return result;
}
① 感觉和create的sql获取操作类似,通过table对象拖出数据,进行拼接即可
② 先获取List<KeyValue> keyValueList,KeyValue(javaBean key= 变量名 value=变量值)
③ 拼接:
+ "INSERT INTO "
+ entity的className
+ " ("
+ keyValueList中所有的KEY(逗号隔开)(并把对应得VALUE放如SqlInfo对象)
+ 删除最后一个逗号
+ ") VALUES ("
+ 填写和KEY数量相当的"?,"
+ 删除最后一个逗号
+ ")"
1) 获取 变量名-值数组
public classSqlInfoBuilder
public staticList<KeyValue> entity2KeyValueList(DbUtils db,Object entity) {
List<KeyValue> keyValueList = new ArrayList<KeyValue>();
Class<?> entityType = entity.getClass();
Table table = Table.get(db,entityType);
Id id = table.id;
if (!id.isAutoIncrement()) {
Object idValue = id.getColumnValue(entity);
KeyValue kv =new KeyValue(id.getColumnName(),idValue);
keyValueList.add(kv);
}
Collection<Column> columns = table.columnMap.values();
for (Column column : columns) {
if(column instanceofFinder) {
continue;
}
KeyValue kv = column2KeyValue(entity,column);
if (kv !=null) {
keyValueList.add(kv);
}
}
returnkeyValueList;
}
① 先处理@id,Id不是自增的,则需要手动插入值
② 在处理columns,获取其键-值(先忽略Finder)
a. 先看columns的处理
Collection<Column> columns = table.columnMap.values();
for (Column column : columns) {
if(column instanceofFinder) {
continue;
}
KeyValue kv = column2KeyValue(entity,column);
if (kv !=null) {
keyValueList.add(kv);
}
}
① 遍历之前初始化在table对象中的columnMap
② 单个column的key-value获取column2KeyValue
private staticKeyValue column2KeyValue(Object entity,Column column) {
KeyValue kv = null;
String key = column.getColumnName();
if (key !=null) {
Object value = column.getColumnValue(entity);
value = value ==null ? column.getDefaultValue() : value;
kv =new KeyValue(key,value);
}
returnkv;
}
③ Key就不用说了,Field的name
④ Value的获取column.getColumnValue获取失败直接使用@column注释时填写的defaultValue,若没有填写默认值=“”
⑤ 实例化KeyValue(KEY=Feild的name,VALUE=变量值)对象
public Object getColumnValue(Object entity) {
Object fieldValue = getFieldValue(entity);
return columnConverter.fieldValue2ColumnValue(fieldValue);
}
⑥ getFieldValue 获取具体的值
public Object getFieldValue(Object entity) {
Object fieldValue = null;
if (entity !=null) {
if(getMethod!= null) {
try{
fieldValue = getMethod.invoke(entity);
}catch (Throwable e) {
LogUtils.e(e.getMessage(),e);
}
} else{
try{
this.columnField.setAccessible(true);
fieldValue =this.columnField.get(entity);
}catch (Throwable e) {
LogUtils.e(e.getMessage(),e);
}
}
}
returnfieldValue;
}
非常简单的两步获取:
调用gmethod(初始化column是赋值)获取;
获取失败,Feild.get强制获取
⑦ columnConverter初始化的类型辅助类,以int举例,直接返回了。
public classIntegerColumnConverter
public Object fieldValue2ColumnValue(Integer fieldValue) {
returnfieldValue;
}
b. @id的处理
public Object getColumnValue(Object entity) {
Object idValue = super.getColumnValue(entity);
if (idValue !=null) {
if(this.isAutoIncrement() && (idValue.equals(0) || idValue.equals(0L))) {
return null;
}else {
returnidValue;
}
}
return null;
}
可以看到和Column使用的方法一致,额外加了一个自己的关于isAutoIncrement的检查,防止错误的对自增变量的修改
4.执行Save 的Sql语句
public voidsave(Object entity)throws DbException {
try{
beginTransaction();
createTableIfNotExist(entity.getClass());
execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(this, entity));
setTransactionSuccessful();
}finally {
endTransaction();
}
}
- <4>save
- save
- Save
- save
- save
- save+
- save
- save
- save
- save
- save
- save
- save
- save
- save
- save
- 热迁移save分析(4)
- Julia: save 与 @save
- Hbase export and import
- Jquery如何给网页的title取值和赋值
- lnmp套件使用laravel一键包配置详解
- ERROR: In F:\PCLdon\VTK-7.0.0\Rendering\OpenGL2\vtkOpenGLRenderWindow.cxx, line 545 vtkWin32OpenGLRe
- 集合学习笔记
- <4>save
- android 自定义导航条
- 微信公众号开发过程及对微信公众号内容的认识
- 从数据库读取数据。在页面用表格显示,并实现隔行换色
- Nutch搜索引擎_ Nutch简介及安装
- BZOJ 1133 [POI2009]Kon
- keil提示仿真器SWD/JTAG Communication Failure的问题解决
- Android后台-登录实例(1)
- BoundsChecker是一个Run-Time错误检测工具,它主要定位程序在运行时期发生的各种错误;