{"id":16439299,"url":"https://github.com/lanux/hbatis","last_synced_at":"2026-05-15T00:35:24.811Z","repository":{"id":68670074,"uuid":"103205608","full_name":"lanux/hbatis","owner":"lanux","description":"基于mybatis的crud解决方案","archived":false,"fork":false,"pushed_at":"2017-09-12T05:52:05.000Z","size":291,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-02T02:03:53.206Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lanux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-12T01:16:22.000Z","updated_at":"2019-08-14T13:52:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"9db1b7d0-f730-409f-bb64-89127d8ad6b9","html_url":"https://github.com/lanux/hbatis","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lanux%2Fhbatis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lanux%2Fhbatis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lanux%2Fhbatis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lanux%2Fhbatis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lanux","download_url":"https://codeload.github.com/lanux/hbatis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240757046,"owners_count":19852685,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T09:08:49.405Z","updated_at":"2026-05-15T00:35:19.764Z","avatar_url":"https://github.com/lanux.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hbatis\n\u003e 基于mybatis的crud解决方案\n\n\n## hbatis是什么\n\n\u003e 建立在mybatis之上的 单表通用操作（新增、修改、删除、按字段查、按字段更新等）。减小重复性的、逻辑简单的xml配置，在不侵入mybatis的成本下，以几乎等同的代码量，\n完成单表的CRUD操作，可通过代码构建Statement。大大提高代码的可维护性。\n\n## hbatis的由来\n\u003e- mybatis generator 生成的代码及xml十分臃肿 及难以维护。\n\u003e- mybatis generator 生成的代码功能较弱 且 xml几乎不可复用\n***\n# 开始之旅\n## POM.xml\n```xml\n\u003cdependency\u003e\n\t\u003cgroupId\u003eorg.mybatis.hbatis\u003c/groupId\u003e\n\t\u003cartifactId\u003ehbatis-spring\u003c/artifactId\u003e\n\t\u003cversion\u003e2.0\u003c/version\u003e\n\u003c/dependency\u003e \n```    \n## 配置文件\n ### 不使用hbatis\n ```xml\n \u003cbean id=\"sessionManager\" class=\"org.mybatis.spring.support.SqlSessionDaoSupport\" lazy-\n      init=\"false\" scope=\"singleton\"\u003e\n\t\t  \u003cproperty name=\"sqlSessionFactory\" ref=\"sqlSessionFactory\"\u003e\u003c/property\u003e\n \u003c/bean\u003e\n```\n ### 使用hbatis\n ```xml\n  \u003cbean id=\"sessionManager\" \n         class=\"org.mybatis.hbatis.spring.HbatisSqlSessionDaoSupport\" lazy-\n         init=\"false\" scope=\"singleton\"\u003e\n\t\u003cproperty name=\"sqlSessionFactory\" ref=\"sqlSessionFactory\"\u003e\u003c/property\u003e\n  \u003c/bean\u003e\n```\n \u003e 如此即开启了hbatis支持，是不是 So easy ?!\n \n ## Entity\n ```Java\n @Table(OrgInfo.EntityNode.class)\npublic class OrgInfo implements Serializable {\n\t\n\tprivate static final long serialVersionUID = 1L;\n\t/**\n\t  * ID\n\t  * nullable:true,length:11\n\t  */\n\t@Column(primaryKey = true,autoIncrement = true,comment = \"ID\")\t\n\tprivate Integer id;\n\t/**\n\t  * \n\t  * nullable:false,length:32\n\t  */\n\t@Column(comment = \"\")\t\n\t@NotNull\n\tprivate String code;\n\t/**\n\t  * \n\t  * nullable:false,length:128\n\t  */\n\t@Column(comment = \"\")\t\n\t@NotNull\n\tprivate String secret;\n\t/**\n\t  * 名称\n\t  * nullable:false,length:64\n\t  */\n\t@Column(comment = \"名称\")\t\n\t@NotNull\n\tprivate String name;\n\t/**\n\t  * 图片\n\t  * nullable:true,length:256\n\t  */\n\t@Column(comment = \"图片\")\t\n\tprivate String imgSrc;\n\t/**\n\t  * 类型(1:个人,2:机构,3:机关单位,4:企业)\n\t  * nullable:false,length:11\n\t  */\n\t@Column(comment = \"类型(1:个人,2:机构,3:机关单位,4:企业)\")\t\n\t@NotNull\n\tprivate Integer type;\n\t/**\n\t  * 官网\n\t  * nullable:true,length:250\n\t  */\n\t@Column(comment = \"官网\")\t\n\tprivate String website;\n\t/**\n\t  * 地址\n\t  * nullable:true,length:250\n\t  */\n\t@Column(comment = \"地址\")\t\n\tprivate String address;\n\t/**\n\t  * 电话\n\t  * nullable:true,length:32\n\t  */\n\t@Column(comment = \"电话\")\t\n\tprivate String tel;\n\t/**\n\t  * 邮箱\n\t  * nullable:true,length:64\n\t  */\n\t@Column(comment = \"邮箱\")\t\n\tprivate String email;\n\t/**\n\t  * 联系人\n\t  * nullable:true,length:32\n\t  */\n\t@Column(comment = \"联系人\")\t\n\tprivate String contactor;\n\t/**\n\t  * 状态\n\t  * nullable:false,length:4\n\t  */\n\t@Column(comment = \"状态\")\t\n\t@NotNull\n\tprivate Byte status;\n\t/**\n\t  * 备注\n\t  * nullable:true,length:500\n\t  */\n\t@Column(comment = \"备注\")\t\n\tprivate String remark;\n\t/**\n\t  * \n\t  * nullable:false,length:19\n\t  */\n\t@Column(comment = \"\")\t\n\t@NotNull\n\tprivate Date opOn;\n\t/**\n\t  * \n\t  * nullable:false,length:11\n\t  */\n\t@Column(comment = \"\")\t\n\t@NotNull\n\tprivate Integer opBy;\n        \n\t... get and set \n\n    public static class EntityNode extends AbstractEntityNode\u003cOrgInfo\u003e {\n        public static final EntityNode INSTANCE = new EntityNode(\"toi\");;\n    \t/** ID */\n        public FieldNode\u003cOrgInfo, Integer\u003e id =  createFieldNode(\"id\",\"id\",Integer.class,JdbcType.INTEGER);\n    \t/**  */\n        public FieldNode\u003cOrgInfo, String\u003e code =  createFieldNode(\"code\",\"code\",String.class,JdbcType.VARCHAR);\n    \t/**  */\n        public FieldNode\u003cOrgInfo, String\u003e secret =  createFieldNode(\"secret\",\"secret\",String.class,JdbcType.VARCHAR);\n    \t/** 名称 */\n        public FieldNode\u003cOrgInfo, String\u003e name =  createFieldNode(\"name\",\"name\",String.class,JdbcType.VARCHAR);\n    \t/** 图片 */\n        public FieldNode\u003cOrgInfo, String\u003e imgSrc =  createFieldNode(\"imgSrc\",\"img_src\",String.class,JdbcType.VARCHAR);\n    \t/** 类型(1:个人,2:机构,3:机关单位,4:企业) */\n        public FieldNode\u003cOrgInfo, Integer\u003e type =  createFieldNode(\"type\",\"type\",Integer.class,JdbcType.INTEGER);\n    \t/** 官网 */\n        public FieldNode\u003cOrgInfo, String\u003e website =  createFieldNode(\"website\",\"website\",String.class,JdbcType.VARCHAR);\n    \t/** 地址 */\n        public FieldNode\u003cOrgInfo, String\u003e address =  createFieldNode(\"address\",\"address\",String.class,JdbcType.VARCHAR);\n    \t/** 电话 */\n        public FieldNode\u003cOrgInfo, String\u003e tel =  createFieldNode(\"tel\",\"tel\",String.class,JdbcType.VARCHAR);\n    \t/** 邮箱 */\n        public FieldNode\u003cOrgInfo, String\u003e email =  createFieldNode(\"email\",\"email\",String.class,JdbcType.VARCHAR);\n    \t/** 联系人 */\n        public FieldNode\u003cOrgInfo, String\u003e contactor =  createFieldNode(\"contactor\",\"contactor\",String.class,JdbcType.VARCHAR);\n    \t/** 状态 */\n        public FieldNode\u003cOrgInfo, Byte\u003e status =  createFieldNode(\"status\",\"status\",Byte.class,JdbcType.TINYINT);\n    \t/** 备注 */\n        public FieldNode\u003cOrgInfo, String\u003e remark =  createFieldNode(\"remark\",\"remark\",String.class,JdbcType.VARCHAR);\n    \t/**  */\n        public FieldNode\u003cOrgInfo, Date\u003e opOn =  createFieldNode(\"opOn\",\"op_on\",Date.class,JdbcType.TIMESTAMP);\n    \t/**  */\n        public FieldNode\u003cOrgInfo, Integer\u003e opBy =  createFieldNode(\"opBy\",\"op_by\",Integer.class,JdbcType.INTEGER);\n\t\n        /**\n         * @param alias 别名\n         */\n        public EntityNode(String alias) {\n            super(OrgInfo.class,\"t_org_info\",alias);\n        }\n    }\n    \n    // ==== 自定义属性 ====\n}\n```\n \n ## DAO\n \u003e 继承HbatisMapper\n ```Java\n /**\n * OrgInfoMapper\n * @author generator\n * @date 2017年07月11日\n */\npublic interface OrgInfoMapper extends HbatisMapper\u003cOrgInfo, Integer\u003e {\n\t\n\t\n\t//-- 按实体参数查询[START] \n\tList\u003cOrgInfo\u003e findByQueryParam(@Param(\"queryParam\")OrgInfo.QueryParam queryParam);\n\t\n\tlong countByQueryParam(@Param(\"queryParam\")OrgInfo.QueryParam queryParam);\n\t//-- 按实体参数查询[END] \n\t\n\t//-- 自定义业务方法，请写在下方 --\u003e\n}\n```\n## Service \n\u003e 在Service 中调用Mapper接口\n\n```Java\n/**\n * 删除\n * \n * @param id\n */\npublic void deleteById(Integer pk) {\n\trepo.deleteByPK(pk);\n}\n\n/**\n * 通过id获取\n * \n * @param id\n * @return\n */\npublic OrgInfo findById(Integer pk) {\n\treturn repo.selectByPK(pk);\n}\n\n/**\n * 通过非空属性查询\n * \n * @param OrgInfo\n * @return\n */\npublic List\u003cOrgInfo\u003e findByNotNullProps(OrgInfo entity) {\n\n\tSelectStatement\u003cOrgInfo\u003e st = StatementBuilder.buildSelectSelective(entity);\n\treturn repo.selectByStatement(st);\n}\n/**\n * 单表通用查询样例\n * \n * @param OrgInfo\n * @return\n */\n@Override\npublic OrgInfo findByCode(String code) {\n\tOrgInfo.EntityNode n = OrgInfo.EntityNode.INSTANCE;\n\tSelectStatement\u003cOrgInfo\u003e st = StatementBuilder.buildSelect(n);\n\tst.restrictions().add(n.code.eq(code));\n\treturn CollectionUtil.uniqueResult(this.repo.selectByStatement(st));\n}\n  \n  ```\n\n# 代码生成器\n\u003e 角色类似 mybatis-generator\n\n![](1.png)\n\n![](2.png)\n\n\n## 生成的mapper xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003c!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\" \u003e\n\u003cmapper namespace=\"com.kingseok.cirms.biz.dao.OrgInfoMapper\" \u003e\n\t\u003cresultMap id=\"BaseResultMap\" type=\"com.kingseok.cirms.biz.domain.OrgInfo\" \u003e\n\t    \u003cid column=\"id\" property=\"id\" jdbcType=\"INTEGER\" /\u003e\t\n\t  \t\u003cresult column=\"code\" property=\"code\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"secret\" property=\"secret\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"name\" property=\"name\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"img_src\" property=\"imgSrc\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"type\" property=\"type\" jdbcType=\"INTEGER\" /\u003e\n\t  \t\u003cresult column=\"website\" property=\"website\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"address\" property=\"address\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"tel\" property=\"tel\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"email\" property=\"email\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"contactor\" property=\"contactor\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"status\" property=\"status\" jdbcType=\"TINYINT\" /\u003e\n\t  \t\u003cresult column=\"remark\" property=\"remark\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"op_on\" property=\"opOn\" jdbcType=\"TIMESTAMP\" /\u003e\n\t  \t\u003cresult column=\"op_by\" property=\"opBy\" jdbcType=\"INTEGER\" /\u003e\n    \u003c/resultMap\u003e\n    \u003cresultMap id=\"BaseResultMap_OrgInfo\" type=\"com.kingseok.cirms.biz.domain.OrgInfo\" \u003e\n\t    \u003cid column=\"toi_id\" property=\"id\" jdbcType=\"INTEGER\" /\u003e\t\n\t  \t\u003cresult column=\"toi_code\" property=\"code\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_secret\" property=\"secret\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_name\" property=\"name\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_img_src\" property=\"imgSrc\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_type\" property=\"type\" jdbcType=\"INTEGER\" /\u003e\n\t  \t\u003cresult column=\"toi_website\" property=\"website\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_address\" property=\"address\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_tel\" property=\"tel\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_email\" property=\"email\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_contactor\" property=\"contactor\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_status\" property=\"status\" jdbcType=\"TINYINT\" /\u003e\n\t  \t\u003cresult column=\"toi_remark\" property=\"remark\" jdbcType=\"VARCHAR\" /\u003e\n\t  \t\u003cresult column=\"toi_op_on\" property=\"opOn\" jdbcType=\"TIMESTAMP\" /\u003e\n\t  \t\u003cresult column=\"toi_op_by\" property=\"opBy\" jdbcType=\"INTEGER\" /\u003e\n    \u003c/resultMap\u003e\n    \u003csql id=\"Base_Column_List\" \u003e\n  \t\tid,code,secret,name,img_src,type,website,address,tel,email,contactor,status,remark,op_on,op_by\n\t\u003c/sql\u003e\n  \t\u003csql id=\"Base_Column_List_OrgInfo\" \u003e\n  \t\ttoi.id toi_id,toi.code toi_code,toi.secret toi_secret,toi.name toi_name,toi.img_src toi_img_src,toi.type toi_type,toi.website toi_website,toi.address toi_address,toi.tel toi_tel,toi.email toi_email,toi.contactor toi_contactor,toi.status toi_status,toi.remark toi_remark,toi.op_on toi_op_on,toi.op_by toi_op_by\n\t\u003c/sql\u003e\n\t\n\t\u003c!-- 系统自定义 --\u003e\n\t\u003c!-- 实体参数查询结果[START] --\u003e\n\t\u003cresultMap id=\"ResultMap_FindByQueryParam\" type=\"com.kingseok.cirms.biz.domain.OrgInfo\" extends=\"BaseResultMap_OrgInfo\"\u003e\n\t\t\n\t\u003c/resultMap\u003e\n\n\t\u003csql id=\"Condition_FindByQueryParam\"\u003e\n\t\t\u003cif test=\"queryParam.param!=null\"\u003e\n\t\t\t\u003cbind name=\"p\" value=\"queryParam.param\"/\u003e\n\t\t\t\u003cif test=\"p.id!=null \"\u003e\n\t\t    \tand toi.id=#{p.id}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.code!=null and p.code!=''\"\u003e\n\t\t    \tand toi.code=#{p.code}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.secret!=null and p.secret!=''\"\u003e\n\t\t    \tand toi.secret=#{p.secret}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.name!=null and p.name!=''\"\u003e\n\t\t    \tand toi.name=#{p.name}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.imgSrc!=null and p.imgSrc!=''\"\u003e\n\t\t    \tand toi.img_src=#{p.imgSrc}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.type!=null \"\u003e\n\t\t    \tand toi.type=#{p.type}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.website!=null and p.website!=''\"\u003e\n\t\t    \tand toi.website=#{p.website}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.address!=null and p.address!=''\"\u003e\n\t\t    \tand toi.address=#{p.address}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.tel!=null and p.tel!=''\"\u003e\n\t\t    \tand toi.tel=#{p.tel}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.email!=null and p.email!=''\"\u003e\n\t\t    \tand toi.email=#{p.email}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.contactor!=null and p.contactor!=''\"\u003e\n\t\t    \tand toi.contactor=#{p.contactor}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.status!=null \"\u003e\n\t\t    \tand toi.status=#{p.status}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.remark!=null and p.remark!=''\"\u003e\n\t\t    \tand toi.remark=#{p.remark}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.opOn!=null \"\u003e\n\t\t    \tand toi.op_on=#{p.opOn}\n\t\t    \u003c/if\u003e\n\t\t\t\u003cif test=\"p.opBy!=null \"\u003e\n\t\t    \tand toi.op_by=#{p.opBy}\n\t\t    \u003c/if\u003e\n\t\t\u003c/if\u003e\n\t\t\u003cbind name=\"rp\" value=\"queryParam.ruleParam\" /\u003e\n\t\t\u003cinclude refid=\"org.mybatis.hbatis.orm.mapper.HbatisMapper.RuleParam\"/\u003e\n\t\u003c/sql\u003e\n\t\u003cselect id=\"findByQueryParam\" resultMap=\"ResultMap_FindByQueryParam\"\u003e\n\t\tselect\n\t\t\u003cinclude refid=\"Base_Column_List_OrgInfo\"\u003e\u003c/include\u003e\n\t\tfrom t_org_info toi where 1=1\n\t\t\u003cinclude refid=\"Condition_FindByQueryParam\"\u003e\u003c/include\u003e\n\t\t\u003cif test=\"queryParam.limit gt 0\"\u003e\n\t  \t\tlimit ${queryParam.start},${queryParam.limit}\n\t  \t\u003c/if\u003e\n\t\u003c/select\u003e\n\t\u003cselect id=\"countByQueryParam\" resultType=\"long\"\u003e\n\t\tselect count(1) from t_org_info toi where 1=1\n\t\t\u003cinclude refid=\"Condition_FindByQueryParam\"\u003e\u003c/include\u003e\n\t\u003c/select\u003e\n\t\n\t\u003c!-- 实体参数查询结果[END] --\u003e\n\t\u003c!-- 用户自定义 --\u003e\n\t\n\u003c/mapper\u003e\n```\n\u003e 如果只是单表的CRUD操作，xml内容可为空。但为了减少后期人工添加的麻烦，于是就在模块里生成...\n\u003e 关于分页：因本人一直使用mysql，未编写其它数据库的分页实现\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flanux%2Fhbatis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flanux%2Fhbatis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flanux%2Fhbatis/lists"}