All Projects → biezhi → Anima

biezhi / Anima

Licence: apache-2.0
Minimal database operation library.

Programming Languages

java
68154 projects - #9 most used programming language
java8
65 projects

Projects that are alternatives of or similar to Anima

Dynamic Data Source Demo
基于事务的读写分离
Stars: ✭ 43 (-79.52%)
Mutual labels:  transaction, database
Tupl
The Unnamed Persistence Library
Stars: ✭ 83 (-60.48%)
Mutual labels:  transaction, database
Laravel Transactional Model Events
Add eloquent model events fired after a transaction is committed or rolled back
Stars: ✭ 52 (-75.24%)
Mutual labels:  transaction, database
Active record doctor
Identify database issues before they hit production.
Stars: ✭ 865 (+311.9%)
Mutual labels:  activerecord, database
Gkvdb
[mirror] Go语言开发的基于DRH(Deep-Re-Hash)深度哈希分区算法的高性能高可用Key-Value嵌入式事务数据库。基于纯Go语言实现,具有优异的跨平台性,良好的高可用及文件IO复用设计,高效的底层数据库文件操作性能,支持原子操作、批量操作、事务操作、多表操作、多表事务、随机遍历等特性。
Stars: ✭ 109 (-48.1%)
Mutual labels:  transaction, database
Activerecord Sqlserver Adapter
SQL Server Adapter For Rails
Stars: ✭ 910 (+333.33%)
Mutual labels:  activerecord, database
Tidis
Distributed transactional NoSQL database, Redis protocol compatible using tikv as backend
Stars: ✭ 1,182 (+462.86%)
Mutual labels:  transaction, database
Zero downtime migrations
Zero downtime migrations with ActiveRecord 3+ and PostgreSQL
Stars: ✭ 513 (+144.29%)
Mutual labels:  activerecord, database
Counter culture
Turbo-charged counter caches for your Rails app.
Stars: ✭ 1,397 (+565.24%)
Mutual labels:  activerecord, database
Rexlin600.github.io
系列博客、涵盖领域广、不定时更新、欢迎加入
Stars: ✭ 102 (-51.43%)
Mutual labels:  transaction, database
Libmdbx
One of the fastest embeddable key-value ACID database without WAL. libmdbx surpasses the legendary LMDB in terms of reliability, features and performance.
Stars: ✭ 729 (+247.14%)
Mutual labels:  transaction, database
Querybuilder
SQL query builder, written in c#, helps you build complex queries easily, supports SqlServer, MySql, PostgreSql, Oracle, Sqlite and Firebird
Stars: ✭ 2,111 (+905.24%)
Mutual labels:  activerecord, database
Polo
Polo travels through your database and creates sample snapshots so you can work with real world data in development.
Stars: ✭ 695 (+230.95%)
Mutual labels:  activerecord, database
Active Record
Active Record database abstraction layer
Stars: ✭ 43 (-79.52%)
Mutual labels:  activerecord, database
Rein
Database constraints made easy for ActiveRecord.
Stars: ✭ 657 (+212.86%)
Mutual labels:  activerecord, database
Topaz
A simple and useful db wrapper for Crystal-lang
Stars: ✭ 56 (-73.33%)
Mutual labels:  activerecord, database
With advisory lock
Advisory locking for ActiveRecord
Stars: ✭ 409 (+94.76%)
Mutual labels:  activerecord, transaction
Database consistency
The tool to find inconsistency between models schema and database constraints.
Stars: ✭ 418 (+99.05%)
Mutual labels:  activerecord, database
Activerecord Clean Db Structure
Automatic cleanup for the Rails db/structure.sql file (ActiveRecord/PostgreSQL)
Stars: ✭ 101 (-51.9%)
Mutual labels:  activerecord, database
Radon
RadonDB is an open source, cloud-native MySQL database for building global, scalable cloud services
Stars: ✭ 1,584 (+654.29%)
Mutual labels:  transaction, database

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.

Document

Travis Build Codacy Badge codecov License Twitter URL

Feature

  • Simple DSL
  • H2、MySQL、SQLite、PostgreSQL、Oracle、SqlServer
  • Paging support
  • Flexible configuration
  • Connection pool support
  • Support LocalDateLocalDateTime
  • Support lambda expression
  • Relationship (hasOnehasManybelongsTo)
  • 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>io.github.biezhi</groupId>
    <artifactId>anima</artifactId>
    <version>0.2.7-SNAPSHOT</version>
</dependency>

Here's the RELEASE version.

As Gradle

compile 'io.github.biezhi:anima:0.2.6'

As Maven

<dependency>
    <groupId>io.github.biezhi</groupId>
    <artifactId>anima</artifactId>
    <version>0.2.6</version>
</dependency>

📒 Although Anima 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 the atomic method to complete a transaction. normally, the code will not throw an exception. when a RuntimeException is caught, the transaction will be rollback.

Test Code

See here

License

Apache2

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].