当前位置: 首页 > 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/558353.html

相关文章:

  • 怎么学做一件完整衣服网站北京市规划网站
  • 网站维护服务器WordPress上展示PDF
  • 广州建站业务公司济南网站建设咨询小七
  • 网站权重转移做排名博客主题Wordpress
  • 广州网站推广哪家强检察机关门户网站建设自查报告
  • 旅行做攻略的网站wordpress只在首页显示不出来
  • 制作一个网站平台需要多少钱做网站算软件行业吗
  • 站长工具综合查询2020教育集团网站设计策划书
  • 怎样建一个收费网站杭州建设职业学校网站
  • 古典网站素材网页链接制作生成二维码
  • 知乎有趣的网站符合网络营销的网站
  • 网站织梦设计制作效果图
  • 网站升级公告模板上海沪港建设咨询有限公司网站
  • 网站公司建设 中山网站怎么做定位功能
  • 右翼网站佛山网站建设全方位服务
  • 建设银行上海黄浦支行网站织梦网站模板还原的文件在哪里
  • 学做网站开发要1万6游戏代理平台免费版
  • 用php 如何做网站做房产网站长
  • wordpress用户登录后志鸿优化设计官网
  • 花钱做网站不给源码活动策划网站
  • 网站建设qianhaiyou网站建设的安全防护方法
  • 可信网站是否有规定必须做惠州做棋牌网站建设哪家技术好
  • 广东住房城乡建设厅网站首页做外贸一般总浏览的网站
  • 南京网站制作wordpress新增标题
  • 忘记网站后台用户名网站宣传高新技术企业
  • 甘肃省建设厅网站首页建筑安全员证查询网上查询
  • 设计网站与建设祁东县建设局网站
  • 佛山模板建站定制网站德国购物网站大全
  • 做一个网站怎么做的吗长沙网站建站公司
  • 网站设计培训机构南宁网站建设智能优化