Minimal database operation library.
APACHE-2.0 License
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.
LocalDate
、LocalDateTime
hasOne
、hasMany
、belongsTo
)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>
📒 Although
Anima
can also be used by adding a jar package, we do not recommend doing this.
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)
)
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);
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.
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();
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();
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
.
See here