Topshelf+Quartz.net+Dapper+Npoi(二)
quartznet
上篇说到quartznet这个东东,topshelf+quartznet有很多不错的文章,可以查看七七同学的文章(http://www.cnblogs.com/jys509/p/4628926.html)。这里我主要说说cron表达式,如果玩过linux下定时任务的肯定不陌生。
官方英文介绍地址:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html
cron expressions 整体上还是非常容易理解的,只有一点需要注意:"?"号的用法,看下文可以知道“?”可以用在 day of month 和 day of week中,他主要是为了解决如下场景,如:每月的1号的每小时的31分钟,正确的表达式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,因为这样代表每周的任意一天。
由7段构成:秒 分 时 日 月 星期 年(可选)
"-" :表示范围 MON-WED表示星期一到星期三
"," :表示列举 MON,WEB表示星期一和星期三
"*" :表是“每”,每月,每天,每周,每年等
"/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始
"?" :只能出现在日,星期段里面,表示不指定具体的值
"L" :只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
"W" :表示工作日,距离给定值最近的工作日
"#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=SUN...6=FRI,7=SAT)
官方实例
| Expression | Meaning |
|---|---|
| 0 0 12 * * ? | 每天中午12点触发 |
| 0 15 10 ? * * | 每天上午10:15触发 |
| 0 15 10 * * ? | 每天上午10:15触发 |
| 0 15 10 * * ? * | 每天上午10:15触发 |
| 0 15 10 * * ? 2005 | 2005年的每天上午10:15触发 |
| 0 * 14 * * ? | 在每天下午2点到下午2:59期间的每1分钟触发 |
| 0 0/5 14 * * ? | 在每天下午2点到下午2:55期间的每5分钟触发 |
| 0 0/5 14,18 * * ? | 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 |
| 0 0-5 14 * * ? | 在每天下午2点到下午2:05期间的每1分钟触发 |
| 0 10,44 14 ? 3 WED | 每年三月的星期三的下午2:10和2:44触发 |
| 0 15 10 ? * MON-FRI | 周一至周五的上午10:15触发 |
| 0 15 10 15 * ? | 每月15日上午10:15触发 |
| 0 15 10 L * ? | 每月最后一日的上午10:15触发 |
| 0 15 10 L-2 * ? | Fire at 10:15am on the 2nd-to-last last day of every month |
| 0 15 10 ? * 6L | 每月的最后一个星期五上午10:15触发 |
| 0 15 10 ? * 6L | Fire at 10:15am on the last Friday of every month |
| 0 15 10 ? * 6L 2002-2005 | 2002年至2005年的每月的最后一个星期五上午10:15触发 |
| 0 15 10 ? * 6#3 | 每月的第三个星期五上午10:15触发 |
| 0 0 12 1/5 * ? | Fire at 12pm (noon) every 5 days every month, starting on the first day of the month. |
| 0 11 11 11 11 ? | Fire every November 11th at 11:11am. |
class Program
{
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
HostFactory.Run(x =>
{
x.UseLog4Net();
x.Service<ServiceRunner>();
x.RunAsLocalSystem(); x.SetDescription("Windows服务导出数据");
x.SetDisplayName("QuartzTopShelf");
x.SetServiceName("QuartzTopShelfService");
x.EnablePauseAndContinue(); });
}
}
public class ServiceRunner : ServiceControl, ServiceSuspend
{
private readonly IScheduler scheduler; public ServiceRunner()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler();
} public bool Start(HostControl hostControl)
{
scheduler.Start();
return true;
} public bool Stop(HostControl hostControl)
{
scheduler.Shutdown(false);
return true;
} public bool Continue(HostControl hostControl)
{
scheduler.ResumeAll();
return true;
} public bool Pause(HostControl hostControl)
{
scheduler.PauseAll();
return true;
} }
Dapper
Dapper是一款轻量级ORM工具(Github)。如果你在小的项目中,使用Entity Framework、NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀。你又觉得ORM省时省力,这时Dapper 将是你不二的选择。
Dapper优势:
- 轻量。只有一个文件(SqlMapper.cs),编译完成之后只有120k(好象是变胖了)
- 速度快。Dapper的速度接近与IDataReader,取列表的数据超过了DataTable。
- 支持多种数据库。Dapper可以在所有Ado.net Providers下工作,包括sqlite, sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
- 可以映射一对一,一对多,多对多等多种关系。
- 性能高。通过Emit反射IDataReader的序列队列,来快速的得到和产生对象,性能不错。
- 支持FrameWork2.0,3.0,3.5,4.0,4.5
上篇已经说过我用dapper的原因,就是为了方便而已。(使用dapper可以不去考虑你的数据库是sqlserver还是mysql,上层只需要配置一下连接串就行,方便的很)
直接上代码(用的是仓储模式):
IRepository.cs
public interface IRepository<TEntity> where TEntity : class
{
object Insert(TEntity entity); void Insert(IList<TEntity> list); bool Update(TEntity entity); bool Delete(TEntity entity); TEntity GetEntity(int id); int GetCount(object predicate); /// <summary>
/// 分页获取数据
/// </summary>
/// <param name="predicate"></param>
/// <param name="page">页数</param>
/// <param name="resultsPerPage">每页数量</param>
/// <param name="sort">排序</param>
/// <returns></returns>
IList<TEntity> GetPageList(object predicate, int pageIndex, int pageSize, IList<ISort> sort); }
Repository.cs
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private string _connName = null;
/// <summary>
/// 数据库连接名称
/// </summary>
public string connName { set { _connName = value; } } public object Insert(TEntity entity)
{
using (var db = DbFactory.GetDatabase(_connName))
{ return db.Insert(entity);
}
} public void Insert(IList<TEntity> list)
{
using (var db = DbFactory.GetDatabase(_connName))
{
db.Insert<TEntity>(list);
}
} public bool Update(TEntity entity)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Update(entity);
}
} public bool Delete(TEntity entity)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Delete(entity);
}
} public IList<TEntity> GetList()
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.GetList<TEntity>().ToList();
}
}
public IList<TEntity> GetList(object predicate, IList<ISort> sort = null)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.GetList<TEntity>(predicate, sort).ToList();
} }
public IList<TEntity> GetPageList(object predicate, int pageIndex, int pageSize, IList<ISort> sort)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.GetPage<TEntity>(predicate, sort, pageIndex, pageSize).ToList();
}
} public int GetCount(object predicate)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Count<TEntity>(predicate);
}
} public TEntity GetEntity(int id)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Get<TEntity>(id);
}
}
public TEntity GetEntity(string id)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Get<TEntity>(id);
}
}
}
DbFactory.CS
public class DbFactory
{
/// 得到web.config里配置项的数据库连接字符串。
private static readonly ConnectionStringSettings _settings = ConfigurationManager.ConnectionStrings["XX"]; public static IDbConnection GetDbConnection(string connName = null)
{
ConnectionStringSettings settings = _settings;
if (connName != null)
settings = ConfigurationManager.ConnectionStrings[connName];
if (settings == null)
throw new Exception("数据库连接字符串不能为空!");
DbServerType type = (DbServerType)Enum.Parse(typeof(DbServerType), settings.ProviderName);
return GetDbConnection(settings.ConnectionString, type);
} public static IDbConnection GetDbConnection(string connStr, DbServerType type)
{
if (string.IsNullOrEmpty(connStr)) throw new Exception("数据库连接字符串不能为空!"); IDbConnection conn = null;
switch (type)
{
case DbServerType.MsSqlServer:
conn = new SqlConnection(connStr);
break;
case DbServerType.MySQL:
conn = new MySqlConnection(connStr);
break;
case DbServerType.SQLite:
case DbServerType.Orcale:
case DbServerType.DB2:
case DbServerType.MongoDB:
default:
throw new NotImplementedException("尚未实现对该数据库的支持!");
}
conn.Open();
return conn;
} public static IDatabase GetDatabase(string connName = null)
{
ConnectionStringSettings settings = _settings;
if (connName != null)
settings = ConfigurationManager.ConnectionStrings[connName];
if (settings == null)
throw new Exception("数据库连接字符串不能为空!");
DbServerType type = (DbServerType)Enum.Parse(typeof(DbServerType), settings.ProviderName);
return GetDatabase(settings.ConnectionString, type);
} public static IDatabase GetDatabase(string connStr, DbServerType type)
{
if (string.IsNullOrEmpty(connStr)) throw new Exception("数据库连接字符串不能为空!"); IDbConnection conn = null;
IDapperExtensionsConfiguration config = null;
ISqlGenerator sqlGenerator = null; switch (type)
{
case DbServerType.MsSqlServer:
conn = new SqlConnection(connStr);
config = new DapperExtensionsConfiguration(typeof(AutoClassMapper<>), new List<Assembly>(), new SqlServerDialect());
sqlGenerator = new SqlGeneratorImpl(config);
break;
case DbServerType.MySQL:
conn = new MySqlConnection(connStr);
config = new DapperExtensionsConfiguration(typeof(AutoClassMapper<>), new List<Assembly>(), new MySqlDialect());
sqlGenerator = new SqlGeneratorImpl(config);
break;
case DbServerType.SQLite:
case DbServerType.Orcale:
case DbServerType.DB2:
case DbServerType.MongoDB:
default:
throw new NotImplementedException("尚未实现对该数据库的支持!");
}
return new Database(conn, sqlGenerator);
}
}
NPOI
npoi没什么好说的,直接nuget上下载dll,就可以使用了,有兴趣的可以下载源码看看,用它做一些excel的样式也是很方便的。
public static class NPOIHelper
{
public static void ExportToFile(DataSet dataSet, string fileFullPath)
{
List<DataTable> dts = new List<DataTable>();
foreach (DataTable dt in dataSet.Tables) dts.Add(dt);
ExportToFile(dts, fileFullPath);
}
public static void ExportToFile(DataTable dataTable, string fileFullPath)
{
List<DataTable> dts = new List<DataTable>();
dts.Add(dataTable);
ExportToFile(dts, fileFullPath);
}
public static void ExportToFile(IEnumerable<DataTable> dataTables, string fileFullPath)
{
IWorkbook workbook = new XSSFWorkbook();
int i = ;
foreach (DataTable dt in dataTables)
{
string sheetName = string.IsNullOrEmpty(dt.TableName)
? "Sheet " + (++i).ToString()
: dt.TableName;
ISheet sheet = workbook.CreateSheet(sheetName); IRow headerRow = sheet.CreateRow();
for (int j = ; j < dt.Columns.Count; j++)
{
string columnName = string.IsNullOrEmpty(dt.Columns[j].ColumnName)
? "Column " + j.ToString()
: dt.Columns[j].ColumnName;
headerRow.CreateCell(j).SetCellValue(columnName);
} for (int a = ; a < dt.Rows.Count; a++)
{
DataRow dr = dt.Rows[a];
IRow row = sheet.CreateRow(a + );
for (int b = ; b < dt.Columns.Count; b++)
{
row.CreateCell(b).SetCellValue(dr[b] != DBNull.Value ? dr[b].ToString() : string.Empty);
}
}
} using (FileStream fs = File.Create(fileFullPath))
{
workbook.Write(fs);
}
} public static List<DataTable> GetDataTablesFrom(string xlsxFile)
{
if (!File.Exists(xlsxFile))
throw new FileNotFoundException("文件不存在"); List<DataTable> result = new List<DataTable>();
Stream stream = new MemoryStream(File.ReadAllBytes(xlsxFile));
IWorkbook workbook = new XSSFWorkbook(stream);
for (int i = ; i < workbook.NumberOfSheets; i++)
{
DataTable dt = new DataTable();
ISheet sheet = workbook.GetSheetAt(i);
IRow headerRow = sheet.GetRow(); int cellCount = headerRow.LastCellNum;
for (int j = headerRow.FirstCellNum; j < cellCount; j++)
{
DataColumn column = new DataColumn(headerRow.GetCell(j).StringCellValue);
dt.Columns.Add(column);
} int rowCount = sheet.LastRowNum;
for (int a = (sheet.FirstRowNum + ); a < rowCount; a++)
{
IRow row = sheet.GetRow(a);
if (row == null) continue; DataRow dr = dt.NewRow();
for (int b = row.FirstCellNum; b < cellCount; b++)
{
if (row.GetCell(b) == null) continue;
dr[b] = row.GetCell(b).ToString();
} dt.Rows.Add(dr);
}
result.Add(dt);
}
stream.Close(); return result;
}
}
好了,就说到这里吧,欢迎拍砖。
Topshelf+Quartz.net+Dapper+Npoi(二)的更多相关文章
- Topshelf+Quartz.net+Dapper+Npoi(一)
背景 前段时间公司有个需求(每天给业务导出一批数据,以excel的形式通过邮件发送给他).A说:直接写个服务,判断等于某个时间点,执行一下sql语句,生成excel,写个EmaiHelper发送给他不 ...
- .net core+topshelf+quartz创建windows定时任务服务
.net core+topshelf+quartz创建windows定时任务服务 准备工作 创建.net core 控制台应用程序,这里不做过多介绍 添加TopShelf包:TopShelf: 添加Q ...
- Dapper学习 - Dapper.Rainbow(二) - Update/Delete
上一篇介绍了Rainbow的Create方法, 这里就来介绍一下Update方法吧, 毕竟新增和修改是双胞兄弟嘛. 一.Update 1. 测试代码: var conStr = Configurati ...
- Spring的quartz定时器重复执行二次的问题解决
Spring的quartz定时器同一时刻重复执行二次的问题解决 最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此. 打印出他们的ha ...
- 轻量级ORM框架Dapper应用二:使用Dapper实现CURD操作
在上一篇文章中,讲解了如何安装Dapper,这篇文章中将会讲解如何使用Dapper使用CURD操作. 例子中使用到的实体类定义如下: using System; using System.Collec ...
- Topshelf+Quartz在.Net Core框架下的实现
在我们日常开发工作中,经常会运用到Quartz+Topshelf组件的组合来开发一些定时任务.那么在.Net Core下如何去使用呢?我自己尝试搭建了一个测试项目,过程中遇到了以下一些问题: Quar ...
- TopShelf+Quartz.net 实现window服务
Quartz.NET官网 TopShelf 网址 代码地址:https://github.com/SeaLee02/ProjectDemo/tree/master/WindowServerDemo ...
- Quartz.NET总结(二)CronTrigger和Cron表达式
Quartz.NET的任务调度,主要就是依靠CronTrigger和Cron表达式.Cron是已经在UNIX存在了很长一段时间,它有着强大和可靠的调度能力.CronTrigger类也正是是基于Cron ...
- TopShelf&Quartz.Net实现多任务的值守
很多时候,我们需要为一个服务器安装一堆的服务,来监控各种数据. 在windows服务器里,我们会部署专门的Quartz.Net多任务轮询服务. 同时,我们针对不同的任务制作专门的***Job.dll, ...
随机推荐
- 1102 Invert a Binary Tree (25 分)(二叉树遍历)
二叉树有N个结点,给出每个结点的左右孩子结点的编号,把二叉树反转(左右孩子交换 所以是后序遍历交换) 输出反转后二叉树的层序遍历和中序遍历 #include<bits/stdc++.h> ...
- Nginx下配置codeigniter框架
原来在winserver+Apache环境下工作良好的一个微信公众号后台迁移到阿里云(环境:Ubuntu 64位 | PHP5.4 | Nginx1.6)下却频出 404,403,只能访问CI rou ...
- 决策树之CART算法
顾名思义,CART算法(classification and regression tree)分类和回归算法,是一种应用广泛的决策树学习方法,既然是一种决策树学习方法,必然也满足决策树的几大步骤,即: ...
- 【bzoj1044】[HAOI2008]木棍分割 二分+dp
题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且 ...
- 用canvas实现鼠标拖动绘制矩形框
需要用到jCanvas插件和jQuery. jCanvas下载:https://raw.githubusercontent.com/caleb531/jcanvas/master/jcanvas.mi ...
- UVA 11478(差分约束 + 二分)
题意: 给定一个有向图,每条边都有一个权值,每次你可以选择一个结点和一个整数的,把所有以v为终点的边的权值减去d, 把所有以v为起点的边的权值加上d 最后要让所有边的权的最小值非负且尽量大 代码 #i ...
- chrome性能指标(TTFB,TTSR,TTDC,TTFL)
1.TTFB (Time To First Byte) 是最初的网络请求被发起到从服务器接收到第一个字节这段时间,它包含了 TCP连接时间,发送HTTP请求时间和获得响应消息第一个字节的时间. 注意: ...
- WebStrom Sass 编译配置 windows
第一步: 先安装Ruby下载 一路next 安装完成后打开开始菜单 打开后输入 gem install sass sass -v 出现版本号说明成功 第二部配置webstorm 在webstorm中s ...
- CI的多级目录的功能
https://segmentfault.com/q/1010000008317555?_ea=1621531
- 扩展欧几里得(ex_gcd),中国剩余定理(CRT)讲解 有代码
扩展欧几里得算法 求逆元就不说了. ax+by=c 这个怎么求,很好推. 设d=gcd(a,b) 满足d|c方程有解,否则无解. 扩展欧几里得求出来的解是 x是 ax+by=gcd(a,b)的解. 对 ...