背景
最近正在整理之前基于mybatis的半ORM框架。原本的框架底层类ORM操作是通过StringBuilder的append拼接的,这次打算用JsqlParser重写一遍,一来底层不会存在太多的文本拼接,二来基于其他开源包维护难度会小一些,最后还可以整理一下原有的冗余方法。
这两天整理insert相关的方法,在将对象插入数据库后,期望是要返回完整对象,并且包含实际的数据库id。
基础相关框架为:spring、mybatis、hikari。
底层调用方法
最底层的做法实际上很直白,就是利用mybatis执行最简单的sql语句,给上代码。
@Repository("baseDao") public class BaseDao extends SqlSessionDaoSupport { private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 最大的单次批量插入的数量 */ private static final int MAX_BATCH_SIZE = 10000; @Override @Autowired public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { super.setSqlSessionFactory(sqlSessionFactory); } /** * 根据sql方法名称和对象插入数据库 */ public Object insert(String sqlName, Object obj) throws SQLException { return getSqlSession().insert(sqlName, obj); // 此处直接执行传入的xml中对应的sql id,以及参数 } }
单个对象插入
java代码
/** * 简单插入实体对象 * * @param entity 实体对象 * @throws SQLException */ public <T extends BaseEntity> T insertEntity(T entity) throws SQLException { Insert insert = new Insert(); insert.setTable(new Table(entity.getClass().getSimpleName())); insert.setColumns(JsqlUtils.getColumnNameFromEntity(entity.getClass())); insert.setItemsList(JsqlUtils.getAllColumnValueFromEntity(entity,insert.getColumns())); Map<String, Object> param = new HashMap<>(); param.put("baseSql", insert.toString()); param.put("entity", entity); this.insert("BaseDao.insertEntity", param); return entity; }
xml代码
<insert id="insertEntity" parameterType="java.util.Map" useGeneratedKeys="true" keyProperty="entity.id"> ${baseSql} </insert>
其他的就不多说了,这里针对如何返回已经入库的id给个说明。
在xml的 insert 标签中,设置 keyProperty 为 对应对象的id字段,和 insert(sqlName, obj) 这个方法中的 obj 是对应的。
这里一般有两种情况:
直接保存实体的对象作为参数传入(给伪代码示例)
SaveObject saveObject = new SaveObject(); // SaveObject中包含字段soid,作为自增id saveObject.setName("my name"); saveObject.setNums(2); getSqlSession().insert("saveObject.insert",saveObject);
这种情况实际就是传入了待保存的对象。这时候我们的xml应该这样
<insert id="insert" parameterType="SaveObject " useGeneratedKeys="true" keyProperty="soid"> insert into save_object (`name`,nums) values (#{names},#{nums}) </insert>
这里我们传入了SaveObject实体对象作为参数,所以我们的 keyProperty 就是parameter的id对应的字段,在这里就是 soid 。
多个对象,实体对象作为其中一个对象传入
Map<String, Object> param = new HashMap<>(); param.put("baseSql", insert.toString()); param.put("entity", entity); // 此处对应实体作为map的第二个参数传入 this.insert("BaseDao.insertEntity", param);
<insert id="insertEntity" parameterType="java.util.Map" useGeneratedKeys="true" keyPro<em style="color:transparent">本文来源[email protected]搞@^&代*@码)网9</em>perty="entity.id"> ${baseSql} </insert>