一款编程式、轻量级的持久层框架
TODO 整体情况
连接是非常宝贵的资源,频繁地创建和销毁连接会导致应用性能差,因此采用连接池来缓存连接,不需要频繁的建立和销毁。
(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);
}
}
TODO
在开始之前,先介绍一下一些约定
(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);
}
}
(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);
}
(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&useSSL=false&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);
}
}
- SQL DSL
- 自定义数据源缓存池
- 执行器,包含原生实现 & Spring JdbcTemplate集成
- 支持分库分表
- 支持原生SQL
- 支持多表连接查询
- 支持子查询
- 集成Spring Boot
- 支持返回主键
- 插件化
(1) tyrion-core 测试覆盖率
(2) tyrion-spring 测试覆盖率