Springboot+Mybatis+Maven+Oracle+Cassandra+事务(Aop)+定时任务实现

来源:互联网 发布:网络感叹号怎么解决 编辑:程序博客网 时间:2024/06/11 09:40
本文将通过示例介绍Springboot,mybatis,maven,oracle,cassandra,事务,定时任务等框架的集成,因此业务不会复杂,供学习使用。

一.基础知识

1. Springboot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
Springboot特点:
1). 创建独立的Spring应用程序
2). 嵌入的Tomcat,无需部署WAR文件
3). 简化Maven配置
4). 自动配置Spring
5). 提供生产就绪型功能,如指标,健康检查和外部配置
6). 绝对没有代码生成和对XML没有要求配置

2. Mybatis

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
mybatis特点:
1). MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
2). MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
3). MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

3. Cassandra

Cassandra 的名称来源于希腊神话,是特洛伊的一位悲剧性的女先知的名字,因此项目的Logo是一只放光的眼睛。
Cassandra是一个高可靠的大规模分布式存储系统。高度可伸缩的、一致的、分布式的结构化key-value存储方案,集Google BigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。2007由facebook开发,2009年成为Apache的孵化项目。
Cassandra使用了Google BigTable的数据模型,与面向行的传统的关系型数据库不同,这是一种面向列的数据库,列被组织成为列族(Column Family),在数据库中增加一列非常方便。对于搜索和一般的结构化数据存储,这个结构足够丰富和有效。
Cassandra的系统架构与Dynamo一脉相承,是基于O(1)DHT(分布式哈希表)的完全P2P架构,与传统的基于Sharding的数据库集群相比,Cassandra可以几乎无缝地加入或删除节点,非常适于对于节点规模变化比较快的应用场景。
Cassandra的数据会写入多个节点,来保证数据的可靠性,在一致性、可用性和网络分区耐受能力(CAP)的折衷问题上,Cassandra比较灵活,用户在读取时可以指定要求所有副本一致(高一致性)、读到一个副本即可(高可用性)或是通过选举来确认多数副本一致即可(折衷)。这样,Cassandra可以适用于有节点、网络失效,以及多数据中心的场景。
1). 列表数据结构
在混合模式可以将超级列添加到5维的分布式Key-Value存储系统。
2). 模式灵活
使用Cassandra,你不必提前解决记录中的字段。你可以在系统运行时随意的添加或移除字段。
3). 真正的可扩展性
Cassandra是纯粹意义上的水平扩展。为给集群添加更多容量,可以增加动态添加节点即可。你不必重启任何进程,改变应用查询,或手动迁移任何数据。
4). 多数据中心识别
你可以调整节点布局来避免某一个数据中心起火,一个备用的数据中心将至少有每条记录的完全复制。
5). 范围查询
如果你不喜欢全部的键值查询,则可以设置键的范围来查询。
6). 分布式写操作
你以在任何地方任何时间集中读或写任何数据。并且不会有任何单点失败。

4.Springboot集成框架

1).spring-boot-starter-data-cassandra
2).mybatis-spring-boot-starter
3).spring-boot-starter-aop

二.业务需求

定时同步cassandra数据库数据到oracle数据库

三.代码示例

1. 代码目录


2.application.properties配置文件

# loggerlogging.level.root=info##########################mybatis#######################################mybatis.config-locations=classpath:mybatis/mybatis-config.xmlmybatis.mapper-locations=classpath:mybatis/mapper/*.xml##########################数据库连接池########################################单一数据源spring.datasource.primary.url=jdbc:oracle:thin:@ip:1521/dwracspring.datasource.primary.username=rootspring.datasource.primary.password=rootspring.datasource.primary.driver-class-name=oracle.jdbc.driver.OracleDriverspring.datasource.primary.min-idle=5 spring.datasource.primary.max-active= 10spring.datasource.primary.max-idle=10#测试连接语句spring.datasource.primary.connection-test-query=SELECT 1 FROM DUALspring.datasource.primary.test-while-idle=truespring.datasource.primary.test-on-borrow=false##########################cassandra数据库#######################################spring.data.cassandra.keyspace-name=ups#测试环境spring.data.cassandra.contact-points=ipspring.data.cassandra.username= casrootspring.data.cassandra.port= 9042spring.data.cassandra.password= root################################定时任务信息#########################################syncTask.cron=0 0 0/1 * * ?
注意:
1) 配置mybatis时,需要在相应路径位置建立*.xml文件

3. oracle数据源配置

package com.lm.springboot_mybatis_oracle_cassandra.datasource;import javax.sql.DataSource;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.SqlSessionTemplate;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;/** * 主数据源配置(可配多数据源) *  * @author liangming.deng * @date 2017年6月9日 * */@Configuration@MapperScan(basePackages = "com.lm.springboot_mybatis_oracle_cassandra.mapper", sqlSessionTemplateRef = "primarySqlSessionTemplate")@EnableTransactionManagementpublic class DataSourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() {  return DataSourceBuilder.create().build(); } @Bean(name = "primarySqlSessionFactory") public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource)   throws Exception {  SqlSessionFactoryBean bean = new SqlSessionFactoryBean();  bean.setDataSource(dataSource);  bean.setMapperLocations(    new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*.xml"));  return bean.getObject(); } @Bean(name = "primaryTransactionManager") public DataSourceTransactionManager primaryTransactionManager(   @Qualifier("primaryDataSource") DataSource dataSource) {  return new DataSourceTransactionManager(dataSource); } @Bean(name = "primarySqlSessionTemplate") public SqlSessionTemplate primarySqlSessionTemplate(   @Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {  return new SqlSessionTemplate(sqlSessionFactory); }}
注意:
1) 配置mapper自动扫描包:@MapperScan
2) 数据源name需要与properties中配置文件对应:name="primaryDataSource"

3. 事务Aop控制

package com.lm.springboot_mybatis_oracle_cassandra.datasource;import java.util.Calendar;import javax.sql.DataSource;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.DefaultTransactionDefinition;/** * aop事务控制 *  * @author liangming.deng * @date 2017年6月9日 * */@Aspect@Configurationpublic class TranscationAop { private static Logger logger = LoggerFactory.getLogger(TranscationAop.class); @Autowired PlatformTransactionManager transactionManager; /**  * 注入dataSource  *   * @param dataSource  * @return  */ @Bean public PlatformTransactionManager txManager(@Qualifier("primaryDataSource") DataSource dataSource) {  return new DataSourceTransactionManager(dataSource); } /**  * 定义事务扫描包  */ @Pointcut("execution(* com.lm.springboot_mybatis_oracle_cassandra.service..*.*(..))") public void service() { } /**  * 环绕通知 事务  *   * @param pjp  * @return  */ @Around("service()") public Object tran(ProceedingJoinPoint pjp) {  long startTimeLong = Calendar.getInstance().getTimeInMillis();  TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());  String classInfo = getClassInfo(pjp);  try {   pjp.proceed();  } catch (Throwable throwable) {   logger.error(classInfo + " 异常 事务回滚 :" + throwable.getMessage());   transactionManager.rollback(transactionStatus);   return null;  }  transactionManager.commit(transactionStatus);  long endTimeLong = Calendar.getInstance().getTimeInMillis();  logger.info(classInfo + " 事务提交成功,耗时:" + (endTimeLong - startTimeLong));  return null; } /**  * 获取className和method  *   * @param pjp  * @return  */ private static String getClassInfo(ProceedingJoinPoint pjp) {  StringBuilder sBuilder = new StringBuilder();  if (null == pjp) {   return sBuilder.toString();  }  sBuilder.append(pjp.getTarget().getClass().getSimpleName()).append(" ").append(pjp.getSignature().getName());  return sBuilder.toString(); }}
注意:
1) 注入指定的数据源
2) 环绕通知事务处理

4. cassandra获取数据实现

package com.lm.springboot_mybatis_oracle_cassandra.dao.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.cassandra.core.CassandraTemplate;import org.springframework.stereotype.Repository;import com.lm.springboot_mybatis_oracle_cassandra.dao.UpsCalendarCassandraDao;import com.lm.springboot_mybatis_oracle_cassandra.entity.UpsCalendarEntity;/*** 获取cassandra数据库数据dao实现* @author liangming.deng* @date 2017年6月9日**/@Repositorypublic class UpsCalendarCassandraDaoImpl implements UpsCalendarCassandraDao {@Autowiredprivate CassandraTemplate cassandraTemplate;@Overridepublic List<UpsCalendarEntity> getAll() {return cassandraTemplate.select("SELECT ID, NAME, DESCRIPTION, ORG_ID, IS_ACTIVE, CREATED, CREATEDBY, UPDATED,UPDATEDBY FROM UPS_CALENDAR",UpsCalendarEntity.class);}}
注意:
1)通过CassandraTemplate实现数据获取,具体可以查询springboot-cassandra集成api

5.service数据业务

package com.lm.springboot_mybatis_oracle_cassandra.service.impl;import java.util.List;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.lm.springboot_mybatis_oracle_cassandra.dao.UpsCalendarCassandraDao;import com.lm.springboot_mybatis_oracle_cassandra.entity.UpsCalendarEntity;import com.lm.springboot_mybatis_oracle_cassandra.mapper.UpsCalendarMapper;import com.lm.springboot_mybatis_oracle_cassandra.service.UpsCalendarService;@Servicepublic class UpsCalendarServiceImpl implements UpsCalendarService {private static Logger logger = LoggerFactory.getLogger(UpsCalendarServiceImpl.class);@Autowiredprivate UpsCalendarCassandraDao UpsCalendarCassandraDao;@Autowiredprivate UpsCalendarMapper UpsCalendarMapper;@Overridepublic void batchSaveCassandraToOracle() {List<UpsCalendarEntity> UpsCalendars = null;// 1.获取cassandra数据UpsCalendars = UpsCalendarCassandraDao.getAll();// 2.删除oracle数据UpsCalendarMapper.delete();// 3.批量增加oracle数据UpsCalendarMapper.batchInsert(UpsCalendars);logger.info("batchSaveCassandraToOracle finish");}@Overridepublic void batchSaveExceptionCassandraToOracle() {List<UpsCalendarEntity> UpsCalendars = null;// 1.获取cassandra数据UpsCalendars = UpsCalendarCassandraDao.getAll();// 2.删除oracle数据UpsCalendarMapper.delete();//手动给出异常int j = 1 / 0;// 3.批量增加oracle数据UpsCalendarMapper.batchInsert(UpsCalendars);logger.info("batchSaveCassandraToOracle finish");}}
注意:
batchSaveCassandraToOracle:正常逻辑
batchSaveExceptionCassandraToOracle:异常逻辑,事务回滚

6.定时任务

package com.lm.springboot_mybatis_oracle_cassandra.task;import javax.annotation.PostConstruct;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Lazy;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import com.lm.springboot_mybatis_oracle_cassandra.service.UpsCalendarService;@Component@Lazy(value = false)public class SyncTask { private static Logger LOGGER = LoggerFactory.getLogger(SyncTask.class); @Autowired private UpsCalendarService upsCalendarService; @PostConstruct @Scheduled(cron = "${syncTask.cron}") public void syncCassandraToOracle() {  LOGGER.info("SyncTask syncCassandraToOracle start sync...");  upsCalendarService.batchSaveCassandraToOracle();  upsCalendarService.batchSaveExceptionCassandraToOracle();  LOGGER.info("SyncTask syncCassandraToOracle end sync..."); }}
注意:
1) 配置文件读取定时任务cron: @Scheduled(cron = "${syncTask.cron}")
2) 启动程序就执行定时任务:@PostConstruct

7.实例演示


四.代码地址

oschina:http://git.oschina.net/a123demi/springboot_mybatis_oracle_cassandra
csdn:http://download.csdn.net/detail/a123demi/9865580
原创粉丝点击