该项目可以让开发者使用原生sql或者查询构造器与数据库进行交互,同时easyDB
还支持自动分页器,只需要传入一些参数就可以实现自动分页。
将EasyDB-1.0.2.jar
放到项目的lib
目录下
配置maven
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.wlkjyy</groupId>
<artifactId>EasyDB</artifactId>
<version>1.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/EasyDB-1.0.2.jar</systemPath>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
创建一个Manager
实例,通过addConnection
方法添加一个连接,通过getEloquentInstance
方法获取一个DB实例
import com.wlkjyy.Capsule.Manager;
import com.wlkjyy.Eloquent.DB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
/**
* @Author: wlkjyy <[email protected]>
* @Date: 2024/3/26
* @Project: Default (Template) Project
*/
public class Main {
public static void main(String[] args) throws SQLException {
Manager manager = new Manager();
manager.addConnection(new HashMap<>(){
{
put("host", "localhost");
put("port", 3306);
put("username", "root");
put("password", "123456");
put("database", "testdatabase");
}
});
DB myDB = manager.getEloquentInstance();
}
}
创建一个service
@Service
public class db {
@Bean
public DB DB(){
Manager manager = new Manager();
manager.addConnection(new HashMap<>(){
{
put("host", "localhost");
put("port", 3306);
put("username", "root");
put("password", "123456");
put("database", "jianzhan");
}
});
return manager.getEloquentInstance();
}
}
使用
@RestController
public class IndexController {
@Autowired
DB db;
@GetMapping("/")
public ArrayList<HashMap<String, Object>> index() throws SQLException {
return db.table("users").get();
}
}
easyDB
默认情况下是使用的Hikari
连接池,相关参数位于MySqlConnector.java
中
默认情况下,是使用10
个连接。
你可以使用 提供的 table
方法开始查询。table 方法为指定的表返回一个链式查询构造器实例,允许在查询上链接更多约束,最后使用 get
方法检索查询结果:
ArrayList<HashMap<String, Object>> users = MyDB.table("users").get();
get
方法返回包含查询结果的 ArrayList<HashMap<String, Object>>
,你可以这样去实现访问每一条数据
ArrayList<HashMap<String, Object>> users = MyDB.table("users").get();
for (HashMap<String, Object> user : users) {
System.out.println(user.get("username"));
}
where
方法可以创建一个带有where的sql,通常情况下,where
方法包含三个参数,分别为字段
、操作
、结果
,当不传入操作
时,操作
默认为=
例如下方这个示例,可以查询users
表下所有active
为1的所有
数据,返回一个ArrayList<HashMap<String, Object>>
类型的数据
MyDB.table("users").where("active",1).get();
例如下方这个示例,可以查询users
表下所有active
大于1的所有
数据
MyDB.table("users").where("active",">",1).get();
有时,你只想获取第一条数据,你就可以通过first
方法,你可以查询出第一条数据,他是基于limit 1
实现的,返回类型为HashMap<String, Object>
MyDB.table("users").where("active",1).first();
你可以通过find
方法实现使用主键来查询一条数据
,当不传入主键时,主键默认为id
MyDB.table("users").find(1);
如果你的表主键非id
时,你需要指定一个主键
MyDB.table("users").find("uid",1);
你可以使用getSql
方法实现获取查询构造器生成的SQL
代码
DB.table("users").where("active",1).orWhere("username","admin").getSql()
输出如下
select * from `users` where `active` = ? or `username` = ?
通常情况下,你的查询并不是只有一个条件,你可以使用多个where
来实现多条件查询
例如下方这个示例,查询users
表下active
为1且username
为admin
的第一条数据
MyDB.table("users").where("active",1).where("username","admin").first();
orWhere
可以实现一个或条件查询
,当然也可以指定多个orWhere
例如下方这个示例,可以查询users
表下active
为1或者username
为admin
的第一条数据
MyDB.table("users").where("active",1).orWhere("username","admin").first();
该构造器生成的SQL语句如下:
select * from `users` where `active` = ? or `username` = ?
查询users
表下username
为admin
且password
为md5加密的123456
的第一条数据
MyDB.table("users").where("username","admin").md5Where("password","123456").first();
查询users
表下username
为admin
或者password
为md5加密的123456
的第一条数据
MyDB.table("users").where("username","admin").orMd5Where("password","123456").first();
whereBetween可以查询某个区间内的值
MyDB.table("users").whereBetween("id", 1, 5).get()
orWhereBetween可以查询某个区间内的值
MyDB.table("users").orWhereBetween("id", 1, 5).get()
whereIn可以查询某个字段特定的值
DB.table("users").whereIn("id", new Object[]{1,7}).get()
orWhereIn可以查询某个字段特定的值
MyDB.table("users").orWhereIn("id", new Object[]{1,7}).get()
whereNotBetween
方法用于验证字段的值是否不在给定的两个值范围之中:
MyDB.table("users").whereNotBetween ("id", 1, 5).get()
MyDB.table("users").orWhereNotBetween ("id", 1, 5).get()
whereNull
和whereNotNull
可以验证字段是否为null或不为null
MyDB.table("users").whereNull("verify_email").first()
MyDB.table("users").whereNotNull("verify_email").first()
whereColumn
和orWhereColumn
可以实现对两个字段
进行比较
例如下面这样
MyDB.table("users").whereColumn("id","uid").first()
也可以是这样
MyDB.table("users").whereColumn("id",">","uid").first()
也可以连贯操作
DB.table("users").whereColumn("id","=","uid").orWhereColumn("id","<","uid").get()
查询构建器的 delete
方法可用于从表中删除记录。delete
方法会返回受影响的行数。你可以通过在调用 delete
方法之前添加 where
子句来限制 delete
语句:
MyDB.table("users").where("username","test123").delete();
如果你希望截断整个表,这将从表中删除所有记录并将自动递增 ID 重置为零,你可以使用 truncate
方法:
MyDB.table('users').truncate();
通过update
方法可以实现数据的更新,需要传入一个Hashmap的数据格式,其中key
为字段,value
为设置的值
update
方法会返回受影响的行数,通常情况下为0行代表执行错误。
更新users表下username为test
的数据,将token更新为123456
MyDB.table("users").where("username","test").update(new HashMap<String, Object>(){{
put("token",123456);
}});
通过count
方法可以获取总条数,返回一个Int
类型数据
获取users
表下active
为1的条数
MyDB.table("users").where("active",1).count();
通过max
方法可以获取最大值,返回一个Double
类型数据
获取users
表下uid
的最大值
MyDB.table("users").max("uid");
获取users
表下active
为1的uid最大值
MyDB.table("users").where("active",1).max("uid");
通过min
方法可以获取最小值,返回一个Double
类型数据
获取users
表下uid
的最小值
MyDB.table("users").min("uid");
获取users
表下active
为1的uid最小值
MyDB.table("users").where("active",1).min("uid");
通过avg
方法可以获取最小值,返回一个Double
类型数据
获取users
表下uid
的平均值
MyDB.table("users").avg("uid");
获取users
表下active
为1的uid平均值
MyDB.table("users").where("active",1).avg("uid");
MyDB.table("users").where("active",1).limit(0,100).get()
等价于
MyDB.table("users").where("active",1).limit(100).get()
查询构造器还提供了方便的方法来增加或减少给定列的值。这两种方法都至少接受一个参数:要修改的列。可以提供第二个参数来指定列应该增加或减少的数量:
// 默认+1
MyDB.table("users").where("active",1).increment("money");
// 指定+5
MyDB.table("users").where("active",1).increment("money",5);
// 默认-1
MyDB.table("users").where("active",1).decrement("money");
// 指定-5
MyDB.table("users").where("active",1).decrement("money",5);
此外,你可以使用 incrementEach
和 decrementEach
方法同时增加或减少多个列:
DB.table("users").where("id",2).incrementEach(new HashMap<String, Object>(){{
put("money",1.6);
put("age",1);
}})
除了通过 count
方法可以确定查询条件的结果是否存在之外,还可以使用 exists
和 doesntExist
方法:
if(MyDB.table("users").where("username","admin").exists()){
// .....
}
if(MyDB.table("users").where("username","admin").doesntExist()){
// ...
}
distinct
方法可以让结果不重复,例如下面这样
MyDB.table("users").distinct("username").get()
distinct
方法也可以指定多个列
MyDB.table("users").distinct("username","nickname").get()
通过addColumnCount
、addColumnSum
、addColumnAvg
、addColumnMin
、addColumnMax
中可以加入count、sum、avg、min、max等查询。
例如下面这样
MyDB.table("users").addColumnCount("username").get()
默认情况下,统计后的名字为count
,你也可以为统计字段可以设置一个别名user_count_number
,例如这样
MyDB.table("users").addColumnCount("username","user_count_number").get()
可以得到以下结果
[{user_count_number=2}]
你也可以添加多个统计,例如这样
DB.table("users").addColumnCount("id","id_count").addColumnSum("id","sum").get()
通过下面这个示例,可以获取出所有不重复的用户名
,切记,groupBy
需要配置select
使用
MyDB.table("users").select("username").groupBy("username").get()
[{username=wlkjyy}, {username=qian}]
通过下面这个示例,你可以对分组后的money
进行求和
MyDB.table("users").select("username").addColumnSum("money","all_money").groupBy("username").get()
[{all_money=5, username=wlkjyy}, {all_money=1, username=qian}]
MyDB.table("users").where("active",1).limit(100).orderBy("id","asc").get()
等价于
MyDB.table("users").where("active",1).limit(100).orderBy("id").get()
多个orderBy排序
MyDB.table("users").where("active",1).limit(100).orderBy("id","asc").orderBy("username").get()
orderByAsc
和orderByDesc
可以对某个字段进行排序
例如下面这样
MyDB.table("users").orderByAsc("id").get()
他等价于
MyDB.table("users").orderBy("id","asc").get()
inRandomOrder
方法被用来将查询结果随机排序。例如,你可以使用这个方法去获得一个随机用户:
MyDB.table("users").inRandomOrder().first()
latest
和 oldest
方法可以方便让你把结果根据日期排序。查询结果默认根据数据表的 created_at
字段进行排序 。或者,你可以传一个你想要排序的列名,通过:
MyDB.table("users").select("uid").latest().get()
MyDB.table("users").select("uid").oldest().get()
当然也可以传入其他字段进行排序
MyDB.table("users").select("uid").latest("time").get()
reorder
方法可用于移除所有已存在的排序并且应用一个新的排序(可选):
MyDB.table("users").orderByAsc("id").reorder().first()
也可以这样做
MyDB.table("users").orderByAsc("id").reorder("id","desc").first()
通过select
可以设置只获取那些字段出来,如果不进行设置,默认情况下为*
,即所有字段
MyDB.table("users").select("uid").get()
输出为
[{uid=1}, {uid=2}, {uid=7}]
通过addSelect
可以动态的添加要查询的字段
MyDB.table("users").select("uid").addSelect("user").get()
你可以通过insert
方法向表中插入一条数据
MyDB.table("users").insert(new HashMap<>(){
{
put("username","admin");
put("password","123456");
}
})
对于查询,返回类型为ArrayList<HashMap<String, Object>>
,对于删除、更新、插入,返回类型为int
受影响的行数
MyDB.query("select * from `user`")
MyDB.query("select * from `admin` where `uid` = ?", new Object[]{1})
MyDB.update("update `user` set `cookie`=123123 where uid = 1")
MyDB.update("update `user` set `cookie`=123123 where uid = ?",new Object[]{
1
})
MyDB.delete("delete from `users` where `uid` = 1");
MyDB.delete("delete from `users` where `uid` = ?",new Object[]{
1
});
easyDB
允许用户传入一些简单的参数就可以自动生成前端分页代码或者输出json
格式的数据到前端。
db.table("users").paginate(15,1)
如果你希望使用自动分页器,那么你就不需要去使用get
、find
、first
方法去获取数据了,你需要直接使用paginate
来获取一个分页器实例。
paginate
方法包含3个参数,分别为每页的数量
、当前页
、分页参数
,其中分页参数
默认不传入情况下为page
,则URL路径为?page=1
你也可以这样
db.table("users").paginate(15,1,"pages")
在Springboot中你可以这样做
db.table("users").paginate(15,Integer.valueOf((String) request.getAttribute("pages")),"pages")
在springboot中可以这样实现
@GetMapping("/test")
public String index(Model model,HttpServletRequest request) {
Paginate paginate = db.table("users").paginate(15,Integer.valueOf((String) request.getAttribute("pages")),"pages");
model.addAttribute("paginate", paginate);
return "index";
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
[[${paginate.links()}]]
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:each="row:${paginate.item()}">
<span th:text="${row.id}"></span>
<span th:text="${row.username}"></span>
</div>
[[${paginate.links()}]]
</body>
</html>
easyDB
目前只支持渲染bootstrap5
的分页代码,你可以在Paginate.java
中实现自己的分页代码渲染逻辑。
通过links
方法渲染的HTML分页代码,默认情况下url
只包含page
分页参数,你可以使用下面方法添加更多的分页参数
[[${paginate.links("usertype=admin&local=admin")}]]
你也可以在创建分页器的时候指定分页参数
db.table("users").paginate(15,1).setParamter("username=admin")
你可以通过下面这个示例,将分页输出为json
@RestController
public class IndexController {
@Autowired
DB db;
@GetMapping("/test")
public String index(HttpServletRequest request) {
return db.table("users").paginate(15,1).toHashmap();
}
}
每一个分页器实例都提供了下列方法来获取分页信息:
方法 | 描述 |
---|---|
paginate.count() | 获取分页的总数据数量 |
paginate.currentPage() | 获取当前页码 |
paginate.hasPages() | 判断是否有分页 |
paginate.links() | 获取分页HTML渲染 |
paginate.setParamter() | 设置额外的分页参数 |
paginate.toHashmap() | 转换为hashmap |
paginate.count() | 获取当前分页的数据数量 |
paginate.items() | 获取当前分页的数据 |
paginate.lastPage() | 获取最后一页的页码 |
paginate.lastPageUrl() | 获取最后一页的URL |
paginate.firstPageUrl() | 获取第一页的URL |
paginate.nextPageUrl() | 获取下一页的URL |
paginate.onFirstPage() | 判断是否是第一页 |
paginate.perPage() | 获取每页的数量 |
paginate.previousPageUrl() | 获取上一页的URL |
paginate.total() | 获取数据总量 |
paginate.url() | 获取指定页的URL |
paginate.hasMorePages() | 是否有更多的页 |