当前位置: 首页 > wzjs >正文

网站界面设计如何实现功能美与形式美的统一网站续费服务商

网站界面设计如何实现功能美与形式美的统一,网站续费服务商,范湖网站建设团队,关键词优化的策略有哪些简介 使用内存数据库来测试mapper层的sql代码,这种方式可以让测试案例摆脱对数据库的依赖,进而变得可重复执行。 这里选择的内存数据库是h2,它是纯java编写的关系型数据库,开源免费,而且轻量级的,性能较好…

简介

使用内存数据库来测试mapper层的sql代码,这种方式可以让测试案例摆脱对数据库的依赖,进而变得可重复执行。

这里选择的内存数据库是h2,它是纯java编写的关系型数据库,开源免费,而且轻量级的,性能较好,可以内嵌进java应用中做内存数据库。

编写方式

开发一个比较基础的组件,必须要为mapper层写单元测试,当前项目之前的sql代码都没有单元测试,同时,每次代码合并时都要跑自动化测试,需要把之前所有的单元测试跑一遍。

在这样的背景下,考虑以内存数据库为基础来为mapper接口编写单元测试,它足够稳定,可以支持自动化测试。

被测代码的sql写在注解上。

实现步骤

基本原理:使用内存数据库,构建mabatis的运行环境

第一步:配置建表语句。在项目路径下,编写一个配置文件,里面是每张表的建表语句,要注意,h2数据库的建表语句和其他数据库的略有不同,它不支持索引,因为它的数据是在内存中。

第二步:配置mybatis运行环境

public class BaseMapperTestConfig {// 支持跨线程运行private static final ThreadLocal<SqlSession> threadLocalSession = new ThreadLocal<>();// 获取单个mapper接口的实例public static <T> T getMapper(Class<T> clazz) {// 配置MyBatis环境TransactionFactory transactionFactory = new JdbcTransactionFactory();Environment environment = new Environment("dev", transactionFactory, getDataSource());Configuration configuration = new Configuration(environment);// 添加Mapper扫描路径configuration.addMapper(clazz);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);SqlSession sqlSession = sqlSessionFactory.openSession();threadLocalSession.set(sqlSession);return sqlSession.getMapper(clazz);}// 获取多个mapper接口的实例,依照传入顺序依次返回public static List<Object> getMappers(Class<?> ...clazzs) {// 配置MyBatis环境TransactionFactory transactionFactory = new JdbcTransactionFactory();Environment environment = new Environment("dev", transactionFactory, getDataSource());Configuration configuration = new Configuration(environment);// 添加Mapper扫描路径for (Class<?> clazz : clazzs) {configuration.addMapper(clazz);}SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);SqlSession sqlSession = sqlSessionFactory.openSession();threadLocalSession.set(sqlSession);// 多个mapper要在同一个sqlSession之下List<Object> result = new ArrayList<>();for (Class<?> clazz : clazzs) {result.add(sqlSession.getMapper(clazz));}return result;}// 关闭sqlSessionpublic static void close() {SqlSession sqlSession = threadLocalSession.get();if (sqlSession != null) {sqlSession.close();threadLocalSession.remove();}}// 清空数据表public static void clearData(String tableName) throws SQLException {SqlSession sqlSession = threadLocalSession.get();if (sqlSession != null) {Connection connection = sqlSession.getConnection();Statement statement = connection.createStatement();String sql = "delete from " + tableName;// update类型的语句返回false,表示没有resultSet对象statement.execute(sql);statement.close();}}// 配置数据库连接池,这里就是使用了内存数据库private static DataSource getDataSource() {EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();return databaseBuilder.setType(EmbeddedDatabaseType.H2)// 设置数据库名称和锁超时时间,时间是10秒;启用mvcc;设置隔离级别是串行化。// 每次都使用不同的数据库实例.setName("testdb" + System.currentTimeMillis() +";LOCK_TIMEOUT=10000;MVCC=TRUE;LOCK_MODE=3").addScript("classpath:db/schema.sql") // 启动时初始化建表语句.build();}
}

第三步:单测案例,从之前配置好的mybatis环境中获取mapper实例,然后测试,每个单测运行前向数据库中插入一条数据,运行后删除数据,确保运行环境的稳定。

public class MapperTest {private static StudentMapper studentMapper;private final String TABLE_NAME = "t_student";@BeforeClasspublic static void init() {studentMapper = BaseMapperTestConfig.getMapper(StudentMapper.class);}@AfterClasspublic static void destroy() {BaseMapperTestConfig.close();}@Beforepublic void before() throws SQLException {PO po = createPO(1L, 2L);  // 单测执行前向数据库中插入一条数据studentMapper.insert(po);}@Afterpublic void after() throws SQLException {BaseMapperTestConfig.clearData(TABLE_NAME);  // 单测执行完之后清空数据库}@Testpublic void testInsert() {// 执行insert语句PO po = createPO(2L, 3L);int insertNum = studentMapper.insert(po);assert insertNum == 1;}public PO createPO(Long d1, Long d2) {// 创建一个po类}
}

总结:

  • 关键是在单测中配置mybatis的执行环境,这样可以避免启动spring容器,加快测试速度

  • 每个单测执行前,向数据库中插入固定的数据,执行完成后,情况数据库中的数据,保证测试环境的稳定。

  • h2数据库提供了web页面,供用户访问,不过这里并没有用到,建议用户在增删改查四个测试方法中做好充分的断言,保证数据的正确。

踩坑记录

h2数据库 并发修改异常

在使用内存数据库进行单元测试时,一个常见的问题是并发修改异常。这通常发生在多线程环境或多个测试类同时运行时。如果测试类在同一个JVM实例中运行,会共享同一个内存数据库实例,从而导致并发修改问题。

问题原因:

  • 内存数据库共享:在同一个 JVM 中,多个测试类共享同一个内存数据库实例,导致并发操作冲突。
  • 事务管理:测试类之间未正确隔离事务,导致并发操作冲突。
  • 数据库初始化:每个测试类分别进行数据库初始化时,可能会导致并发请求处理不当。

错误案例:获取锁超时,原因是并发修改。具体情况是,单独执行测试类没有问题,通过mvn clean test执行时,某些测试类就会报并发修改异常

org.apache.ibatis.exceptions.PersistenceException: ### Error updating database.  Cause: org.h2.jdbc.JdbcSQLTimeoutException: Timeout trying to lock table {0}; 
org.h2.message.DbException: Concurrent update in table "SCENE_SET_DEV": another transaction has updated or deleted the same row [90131-199]

解决方案

  1. 使用不同的数据库实例:为每个测试类使用独立的内存数据库实例
public class TestDataSourceConfig {private static DataSource getDataSource() {EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();return databaseBuilder.setType(EmbeddedDatabaseType.H2)// 设置数据库名称,每次都生成一个单独的数据库。// 锁超时时间,时间是10秒;// 启用mvcc;设置隔离级别是串行化;使用不同的数据库实例.setName("testdb" + System.currentTimeMillis() +";LOCK_TIMEOUT=10000;MVCC=TRUE;LOCK_MODE=3").addScript("classpath:db/schema.sql") // 启动时初始化建表语句.build();}
}

在这段代码中,通过加入 System.currentTimeMillis() 方法确保每次测试都使用唯一的数据库实例。

参考

  • https://www.jianshu.com/p/3f34b1c584c3
http://www.dtcms.com/wzjs/617330.html

相关文章:

  • 在网站后台管理系统里产品说明怎么添加图片昆山汽车网站建设
  • 中国建站公司张家界seo优化方案
  • 手机图片网站模板外贸网站建设方法
  • 怎么做购物网站的购物车个人做网站下载网上图可以吗
  • 做网站要学些什么条件wordpress用户权限在哪改
  • 专业外贸网站建设公司价格免费网站加速软件
  • 网站设置的关键词广州网站改版设计
  • 找人做网站要准备什么软件网站及微信建设是否涉及知识产权
  • 铜陵网站建设吾爱wordpress
  • 襄阳万家灯火网站建设西安做百度网站的
  • 成都有哪些做网站的俄罗斯乌克兰战争
  • 天津市城乡建设局网站做网站导航栏素材图
  • 网站模板及源码计算机网络技术主修课程
  • 求网站制作知名高端网站建设
  • 网站资料要提供哪些怎么在自己做的网站上发视频
  • 苍南网站制作php wordpress乱码
  • 上海网站注销太原网站怎么做seo
  • 为什么要做营销型网站服装详情页设计
  • 什么是个人网站js调用wordpress文章
  • 国外设计网站h开头福田瑞沃小金刚c版
  • 成都专业的网站建设公司网站域名实名认证通知
  • 山东网站建设公司哪家好美食网站建设项目分析报告
  • 常州网站建设流程玉溪网站制作
  • 企业做网站有用吗天涯wordpress 导出用户
  • 为什么企业建设银行网站打不开2024的新闻有哪些
  • 湖北省建设厅行政审批网站微信公众号端网站开发
  • 黔西南州建设局网站校园网站建设与管理
  • 面试建设单位在哪个网站推广什么意思
  • 杂志社网站建设方案安康微平台
  • 河南做网站推广哪个好百度网盘搜索引擎盘多多