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, ...
随机推荐
- 【志银】Win764位配置Github环境及将代码部署到Github pages-志银强势总结
(软件及教程下载分享:链接:http://pan.baidu.com/s/1dFysay9 密码:pug0) 1-安装Git-2.9.2-64-bit.exe(解压安装文件,运行安装程序,除了记得修改 ...
- 巧用Fiddler代理来禁止资源缓存,从而达到每次都是从服务器加载最新的资源
Fiddler -> Rules -> Performance -> Disable Caching 直接设置禁用缓存,再在没有清除缓存功能的APP 中重新加载最新的页面, 每 ...
- mac book pro 安装keras (无gpu)
转自http://www.jianshu.com/p/01dc42595733 注:Macbook pro 13' 没有NVIDIA的显卡,没办法CUDA编程,所以下面都是CPU编程. 1. 安装ho ...
- 浅析Kerberos原理,及其应用和管理
文章作者:luxianghao 文章来源:http://www.cnblogs.com/luxianghao/p/5269739.html 转载请注明,谢谢合作. 免责声明:文章内容仅代表个人观点, ...
- 【bzoj4974】字符串大师 逆模拟KMP
题目描述 一个串T是S的循环节,当且仅当存在正整数k,使得S是$T^k$(即T重复k次)的前缀,比如abcd是abcdabcdab的循环节.给定一个长度为n的仅由小写字符构成的字符串S,请对于每个k( ...
- P2324 [SCOI2005]骑士精神
题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位.两组数据之间没有空行. 输出格式 ...
- [poj] 3068 "Shortest" pair of paths || 最小费用最大流
[原题](http://poj.org/problem?id=3068) 给一个有向带权图,求两条从0-N-1的路径,使它们没有公共点且边权和最小 . //是不是像传纸条啊- 是否可行只要判断最后最大 ...
- 算法复习———dijkstra求次短路(poj3255)
题目: Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her ...
- Codeforces 934.B A Prosperous Lot
B. A Prosperous Lot time limit per test 1 second memory limit per test 256 megabytes input standard ...
- bzoj 2671 莫比乌斯反演
Calc Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 451 Solved: 234[Submit][Status][Discuss] Descr ...