byWeaponLin / tyrion

tyrion is a lightly programmatic persistence framework(developing)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

tyrion

一款编程式、轻量级的持久层框架

1 Architecture

TODO 整体情况

1.1 DSL

DSL设计一览

1.2 连接池

连接是非常宝贵的资源,频繁地创建和销毁连接会导致应用性能差,因此采用连接池来缓存连接,不需要频繁的建立和销毁。

(1)首先我们定义了一个连接池

public class ConnectionPool {

    /**
     * 空闲连接
     */
    private LinkedList<PooledConnection> idleConnections;
    /**
     * 繁忙连接
     */
    private LinkedList<PooledConnection> activeConnections;
}

(2)初始化连接池

public void initConnectionPool() {
    synchronized (ConnectionPool.class) {
        for (int i = 0; i < poolSize; i++) {
            try {
                Connection connection = DriverManager.getConnection(url, username, password);
                PooledConnection pooledConnection = new PooledConnection(connection, connectionPool);
                connectionPool.addPool(pooledConnection);
            } catch (Exception e) {
                log.error("init connection pool failed", e);
            }
        }
    }
}

(3)回收连接而不是销毁

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if ("close".equals(method.getName())) {
        connectionPool.recycle(this);
        return null;
    } else {
        return method.invoke(connection, args);
    }
}

1.3

TODO

2 Quick Start

在开始之前,先介绍一下一些约定

(1) 我们需要在实体类上标注@Table注解,同时需要填写database和table,其次在属性上面需要添加@Column注解,表明该属性对应数据库表的字段名。

@Table(database = "demo", table = "user")
public class User {

    @Id
    @Column(column = "id")
    private Long id;

    @Column(column = "name")
    private String name;

    @Column(column = "gender")
    private String gender;

    @Column(column = "age")
    private Integer age;
}

(2) Executor用法

// 定义UserDao接口
public interface UserDao {
    List getAllUser();
    int addUser(User user);
    // 其他接口忽略
}

UserDaoImpl里头需要定义Executor,最终用来执行SQL语句

public class UserDaoImpl implements UserDao {
    private final Executor executor;
    public UserDaoImpl(@NonNull Executor executor) {
        this.executor = executor;
    }

    @Override
    public List<User> getAllUser() {
        SQLParameter sqlParameter = DSL.select()
                .from(table(User.class))
                .build();
        return executor.selectList(sqlParameter);
    }

    @Override
    public int addUser(User user) {
        return executor.insert(user);
    }
}

2.1 原生demo

(1) 创建PooledDataSource & Executor & UserDao实例

PooledDatasource pooledDatasource = new PooledDatasource(
                "com.mysql.cj.jdbc.Driver",
                "jdbc:mysql://localhost:3306/demo?characterEncoding=utf8&useSSL=false&serverTimezone=UTC",
                "root",
                "weaponlin"
        );
Executor executor = new DefaultExecutor(pooledDatasource);
userDao = new UserDaoImpl(executor);

(2) 接下来就可以直接执行SQL,更多SQL执行可以查看RawApplication类

@Test
    public void get_all_user() {
        List<User> users = userDao.getAllUser();
        System.out.println(users);
    }

    @Test
    public void add_user() {
        User user = new User().setId(66L).setAge(10).setName("weapon").setGender("male");

        int affectedRows = userDao.addUser(user);
        assertEquals(1, affectedRows);

        User u = userDao.getUser(66L);
        assertNotNull(u);
        assertEquals(66L, u.getId().longValue());
        assertEquals(10, u.getAge().intValue());
        assertEquals("weapon", u.getName());
        assertEquals("male", u.getGender());

        affectedRows = userDao.deleteUser(66L);
        assertEquals(1, affectedRows);

        u = userDao.getUser(66L);
        assertNull(u);
    }

2.2 集成Spring demo

(1) 配置applicationContext

<!-- 1.配置数据源 -->
    <bean id="dataSource" class="com.weaponlin.inf.tyrion.datasource.PooledDatasource">
        <constructor-arg name="driver" value="com.mysql.cj.jdbc.Driver"></constructor-arg>
        <constructor-arg name="url"
                  value="jdbc:mysql://localhost:3306/demo?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC"></constructor-arg>
        <constructor-arg name="username" value="root"></constructor-arg>
        <constructor-arg name="password" value="weaponlin"></constructor-arg>
    </bean>

    <bean id="jdbcTemplateExecutor" class="com.weaponlin.inf.tyrion.spring.executor.JdbcTemplateExecutor">
        <constructor-arg name="pooledDatasource" ref="dataSource"/>
    </bean>

    <bean id="userDao" class="com.weaponlin.inf.tyrion.demo.dao.impl.UserDaoImpl">
        <constructor-arg name="executor" ref="jdbcTemplateExecutor"/>
    </bean>

(2) 直接使用userDao

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class SpringApplication {

    @Autowired
    private UserDao userDao;

    @Test
    public void get_all_user() {
        List<User> users = userDao.getAllUser();
        System.out.println(users);
    }

    @Test
    public void add_user() {
        User user = new User().setId(66L).setAge(10).setName("weapon").setGender("male");

        int affectedRows = userDao.addUser(user);
        assertEquals(1, affectedRows);

        User u = userDao.getUser(66L);
        assertNotNull(u);
        assertEquals(66L, u.getId().longValue());
        assertEquals(10, u.getAge().intValue());
        assertEquals("weapon", u.getName());
        assertEquals("male", u.getGender());

        affectedRows = userDao.deleteUser(66L);
        assertEquals(1, affectedRows);

        u = userDao.getUser(66L);
        assertNull(u);
    }
}

3 开发进度(in progress)

  • SQL DSL
  • 自定义数据源缓存池
  • 执行器,包含原生实现 & Spring JdbcTemplate集成
  • 支持分库分表
  • 支持原生SQL
  • 支持多表连接查询
  • 支持子查询
  • 集成Spring Boot
  • 支持返回主键
  • 插件化

4 测试相关

(1) tyrion-core 测试覆盖率

tyrion-core 测试覆盖率

(2) tyrion-spring 测试覆盖率

tyrion-spring 测试覆盖率

5 User Feedback

About

tyrion is a lightly programmatic persistence framework(developing)


Languages

Language:Java 100.0%