Anima
Anima
allows you to query database like SQL
and Stream
.
a simple DSL syntax, supports multiple databases, integrates well with Java8,
supports multiple relational mappings, and is a database manipulation tool.
Feature
- Simple DSL
- H2、MySQL、SQLite、PostgreSQL、Oracle、SqlServer
- Paging support
- Flexible configuration
- Connection pool support
- Support
LocalDate
、LocalDateTime
- Support lambda expression
- Relationship (
hasOne
、hasMany
、belongsTo
) - SQL performance statistics
- Based Java8
Usage
Latest snapshot version
If you want to prioritize new features or some BUG fixes you can use it, you need to specify the snapshot repository in
pom.xml
<repository>
<id>snapshots-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<dependency>
<groupId>com.hellokaton</groupId>
<artifactId>anima</artifactId>
<version>0.3.1</version>
</dependency>
Here's the RELEASE
version.
As Gradle
compile 'com.hellokaton:anima:0.3.1'
As Maven
<dependency>
<groupId>com.hellokaton</groupId>
<artifactId>anima</artifactId>
<version>0.3.1</version>
</dependency>
📒 AlthoughAnima
can also be used by adding a jar package, we do not recommend doing this.
Examples
Open Connection
// MySQL
Anima.open("jdbc:mysql://127.0.0.1:3306/demo", "root", "123456");
// SQLite
Anima.open("jdbc:sqlite:./demo.db");
// H2
Anima.open("jdbc:h2:file:~/demo;FILE_LOCK=FS;PAGE_SIZE=1024;CACHE_SIZE=8192", "sa", "");
// DataSource
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(blade.environment().getOrNull("jdbc.url"));
dataSource.setUsername(blade.environment().getOrNull("jdbc.username"));
dataSource.setPassword(blade.environment().getOrNull("jdbc.password"));
Anima.open(dataSource);
📕 This operation only needs one time
public class User extends Model {
private Integer id;
private String userName;
private Integer age;
public User() {
}
public User(String userName, Integer age) {
this.userName = userName;
this.age = age;
}
}
Table Structure
CREATE TABLE `users` (
`id` IDENTITY PRIMARY KEY,
`user_name` varchar(50) NOT NULL,
`age` int(11)
)
Query
long count = select().from(User.class).count();
// SELECT COUNT(*) FROM users
long count = select().from(User.class).where("age > ?", 15).isNotNull("user_name").count();
// SELECT COUNT(*) FROM users WHERE age > ? AND user_name IS NOT NULL
User user = select().from(User.class).byId(2);
// SELECT * FROM users WHERE id = ?
List<User> users = select().from(User.class).byIds(1, 2, 3);
// SELECT * FROM users WHERE id IN (?, ?, ?)
String name = select().bySQL(String.class, "select user_name from users limit 1").one();
List<String> names = select().bySQL(String.class, "select user_name from users limit ?", 3);
List<User> users = select().from(User.class).all();
// SELECT * FROM users
List<User> users = select().from(User.class).like("user_name", "%o%").all();
// SELECT * FROM users WHERE user_name LIKE ?
Limit
List<User> users = select().from(User.class).order("id desc").limit(5);
// SELECT * FROM users ORDER BY id desc
Paging
Page<User> userPage = select().from(User.class).order("id desc").page(1, 3);
// SELECT * FROM users ORDER BY id desc LIMIT ?, ?
Map
select().from(User.class).map(User::getUserName).limit(3).collect(Collectors.toList());
Filter
select().from(User.class).filter(u -> u.getAge() > 10).collect(Collectors.toList());
Lambda
User user = select().from(User.class).where(User::getUserName).eq("jack").one();
// SELECT * FROM users WHERE user_name = ?
List<User> user = select().from(User.class)
.where(User::getUserName).notNull()
.and(User::getAge).gt(10)
.all();
// SELECT * FROM users WHERE user_name IS NOT NULL AND age > ?
select().from(User.class).order(User::getId, OrderBy.DESC).order(User::getAge, OrderBy.ASC).all();
// SELECT * FROM users ORDER BY id DESC, age ASC
Join
@Table(name = "order_info")
@Data
public class OrderInfo extends Model {
private Long id;
private Integer uid;
@Column(name = "productname")
private String productName;
private LocalDateTime createTime;
@Ignore
private User user;
@Ignore
private Address address;
}
// HasOne
OrderInfo orderInfo = select().from(OrderInfo.class)
.join(
Joins.with(Address.class).as(OrderInfo::getAddress)
.on(OrderInfo::getId, Address::getOrderId)
).byId(3);
orderInfo = select().from(OrderInfo.class)
.join(
Joins.with(Address.class).as(OrderInfo::getAddress)
.on(OrderInfo::getId, Address::getOrderId)
)
.join(
Joins.with(User.class).as(OrderInfo::getUser)
.on(OrderInfo::getUid, User::getId)
).byId(3);
// ManyToOne
orderInfo = select().from(OrderInfo.class)
.join(
Joins.with(User.class).as(OrderInfo::getUser)
.on(OrderInfo::getUid, User::getId)
).byId(3);
// OneToMany
UserDto userDto = select().from(UserDto.class).join(
Joins.with(OrderInfo.class).as(UserDto::getOrders)
.on(UserDto::getId, OrderInfo::getUid)
).byId(1);
Insert
Integer id = new User("biezhi", 100).save().asInt();
// INSERT INTO users(id,user_name,age) VALUES (?,?,?)
or
Anima.save(new User("jack", 100));
Batch Save
List<User> users = new ArrayList<>();
users.add(new User("user1", 10));
users.add(new User("user2", 11));
users.add(new User("user3", 12));
Anima.saveBatch(users);
📘 This operation will begin a transaction and rollback when there is a transaction that is unsuccessful.
Update
int result = update().from(User.class).set("user_name", newName).where("id", 1).execute();
// UPDATE users SET username = ? WHERE id = ?
or
int result = update().from(User.class).set("user_name", newName).where("id", 1).execute();
// UPDATE users SET user_name = ? WHERE id = ?
or
User user = new User();
user.setId(1);
user.setUserName("jack");
user.update();
// UPDATE users SET user_name = ? WHERE id = ?
update().from(User.class).set(User::getUserName, "base64").updateById(2);
update().from(User.class).set(User::getUserName, "base64").where(User::getId).eq(2).execute();
Delete
int result = delete().from(User.class).where("id", 1).execute();
// DELETE FROM users WHERE id = ?
or
User user = new User();
user.setAge(15);
user.setUserName("jack");
user.delete();
// DELETE FROM users WHERE user_name = ? and age = ?
delete().from(User.class).where(User::getId).deleteById(3);
delete().from(User.class).where(User::getId).eq(1).execute();
delete().from(User.class).where(User::getAge).lte(20).execute();
Transaction
Anima.atomic(() -> {
int a = 1 / 0;
new User("apple", 666).save();
}).catchException(e -> Assert.assertEquals(ArithmeticException.class, e.getClass()));
📗 Anima
uses theatomic
method to complete a transaction. normally, the code will not throw an exception. when aRuntimeException
is caught, the transaction will berollback
.
Test Code
See here