{"id":15033399,"url":"https://github.com/mybatis-flex/mybatis-flex","last_synced_at":"2025-05-14T02:06:45.128Z","repository":{"id":153307966,"uuid":"606971636","full_name":"mybatis-flex/mybatis-flex","owner":"mybatis-flex","description":"mybatis-flex is an elegant Mybatis Enhancement Framework","archived":false,"fork":false,"pushed_at":"2025-04-21T07:36:08.000Z","size":14117,"stargazers_count":2079,"open_issues_count":190,"forks_count":206,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-04-21T08:36:08.513Z","etag":null,"topics":["java","mybatis","mysql","orm","sql"],"latest_commit_sha":null,"homepage":"https://mybatis-flex.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mybatis-flex.png","metadata":{"files":{"readme":"readme.md","changelog":"changes.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2023-02-27T03:14:05.000Z","updated_at":"2025-04-21T07:36:13.000Z","dependencies_parsed_at":"2023-12-03T05:19:52.951Z","dependency_job_id":"77307e3e-2bda-4bf1-b0a4-02ea0cc5b715","html_url":"https://github.com/mybatis-flex/mybatis-flex","commit_stats":{"total_commits":2891,"total_committers":172,"mean_commits":"16.808139534883722","dds":"0.49083362158422694","last_synced_commit":"37559179b1b6a6ccc4445a76dce2ac0efabd1a22"},"previous_names":[],"tags_count":110,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mybatis-flex%2Fmybatis-flex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mybatis-flex%2Fmybatis-flex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mybatis-flex%2Fmybatis-flex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mybatis-flex%2Fmybatis-flex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mybatis-flex","download_url":"https://codeload.github.com/mybatis-flex/mybatis-flex/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052713,"owners_count":22006716,"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":["java","mybatis","mysql","orm","sql"],"created_at":"2024-09-24T20:21:06.525Z","updated_at":"2025-05-14T02:06:40.075Z","avatar_url":"https://github.com/mybatis-flex.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch4 align=\"right\"\u003e\u003cstrong\u003eEnglish\u003c/strong\u003e | \u003ca href=\"./readme_zh.md\"\u003e简体中文\u003c/a\u003e\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/assets/images/logo_en.png\"/\u003e\n\u003c/p\u003e\n\n# MyBatis-Flex is an elegant Mybatis Enhancement Framework.\n\n\u003cp align=\"center\"\u003e\n    \u003ca target=\"_blank\" href=\"https://search.maven.org/search?q=mybatis-flex%20mybatis-flex\"\u003e\n        \u003cimg src=\"https://img.shields.io/maven-central/v/com.mybatis-flex/parent?label=Maven%20Central\" alt=\"Maven\" /\u003e\n    \u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://www.apache.org/licenses/LICENSE-2.0.txt\"\u003e\n\t\t\u003cimg src=\"https://img.shields.io/:license-Apache2-blue.svg\" alt=\"Apache 2\" /\u003e\n\t\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html\"\u003e\n\t\t\u003cimg src=\"https://img.shields.io/badge/JDK-8-green.svg\" alt=\"jdk-8\" /\u003e\n\t\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html\"\u003e\n\t\t\u003cimg src=\"https://img.shields.io/badge/JDK-11-green.svg\" alt=\"jdk-11\" /\u003e\n\t\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html\"\u003e\n\t\t\u003cimg src=\"https://img.shields.io/badge/JDK-17-green.svg\" alt=\"jdk-17\" /\u003e\n\t\u003c/a\u003e\n    \u003cbr /\u003e\n        \u003cimg src=\"https://img.shields.io/badge/SpringBoot-v2.x-blue\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/SpringBoot-v3.x-blue\"\u003e\n        \u003ca target=\"_blank\" href='https://github.com/noear/solon'\u003e\u003cimg src=\"https://img.shields.io/badge/Solon-v2.x-blue\"\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003ca target=\"_blank\" href='https://gitee.com/mybatis-flex/mybatis-flex'\u003e\n\t\t\u003cimg src='https://gitee.com/mybatis-flex/mybatis-flex/badge/star.svg' alt='Gitee star'/\u003e\n\t\u003c/a\u003e\n    \u003ca target=\"_blank\" href='https://github.com/mybatis-flex/mybatis-flex'\u003e\n\t\t\u003cimg src=\"https://img.shields.io/github/stars/mybatis-flex/mybatis-flex.svg?logo=github\" alt=\"Github star\"/\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n## Features\n\n1. MyBatis-Flex is very lightweight, and it only depends on Mybatis and no other third-party dependencies\n2. Basic CRUD operator and paging query of Entity class\n3. Row mapping support, you can add, delete, modify and query the database without entity classes\n4. Support multiple databases, and expand through dialects flexibly\n5. Support combined primary keys and different primary key content generation strategies\n6. Extremely friendly SQL query, IDE automatically prompts and no worries about mistakes\n7. More little surprises\n\n## hello world(Without Spring)\n\n**step 1: write entity class**\n\n```java\n@Table(\"tb_account\")\npublic class Account {\n\n    @Id(keyType = KeyType.Auto)\n    private Long id;\n    private String userName;\n    private Date birthday;\n    private int sex;\n\n    // getter setter\n}\n```\n\n**step 2: write mapper class(it needs extends BaseMapper)**\n\n```java\npublic interface AccountMapper extends BaseMapper\u003cAccount\u003e {\n    // only Mapper interface define\n}\n```\n\n**step 3: start query data**\n\ne.g. 1: query by primary key\n\n```java\nclass HelloWorld {\n    public static void main(String... args) {\n\n        HikariDataSource dataSource = new HikariDataSource();\n        dataSource.setJdbcUrl(\"jdbc:mysql://127.0.0.1:3306/mybatis-flex\");\n        dataSource.setUsername(\"username\");\n        dataSource.setPassword(\"password\");\n\n        MybatisFlexBootstrap.getInstance()\n                .setDataSource(dataSource)\n                .addMapper(AccountMapper.class)\n                .start();\n\n        AccountMapper mapper = MybatisFlexBootstrap.getInstance()\n                .getMapper(AccountMapper.class);\n\n\n        // id = 100\n        Account account = mapper.selectOneById(100);\n    }\n}\n```\n\ne.g.2: query list\n\n```java\n// use QueryWrapper to build query conditions\nQueryWrapper query = QueryWrapper.create()\n        .select()\n        .from(ACCOUNT)\n        .where(ACCOUNT.ID.ge(100))\n        .and(ACCOUNT.USER_NAME.like(\"zhang\").or(ACCOUNT.USER_NAME.like(\"li\")));\n\n// execute SQL：\n// SELECT * FROM tb_account\n// WHERE tb_account.id \u003e=  100\n// AND (tb_account.user_name LIKE '%zhang%' OR tb_account.user_name LIKE '%li%' )\nList\u003cAccount\u003e accounts = mapper.selectListByQuery(query);\n```\n\ne.g.3: paging query\n\n```java\n// use QueryWrapper to build query conditions\nQueryWrapper query = QueryWrapper.create()\n        .select()\n        .from(ACCOUNT)\n        .where(ACCOUNT.ID.ge(100))\n        .and(ACCOUNT.USER_NAME.like(\"zhang\").or(ACCOUNT.USER_NAME.like(\"li\")))\n        .orderBy(ACCOUNT.ID.desc());\n\n// execute SQL：\n// SELECT * FROM tb_account\n// WHERE tb_account.id \u003e=  100\n// AND (tb_account.user_name LIKE '%zhang%' OR tb_account.user_name LIKE '%li%' )\n// ORDER BY tb_account.id DESC\n// LIMIT 40,10\nPage\u003cAccount\u003e accountPage = mapper.paginate(5, 10, query);\n```\n\n## QueryWrapper Samples\n\n### select *\n\n```java\nQueryWrapper query = new QueryWrapper();\nquery.select().from(ACCOUNT)\n\n// SQL:\n// SELECT * FROM tb_account\n```\n\n### select columns\n\n```java\nQueryWrapper query = new QueryWrapper();\nquery.select(ACCOUNT.ID,ACCOUNT.USER_NAME).from(ACCOUNT)\n\n// SQL:\n// SELECT tb_account.id, tb_account.user_name\n// FROM tb_account\n```\n\n\n```java\nQueryWrapper query = new QueryWrapper()\n    .select(ACCOUNT.ID\n        , ACCOUNT.USER_NAME\n        , ARTICLE.ID.as(\"articleId\")\n        , ARTICLE.TITLE)\n    .from(ACCOUNT.as(\"a\"), ARTICLE.as(\"b\"))\n    .where(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));\n\n// SQL:\n// SELECT a.id, a.user_name, b.id AS articleId, b.title\n// FROM tb_account AS a, tb_article AS b\n// WHERE a.id = b.account_id\n```\n\n### select functions\n\n```java\n QueryWrapper query = new QueryWrapper()\n        .select(\n            ACCOUNT.ID,\n            ACCOUNT.USER_NAME,\n            max(ACCOUNT.BIRTHDAY),\n            avg(ACCOUNT.SEX).as(\"sex_avg\")\n        ).from(ACCOUNT);\n\n// SQL:\n// SELECT tb_account.id, tb_account.user_name,\n// MAX(tb_account.birthday),\n// AVG(tb_account.sex) AS sex_avg\n// FROM tb_account\n```\n\n### where\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .where(ACCOUNT.ID.ge(100))\n    .and(ACCOUNT.USER_NAME.like(\"michael\"));\n\n// SQL:\n// SELECT * FROM tb_account\n// WHERE tb_account.id \u003e=  ?\n// AND tb_account.user_name LIKE  ?\n```\n\n### exists, not exists\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .where(ACCOUNT.ID.ge(100))\n    .and(\n        exists(\n            selectOne().from(ARTICLE).where(ARTICLE.ID.ge(100))\n        )\n    );\n\n// SQL:\n// SELECT * FROM tb_account\n// WHERE tb_account.id \u003e=  ?\n// AND EXIST (\n//  SELECT 1 FROM tb_article WHERE tb_article.id \u003e=  ?\n// )\n```\n\n### and (...) or (...)\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .where(ACCOUNT.ID.ge(100))\n    .and(ACCOUNT.SEX.eq(1).or(ACCOUNT.SEX.eq(2)))\n    .or(ACCOUNT.AGE.in(18,19,20).or(ACCOUNT.USER_NAME.like(\"michael\")));\n\n// SQL:\n// SELECT * FROM tb_account\n// WHERE tb_account.id \u003e=  ?\n// AND (tb_account.sex =  ?  OR tb_account.sex =  ? )\n// OR (tb_account.age IN (?,?,?) OR tb_account.user_name LIKE  ? )\n```\n\n### group by\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .groupBy(ACCOUNT.USER_NAME);\n\n// SQL:\n// SELECT * FROM tb_account\n// GROUP BY tb_account.user_name\n```\n\n### having\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .groupBy(ACCOUNT.USER_NAME)\n    .having(ACCOUNT.AGE.between(18,25));\n\n// SQL:\n// SELECT * FROM tb_account\n// GROUP BY tb_account.user_name\n// HAVING tb_account.age BETWEEN  ? AND ?\n```\n\n\n### orderBy\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n        .select()\n        .from(ACCOUNT)\n        .orderBy(ACCOUNT.AGE.asc(), ACCOUNT.USER_NAME.desc().nullsLast());\n\n// SQL:\n// SELECT * FROM tb_account\n// ORDER BY age ASC, user_name DESC NULLS LAST\n```\n\n\n### join\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))\n    .where(ACCOUNT.AGE.ge(10));\n\n// SQL:\n// SELECT * FROM tb_account\n// LEFT JOIN tb_article\n// ON tb_account.id = tb_article.account_id\n// WHERE tb_account.age \u003e=  ?\n```\n\n\n### limit... offset\n\n```java\nQueryWrapper queryWrapper = QueryWrapper.create()\n    .select()\n    .from(ACCOUNT)\n    .orderBy(ACCOUNT.ID.desc())\n    .limit(10)\n    .offset(20);\n\n// MySql:\n// SELECT * FROM `tb_account` ORDER BY `id` DESC LIMIT 20, 10\n\n// PostgreSQL:\n// SELECT * FROM \"tb_account\" ORDER BY \"id\" DESC LIMIT 20 OFFSET 10\n\n// Informix:\n// SELECT SKIP 20 FIRST 10 * FROM \"tb_account\" ORDER BY \"id\" DESC\n\n// Oracle:\n// SELECT * FROM (SELECT TEMP_DATAS.*,\n//  ROWNUM RN FROM (\n//          SELECT * FROM \"tb_account\" ORDER BY \"id\" DESC)\n//      TEMP_DATAS WHERE  ROWNUM \u003c=30)\n//  WHERE RN \u003e20\n\n// Db2:\n// SELECT * FROM \"tb_account\" ORDER BY \"id\" DESC\n// OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY\n\n// Sybase:\n// SELECT TOP 10 START AT 21 * FROM \"tb_account\" ORDER BY \"id\" DESC\n\n// Firebird:\n// SELECT * FROM \"tb_account\" ORDER BY \"id\" DESC ROWS 20 TO 30\n```\n\n\n### Questions？\n\n**1. How to generate \"ACCOUNT\" class for QueryWrapper by Account.java ?**\n\nBuild the project by IDE, or execute maven build command: `mvn clean package`\n\n![](./docs/assets/images/build_idea.png)\n\n## More Samples\n\n1. [Mybatis-Flex Only (Native)](./mybatis-flex-test/mybatis-flex-native-test)\n2. [Mybatis-Flex with Spring](./mybatis-flex-test/mybatis-flex-spring-test)\n3. [Mybatis-Flex with Spring boot](./mybatis-flex-test/mybatis-flex-spring-boot-test)\n\n## Wechat Group\n\n![](./docs/assets/images/wechat-group.png)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmybatis-flex%2Fmybatis-flex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmybatis-flex%2Fmybatis-flex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmybatis-flex%2Fmybatis-flex/lists"}