{"id":21803012,"url":"https://github.com/litongjava/java-db","last_synced_at":"2025-04-13T19:01:46.629Z","repository":{"id":213144707,"uuid":"732867969","full_name":"litongjava/java-db","owner":"litongjava","description":"jfinal-plugins","archived":false,"fork":false,"pushed_at":"2024-11-27T10:08:28.000Z","size":930,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-27T10:32:45.676Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/litongjava.png","metadata":{"files":{"readme":"readme.md","changelog":null,"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}},"created_at":"2023-12-18T03:24:15.000Z","updated_at":"2024-11-27T10:08:32.000Z","dependencies_parsed_at":"2023-12-18T21:35:03.629Z","dependency_job_id":"fa04cae7-881d-4e62-bd52-13dc3ec44864","html_url":"https://github.com/litongjava/java-db","commit_stats":null,"previous_names":["litongjava/jfinal-plugins","litongjava/java-db"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litongjava%2Fjava-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litongjava%2Fjava-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litongjava%2Fjava-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litongjava%2Fjava-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/litongjava","download_url":"https://codeload.github.com/litongjava/java-db/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226744519,"owners_count":17675024,"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-11-27T11:37:07.235Z","updated_at":"2025-04-13T19:01:46.622Z","avatar_url":"https://github.com/litongjava.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# java‑db\n\n\u003e A lightweight, zero-configuration Java database operation framework supporting multiple data sources, read‑write splitting, SQL template management, ActiveRecord ORM, batch operations, transactions, statistics, and more.\n\n## 🚀 Features\n\n- ✅ Supports MySQL, PostgreSQL, Oracle, SQLite, and more  \n- ✅ Built‑in Druid/HikariCP connection pools  \n- ✅ ActiveRecord ORM + generic Row mode  \n- ✅ Enjoy SQL template management (#namespace/#sql/#para)  \n- ✅ Read‑write splitting (automatic master‑slave routing)  \n- ✅ Batch Save/Update/Delete  \n- ✅ Flexible transactions (Db.tx, declarative Tx)  \n- ✅ SQL execution statistics (LiteSqlStatementStat)  \n- ✅ Guava Striped locks for concurrency control  \n- ✅ Multi‑data source \u0026 sharding support  \n- ✅ Spring Boot integration / JUnit testing  \n- ✅ Native Ehcache \u0026 Redis caching integration  \n\n---\n\n## 📦 Quick Start\n\n### Maven Dependencies\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.litongjava\u003c/groupId\u003e\n  \u003cartifactId\u003ejava-db\u003c/artifactId\u003e\n  \u003cversion\u003e1.5.1\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003emysql\u003c/groupId\u003e\n  \u003cartifactId\u003emysql-connector-java\u003c/artifactId\u003e\n  \u003cversion\u003e8.0.33\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.zaxxer\u003c/groupId\u003e\n  \u003cartifactId\u003eHikariCP\u003c/artifactId\u003e\n  \u003cversion\u003e5.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!-- Ehcache --\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003enet.sf.ehcache\u003c/groupId\u003e\n  \u003cartifactId\u003eehcache-core\u003c/artifactId\u003e\n  \u003cversion\u003e2.6.11\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!-- Jedis for Redis --\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eredis.clients\u003c/groupId\u003e\n  \u003cartifactId\u003ejedis\u003c/artifactId\u003e\n  \u003cversion\u003e4.3.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n---\n\n## ⚙️ Configuration\n\n`app.properties`:\n\n```properties\nDATABASE_DSN=postgresql://user:pass@127.0.0.1:5432/dbname\nDATABASE_DSN_REPLICAS=postgresql://user:pass@127.0.0.1:5433/dbname\njdbc.showSql=true\n\nredis.host=127.0.0.1\nredis.port=6379\nredis.cacheName=main\nredis.timeout=15000\n```\n\n### Java Initialization (Spring Boot example)\n\n```java\n@Configuration\npublic class DbConfig {\n  @Bean(destroyMethod=\"stop\")\n  public ActiveRecordPlugin arp(DataSource ds) {\n    ActiveRecordPlugin arp = new ActiveRecordPlugin(ds);\n    arp.setDialect(new PostgreSqlDialect());\n    arp.setShowSql(true);\n    arp.getEngine().setSourceFactory(new ClassPathSourceFactory());\n    arp.addSqlTemplate(\"/sql/all.sql\");\n    arp.start();\n    return arp;\n  }\n\n  @Bean(destroyMethod=\"stop\")\n  public EhCachePlugin ehCachePlugin() {\n    EhCachePlugin plugin = new EhCachePlugin();\n    plugin.start();\n    return plugin;\n  }\n\n  @Bean(destroyMethod=\"stop\")\n  public RedisPlugin redisPlugin() {\n    RedisPlugin rp = new RedisPlugin(\"main\",\"127.0.0.1\",6379,15000,null,0);\n    rp.start();\n    return rp;\n  }\n}\n```\n\n---\n\n## 🎯 Core API\n\n### CRUD (Row Mode)\n\n```java\nRow r = new Row().set(\"name\",\"Alice\").set(\"age\",30);\nDb.save(\"user\", r);\n\nList\u003cRow\u003e list = Db.find(\"select * from user where age\u003e?\", 20);\nRow one = Db.findFirst(\"select * from user where id=?\", 1);\nDb.update(\"update user set age=? where id=?\", 31, 1);\nDb.deleteById(\"user\", 1);\n```\n\n### ActiveRecord (Model Mode)\n\n```java\npublic class User extends Model\u003cUser\u003e {\n  public static final User dao = new User().dao();\n}\nUser.dao.findById(1);\nnew User().set(\"name\",\"Bob\").save();\n```\n\n### SQL Templates (Enjoy)\n\n```sql\n-- src/main/resources/sql/all.sql\n#include(\"user.sql\")\n```\n\n```sql\n-- src/main/resources/sql/user.sql\n#namespace(\"user\")\n  #sql(\"findByName\")\n    select * from user where name like #para(name)\n  #end\n#end\n```\n\n```java\nList\u003cRow\u003e users = Db.template(\"user.findByName\", Kv.by(\"name\",\"%John%\")).find();\n```\n\n### Batch Operations\n\n```java\nList\u003cRow\u003e rows = ...;\nDb.batchSave(\"user\", rows, 500);\nDb.batchUpdate(\"user\", rows, 500);\n```\n\n### Transactions\n\n```java\nDb.tx(() -\u003e {\n  Db.update(\"update account set balance=balance-? where id=?\",100,1);\n  Db.update(\"update account set balance=balance+? where id=?\",100,2);\n  return true;\n});\n```\n\n### Read‑Write Splitting\n\n```java\nDb.countTable(\"student\");            // automatically uses replica (read)\nDb.use(\"main\").update(...);          // forces write to master\n```\n\n### SQL Statistics\n\n```java\nLite.querySqlStatementStats();\n```\n\n---\n\n## 💾 Caching\n\n### Ehcache\n\nLoads configuration from `classpath:ehcache.xml` by default.\n\n```java\nCacheKit.put(\"users\",\"key\",\"value\");\nString v = CacheKit.get(\"users\",\"key\");\nCacheKit.remove(\"users\",\"key\");\n```\n\n### Redis\n\n#### Basic Usage\n\n```java\n// String\nRedis.use().setStr(\"foo\",\"bar\");\nString foo = Redis.use().getStr(\"foo\");\n\n// Bean\nRedis.use().setBean(\"user:1\",3600,new User(1,\"Alice\"));\nUser u = Redis.use().getBean(\"user:1\",User.class);\n\n// Native Jedis lambda\nLong counter = Redis.call(j -\u003e j.incr(\"counter\"));\n\n// Distributed lock\nString lockId = Redis.use().lock(\"lockName\",30,5);\nif(lockId!=null){ try{/*...*/} finally{ Redis.use().unlock(\"lockName\",lockId);} }\n```\n\n#### Cacheable Annotation\n\n```java\n@Before(RedisCacheInterceptor.class)\n@Cacheable(name=\"users\",value=\"findById\",ttl=600)\npublic User findById(Long id){ ... }\n```\n\n---\n\n## 🧪 Unit Testing\n\n```java\n@BeforeClass\npublic static void init() {\n  EnvUtils.load();\n  new DbConfig().config();\n}\n@Test\npublic void testFind() {\n  Row r = Db.findFirst(\"select 1\");\n  assertNotNull(r);\n}\n```\n\n---\n\n## 📖 Documentation \u0026 Links\n\n- GitHub: https://github.com/litongjava/java-db  \n- Document : https://www.tio-boot.com/zh/09_java-db/01.html\n---\n\n## 📝 License\n\nApache‑2.0","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitongjava%2Fjava-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flitongjava%2Fjava-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitongjava%2Fjava-db/lists"}