Model.findFirst封装不在sql中写表名的方法

[背景]

jfinal的activeModel的model类默认提供了findFirst方法,一般的使用方法如下

employeePhotoFaceDao.findFirst("select * from employee_photo_face where id=?");

使我不满意的是需要在sql中添加表名 employee_photo_face,能不能不添加这个表名呢?

[分析]

jfinal在启动是使用_MappingKit 建立的映射

public class _MappingKit {
	
  public static void mapping(ActiveRecordPlugin arp) {
    arp.addMapping("employee", "id", Employee.class);
    arp.addMapping("employee_department", "id", EmployeeDepartment.class);
    arp.addMapping("employee_group", "id", EmployeeGroup.class);
    arp.addMapping("employee_photo_face", "id", EmployeePhotoFace.class);
    arp.addMapping("employee_type", "id", EmployeeType.class);
    arp.addMapping("sys_user", "id", SysUser.class);
  }
}

可以使用TableMapping.me().getTable(modelClass); 获取表名

剩下的就是泛型的问题了

[封装]

最终封装的代码如下

package com.litong.jfinal.service;

import com.jfinal.aop.Aop;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;
import com.litong.modules.face.recognize.common.model.EmployeePhotoFace;

/**
 * @author litong
 * @date 2020年9月29日_上午8:14:51 
 * @version 1.0 
 * @param <M>
 * @desc
 */
public class ActiveRecoredService {

// 第一版
//  public EmployeePhotoFace findFirst(String select, String where, Class<EmployeePhotoFace> class1) {
//    return null;
//  }

// 第二版
//  public <T>T findFirst(String select, String where, Class<T> class1) {
//    return null;
//  }
// 第三版
//  public <T> T findFirst(String select, String where, Class<? extends Model> class1) {
//    return null;
//  }
  // 第 四 版
  public <M extends Model<M>> M findFirst(String select, String where, Class<M> modelClass, Object... paras) {
    Table table = TableMapping.me().getTable(modelClass);
    M m = Aop.get(modelClass);
    return m.findFirst(select + " " + "from " + table.getName() + " " + where, paras);
  }

  public static void main(String[] args) {
    ActiveRecoredService activeRecoredService = Aop.get(ActiveRecoredService.class);
    EmployeePhotoFace e = activeRecoredService.findFirst("select ", "where id=1", EmployeePhotoFace.class);
  }
}

测试

  public void testModel() {
    // ar 应 设置成类变量
    ActiveRecoredService ar = Aop.get(ActiveRecoredService.class);
    EmployeePhotoFace findFirst = ar.findFirst("select *", "where id=?", EmployeePhotoFace.class, 1);
    JsonBean<EmployeePhotoFace> jsonBean = new JsonBean<>(findFirst);
    renderJson(jsonBean);
  }

测试成功

评论区

sioui

2020-09-29 15:05

写这么多代码不累吗?

doubuxingle

2020-09-29 15:13

有点麻烦, 既然表名都省了,为什么不把select ,where 都去掉。。 这实用性也不强啊

JFinal

2020-09-29 15:57

保留了表名,一是为了 sql 完整性,sql 可读性会好点。二是减少 string 拼接能提升点性能

在做这个功能的时候去除表名当然是可以的,最终是权衡后的选择

杜福忠

2020-09-29 18:37

PS简写的有:
User user = User.dao.findByIdLoadColumns(123, "age");
User user = User.dao.findByIdLoadColumns(new Object[]{123, 456}, "name, age");

李通

2020-09-29 19:04

@JFinal 谢谢波总肯定 @杜福忠 我公司的表,字段都很多,很少有查询单条记录册场景

l745230

2020-09-30 08:42

讲道理,字段多,更不能去省略表名. 实际编码中直接把sql复制出来去调试不香吗,这种封装还要去找model找对应的表名,在拼接起来.
曾经用过这种封装.只能说无力吐槽. 效率那是一点没提高,调试难度繁琐,不好用.

李通

2020-09-30 08:54

@l745230 你是正确的 @杜福忠 你是正确的 我错了,不应该写这种代码

杜福忠

2020-09-30 09:10

@李通 业务框架封装没有对错吧,可能是大家没有触及你的业务感觉不到便利

快乐的蹦豆子

2020-10-09 11:28

无法理解

JJfinal

2020-10-17 09:42

@l745230 赞同,通常数据异常时都是复制SQL调试