Blog

mybatis动态sql-(2)-多次条件判断where和trim

在前面一中:

sql映射文件:只用到了if,如果 条件一 id 是null;

那么sql 语句 就成了select * from tbl_employee  where  and  id=#{id}   会报错

<select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
	 	select * from tbl_employee where
	 	
		 	<!-- test:判断表达式(OGNL)
		 	OGNL参照PPT或者官方文档。
		 	  	 c:if  test
		 	从参数中取值进行判断
		 	
		 	遇见特殊符号应该去写转义字符:
		 	&&:
		 	-->
		 	<if test="id!=null">
		 		id=#{id}
		 	</if>
		 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
		 		and last_name like #{lastName}
		 	</if>
		 	<if test="email!=null and email.trim()!=&quot;&quot;">
		 		and email=#{email}
		 	</if> 
		 	<!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
		 	<if test="gender==0 or gender==1">
		 	 	and gender=#{gender}
		 	</if>
	 	
	 </select>


</mapper>

查询的时候如果某些条件没带可能sql拼装会有问题。

一、SQL条件语句问题简单解决方法

1、将SQL语句写成select * from tbl_employee  where  1=1
后面的条件语句都写成: and xxx 之类的。
2、mybatis使用where标签来将所有的查询条件包括在内。mybatis就会将where标签中拼装的sql,多出来的and或者or去掉where只会去掉第一个多出来的and或者or。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.EmployeeMapperDynamicSQL">
<!-- 
上面的 namespace:名称空间;指定为接口的全类名
下面的 id:唯一标识被规定为接口方法名 【public Employee getEmpById(Integer id);】
下面的 resultType:返回值类型
下面的 #{id}:从传递过来的参数中取出id值
 -->
	
<!-- 
• if:判断
• choose (when, otherwise):分支选择;带了break的swtich-case
	如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个
• trim 字符串截取(where(封装查询条件), set(封装修改条件))
• foreach 遍历集合
	 -->
	 <!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 -->
	 <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
<select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
	 	select * from tbl_employee
	 	
	 	<!-- where -->
	 	<where>
		 	<!-- test:判断表达式(OGNL)
		 	OGNL参照PPT或者官方文档。
		 	  	 c:if  test
		 	从参数中取值进行判断
		 	
		 	遇见特殊符号应该去写转义字符:
		 	&&:
		 	-->
		 	<if test="id!=null">
		 		id=#{id}
		 	</if>
		 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
		 		and last_name like #{lastName}
		 	</if>
		 	<if test="email!=null and email.trim()!=&quot;&quot;">
		 		and email=#{email}
		 	</if> 
		 	<!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
		 	<if test="gender==0 or gender==1">
		 	 	and gender=#{gender}
		 	</if>
	 	</where>
	 </select>


</mapper>

二、SQL条件语句问题高级解决方法

采用 trim 字符串截取方法:

<!--public List<Employee> getEmpsByConditionTrim(Employee employee);  -->
 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
	 select * from tbl_employee
	 <!-- 后面多出的and或者or where标签不能解决 
	 prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
	 		prefix给拼串后的整个字符串加一个前缀 
	 prefixOverrides="":
	 		前缀覆盖: 去掉整个字符串前面多余的字符
	 suffix="":后缀
	 		suffix给拼串后的整个字符串加一个后缀 
	 suffixOverrides=""
	 		后缀覆盖:去掉整个字符串后面多余的字符
	 			
	 -->
	 <!-- 自定义字符串的截取规则 -->
	 <trim prefix="where" suffixOverrides="and">
	 	<if test="id!=null">
		 	id=#{id} and
		 </if>
		 <if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
		 	last_name like #{lastName} and
		 </if>
		 <if test="email!=null and email.trim()!=&quot;&quot;">
		 	email=#{email} and
		 </if> 
		 <!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
		 <if test="gender==0 or gender==1">
		 	 gender=#{gender}
		 </if>
	 </trim>
</select>

 

mybatis动态sql-(1)-多次条件判断If和OGNL

1、搭建数据库

tbl_employee表【d_id 是外键 对应 tbl_dept表】

id	last_name    gender	  email       d_id
1	   mike	       0      [email protected]      1
2          book        0      [email protected]    2
3          tom         1      [email protected]    2
4          jerry       1       [email protected]       1

tbl_dept表:

id    dept_name
1      开发部
2      测试部

2、编辑 javabean

特别要提醒:因为是在测试代码中,需要用到自定义Employee构造函数,所以这里为了能让mybatis正常使用反思,一定要添加Employee的无参构造函数。

Employee.java

package com.mybatis.bean;

public class Employee {
	private int id;
	private String lastName;
	private String email;
	private String gender;
	private Department department;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

       /*****  关键是 这个地方啊 出了 问题 ****/
	public Employee() {
		super();
	}
	/*****/
	public Employee(int id,String lastName, String  email, String gender){
		this.id =id;
		this.lastName =lastName;
		this.email =email;
		this.gender =gender;
	}

}

Department.java

package com.mybatis.bean;

import java.util.List;

public class Department {
	
	private Integer id;
	private String departmentName;
        private List<Employee> employees;
        
        public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName
				+ "]";
	}
	
	

}

三、编辑接口文件

EmployeeMapperDynamicSQL.java

package com.mybatis.mapper;

import java.util.List;

import com.mybatis.bean.Employee;

public interface EmployeeMapperDynamicSQL {

	//携带了哪个字段查询条件就带上这个字段的值
	public List<Employee> getEmpsByConditionIf(Employee employee);
	
}

四、SQL映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.EmployeeMapperDynamicSQL">
<!-- 
上面的 namespace:名称空间;指定为接口的全类名
下面的 id:唯一标识被规定为接口方法名 【public Employee getEmpById(Integer id);】
下面的 resultType:返回值类型
下面的 #{id}:从传递过来的参数中取出id值
 -->
	
<!-- 
• if:判断
• choose (when, otherwise):分支选择;带了break的swtich-case
	如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个
• trim 字符串截取(where(封装查询条件), set(封装修改条件))
• foreach 遍历集合
	 -->
	 <!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 -->
	 <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
<select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
	 	select * from tbl_employee
	 	where
                <!-- where -->
	 	
		 	<!-- test:判断表达式(OGNL)
		 	OGNL参照PPT或者官方文档。
		 	  	 c:if  test
		 	从参数中取值进行判断
		 	
		 	遇见特殊符号应该去写转义字符:
		 	&&:
		 	-->
		 	<if test="id!=null">
		 		id=#{id}
		 	</if>
		 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
		 		and last_name like #{lastName}
		 	</if>
		 	<if test="email!=null and email.trim()!=&quot;&quot;">
		 		and email=#{email}
		 	</if> 
		 	<!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
		 	<if test="gender==0 or gender==1">
		 	 	and gender=#{gender}
		 	</if>
	 	
	 </select>


</mapper>

五、全局配置文件

添加了,驼峰映射 大小写 自动转换 配置 setting。
因为从数据库中,选择出来了的就 只有5个字段,这5个字段,自动映射到Employee中,然后 d_id字段无法和bean中的department 属性映射,所以被废弃。department就为null了。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="Cool123!" />
			</dataSource>
		</environment>
	</environments>
	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 
	如果 数据库全局文件 和 子配置文件 不在同一个目录 ,就需要 /目录/目录/.../EmployeeMapper_old.xml
	-->
	<mappers>
	
	    <!-- 新方法操作mybatis 需要 的配置文件 -->
		<mapper resource="EmployeeMapperDynamicSQL.xml" />
	</mappers>
</configuration>

六、Junit单元测试

department属性,是没有赋值的,这里要注意一下。
sql语句的条件判断是OK的。

package com.mybatis.test;


import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.mybatis.bean.Employee;
import com.mybatis.mapper.EmployeeMapperDynamicSQL;


/**
 * 1、接口式编程
 * 	原生:		Dao		====>  DaoImpl
 * 	mybatis:	Mapper	====>  xxMapper.xml
 * 
 * 2、SqlSession代表和数据库的一次会话;用完必须关闭;
 * 3、SqlSession和connection一样她都是非线程安全。每次使用都应该去获取新的对象。(就是不要放在共享成员变量里面,A线程用完释放,B线程再用就为空了)
 * 4、mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。
 * 		(将接口和xml进行绑定)
 * 		EmployeeMapper empMapper =	sqlSession.getMapper(EmployeeMapper.class);
 * 5、两个重要的配置文件:
 * 		mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等...系统运行环境信息
 * 		sql映射文件:保存了每一个sql语句的映射信息:
 * 					将sql抽取出来。	
 *
 */

public class MybatisTest {


	public SqlSessionFactory getSqlSessionFactory() throws IOException {
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	@Test
	public void test_new() throws IOException {
		// 1、获取sqlSessionFactory对象
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		// 2、获取sqlSession对象
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			// 3、获取接口的实现类对象
			//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
			EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
			Employee employee = new Employee(3,"%m%","[email protected]","1");
			List<Employee> list = mapper.getEmpsByConditionIf(employee);
			for(Employee emp :list){
				System.out.println(emp);
				System.out.println(emp.getDepartment());

			}
		} finally {
			openSession.close();
		}

	}

}

 

mybatis基础-关键注意点bean的构造函数问题

当我用Junit单元测试,来学习mybatis时:

mybatis的bean文件中,采用的是默认构造函数。

当bean需要自定义构造函数时,一定要记得顺便 添加一个 无参构函数。因为mybatis用到了反射。无参构造函数是必须的。

如果自定义构造函数后,忘记添加了默认无参构造函数,那么就会报错。说缺少(,,,)形式的构造函数,但是不会说缺少无参构造函数。这个要注意啦。

 

测试踩坑-Junit单元测试时进程sleep连接数据库超时

最近,在用junit单元测试 mybatis。

发现偶尔会出现,代码全部是正确的,但是junit会在控制台 一直占用着,没有任何信息输出。也就是控制台 一直都是 显示 红点,按下红点,就能把控制台进程关闭了。

于是debug了一下,发现一直在连接数据库,然后超时的缘故。

估计了一下,应该是数据库没有任何返回信息,用mysql的客户端能连接,说明是eclipse的 数据库连接出 了问题,应该是eclipse 数据库连接 进程被占用了吧。

后来,我用 mac 系统的强制 关闭 eclipse,然后过一段时间 ,打开,发现 junit单元测试,终于打印出信息了,终于好用了啦。

fuck 终于找到原因了,是代理问题,我开了全局代理。导致eclipse 一直连接不上 mysql,后来关了代理  就行了。

java入门概述

Java 语言

跟任何编程语言一样,Java 语言拥有自己的结构、语法规则和编程范例。Java 语言的编程范例基于面向对象编程 (OOP) 的概念,该语言的特性支持这一概念。

Java 语言是 C 语言的一种衍生语言,所以它的语法规则与 C 语言的语法规则非常相似。例如,方法使代码模块化并使用花括号({ 和 })分隔,变量需要在使用之前声明。

在结构上,Java 语言以 作为开头。包是 Java 语言的命名空间机制。包中包含类,而类中包含方法、变量、常量等。您将在本学习路径中了解 Java 语言的各个部分。

Java 编译器

在 Java 平台编写程序时,您会在 .java 文件中编写源代码,然后编译它们。编译器针对语言的语法规则来检查代码,然后将字节码 写出到 .class 文件中。字节码是一组需要在 Java 虚拟机 (JVM) 上运行的指令。添加了这一抽象级别后,Java 编译器不同于其他语言编译器,其他编译器会写出适合运行程序的 CPU 芯片集的汇编语言指令。

JVM

在运行时,JVM 读取并解释 .class 文件,在编写的 JVM 的目标原生硬件平台上执行程序的指令。JVM 解释字节码就像 CPU 解释汇编语言指令一样。不同之处在于,JVM 是一个专为特定平台编写的软件。JVM 是 Java 语言的 “编写一次、随处运行” 原则的核心。您的代码可在任何拥有合适的 JVM 实现的芯片集上运行。JVM 可用于 Linux 和 Windows 等主要平台,在针对移动电话和爱好者芯片的 JVM 中也已实现了 Java 语言的子集。

垃圾收集器

Java 平台不会强制您时刻关注内存分配(或使用第三方库来完成此工作),它提供了开箱即用的内存管理功能。当您的 Java 应用程序在运行时创建一个对象实例时,JVM 会自动从 中为该对象分配内存空间— 堆是一个专门留给您的程序使用的内存池。Java 垃圾收集器 在后台运行,跟踪记录应用程序不再需要哪些对象并从它们回收内存。这种内存处理方法称为隐式内存管理,因为它不需要您编写任何内存处理代码。垃圾收集是 Java 平台性能的基本特征之一。

Java 开发工具包

下载 Java 开发工具包 (JDK),您会获得 — 包括编译器和其他工具 — 包含预构建的实用程序的完整类库,以帮助您完成最常见的应用程序开发任务。了解 JDK 包和库的范围的最佳方式是查阅 官方在线 Java API 文档— 也称为 Javadoc。可观看这个快速演示,了解如何浏览 Javadoc。

Java 运行时环境

Java 运行时环境(JRE;也称为 Java 运行时)包含 JVM、代码库和运行以 Java 语言编写的程序所必要的组件。JRE 可用于多种平台。您可依据 JRE 许可条款,在您的应用程序中自由地重新分发 JRE,为应用程序的用户提供一个运行您的软件的平台。JRE 包含在 JDK 中。


建议《Effective Java》、《Java编程思想》以及《重构:改善既有代码质量》是Java程序员必看书籍

1、java 值传递与 引用传递。【 深拷贝 与 浅拷贝 问题】

2、String 类问题

3、java 访问权限问题。【类的权限  和 类方法类变量的权限】

来自:https://www.ibm.com/developerworks/cn/java/j-perry-java-platform-overview/index.html

mysql脚本-mysql自动检测宕机重启并邮件通知

1、mysql检测运行状态:

### -ppassword  其中-p 代表密码参数  后面紧跟的是 password 代表数据库密码
mysqladmin -u root -ppassword ping

2、检测脚本:

#!/bin/bash

#  `  斜引号,代表 将命令行结果 返回值 传给 result 变量
 result=`mysqladmin -u root -pKing123456! ping`

# result=`/usr/bin/mysqladmin ping`

expected='mysqld is alive'

if [[ "$result" = "$expected" ]]

then

echo "mysqld is alive"

else

echo "It's dead - restart mysql"

# email subject

SUBJECT="[MYSQL ERROR] - Attempting to restart service"

# Email To ?

EMAIL="[email protected]"

# Email text/message

EMAILMESSAGE="/tmp/emailmessage.txt"

echo "$result was received"> $EMAILMESSAGE

echo "when we were expected $expected" >>$EMAILMESSAGE

# send an email using /bin/mail

mail -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE

sudo vncserver -kill :1

sudo systemctl restart mysqld

fi

3、将检测脚本放入定时器中:

### 编辑 用户 定时器文件
crontab -e
### 定义 每隔 半小时 检测 mysql 运行状态
*/30 * * * *  sh  /root/alarm/mysql-watch.sh

4、脚本文件中 发邮件功能解析

mail -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE

1、安装 sendmail 和 mailx
2、配置smtp文件
3、运行 脚本

参看sendmail配置smtp发邮件

bash-控制-定时器crontab概述

一、crontab介绍

在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron]。cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间。

cron的配置文件称为“crontab”,是“cron table”的简写。

crontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

二、crontab配置文件

1、用户任务调度配置文件

用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab文件都被保存在/var/spool/cron/用户名(包括root用户) 。其文件名与用户名一致,比如tom建的crontab任务对应的文件就是/var/spool/cron/tom。

用下面的命令,创建的crontab任务 ,就是放在 /var/spool/cron/用户名 文件中的。

crontab 
选项:
-e:编辑该用户的计时器设置;
-l:列出该用户的计时器设置;
-r:删除该用户的计时器设置;
-u<用户名称>:指定要设定计时器的用户名称。

crontab -e -u 用户名 (如果 -u 用户名 没填,就默认是编辑当前用户的crontab文件)

使用者权限文件如下:

/etc/cron.deny     该文件中所列用户不允许使用crontab命令
/etc/cron.allow    该文件中所列用户允许使用crontab命令
/var/spool/cron/   所有用户crontab文件存放的目录,以用户名命名

2、系统任务调度配置文件

系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。/etc/crontab 这个文件负责安排由系统管理员制定的维护系统以及其他任务的crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""HOME=/

# run-parts
51 * * * * root run-parts /etc/cron.hourly
24 7 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

前四行是用来配置crond任务运行的环境变量,第一行SHELL变量指定了系统要使用哪个shell,这里是bash,第二行PATH变量指定了系统执行命令的路径,第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户,第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。

3、默认crontab文件或脚本目录

/etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。实际使用时,我们可以把定时执行脚本,按需要放在任意地方。

三、编辑crontab任务

crontab文件的含义:用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:

minute   hour   day   month   week   command     顺序:分 时 日 月 周

其中:

  • minute: 表示分钟,可以是从0到59之间的任何整数。
  • hour:表示小时,可以是从0到23之间的任何整数。
  • day:表示日期,可以是从1到31之间的任何整数。
  • month:表示月份,可以是从1到12之间的任何整数。
  • week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
  • command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。

在以上各个字段中,还可以使用以下特殊字符:

  • 星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
  • 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
  • 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
  • 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

注意如果用如果命令用到%的话需要用\转义

# backup mysql
00 01 * * * mysqldump -u root --password=passwd-d mustang > /root/backups/mustang_$(date +\%Y\%m\%d_\%H\%M\%S).sql
01 01 * * * mysqldump -u root --password=passwd-t mustang > /root/backups/mustang-table_$(date +\%Y\%m\%d_\%H\%M\%S).sql

四、crontab 服务开关

/sbin/service crond start    //启动服务
/sbin/service crond stop     //关闭服务
/sbin/service crond restart  //重启服务
/sbin/service crond reload   //重新载入配置

查看crontab服务状态:

service crond status

手动启动crontab服务:

service crond start

查看crontab服务是否已设置为开机启动,执行命令:

ntsysv

加入开机自动启动:

chkconfig –level 35 crond on

五、crontab举例

每半个小时执行一次,检查mysql是否 奔溃,并重启 邮件通知

*/30 * * * *  sh  /root/alarm/mysql-watch.sh

每1分钟执行一次command

* * * * * command

每小时的第3和第15分钟执行

3,15 * * * * command

在上午8点到11点的第3和第15分钟执行

3,15 8-11 * * * command

每隔两天的上午8点到11点的第3和第15分钟执行

3,15 8-11 */2 * * command

每个星期一的上午8点到11点的第3和第15分钟执行

3,15 8-11 * * 1 command

每晚的21:30重启smb

30 21 * * * /etc/init.d/smb restart

每月1、10、22日的4 : 45重启smb

45 4 1,10,22 * * /etc/init.d/smb restart

每周六、周日的1:10重启smb

10 1 * * 6,0 /etc/init.d/smb restart

每天18 : 00至23 : 00之间每隔30分钟重启smb

0,30 18-23 * * * /etc/init.d/smb restart

每星期六的晚上11:00 pm重启smb

0 23 * * 6 /etc/init.d/smb restart

每一小时重启smb

* */1 * * * /etc/init.d/smb restart

晚上11点到早上7点之间,每隔一小时重启smb

* 23-7/1 * * * /etc/init.d/smb restart

每月的4号与每周一到周三的11点重启smb

0 11 4 * mon-wed /etc/init.d/smb restart

一月一号的4点重启smb

0 4 1 jan * /etc/init.d/smb restart

每小时执行/etc/cron.hourly目录内的脚本

01 * * * * root run-parts /etc/cron.hourly

六、crontab输出重定向

一般情况下:crontab 每成功执行一次,都会发送一封邮件给/var/spool/mail/$user【前提是本机装了邮件服务】
为了避免 比较频繁(如每分钟一次),或者命令输出内容较多的 crontab 任务 发送大量邮件,造成服务器满,所以在添加crontab命令时,最好都加上输出重定向到文件或者/dev/null中。如下

shell上:
0表示标准输入
1表示标准输出
2表示标准错误输出
> 默认为标准输出重定向,与 1> 相同
2>&1 意思是把 标准错误输出 重定向到 标准输出.
&>file 意思是把 标准输出 和 标准错误输出 都重定向到文件file中

在crontab末尾加上
>/dev/null 2>&1.
或者
&> /dev/null

例如
0 1 5 10 * /path/to/script.sh >/dev/null 2>&1
0 1 5 10 * /path/to/script.sh &> /dev/null

另外一种方法是编辑crontab
crontab -e
在第一行加入
MAILTO=""
保存退出

 

参考:

http://man.linuxde.net/crontab
https://www.cnblogs.com/juandx/p/4992465.html

密码和证书-CloudFlare Along with Let’s Encrypt

如何在cloudflare 上更新 leti‘s encrypt  的SSL 证书问题?

因为 用tls 1.0更新 ssl 证书,不能通过 cdn 代理,所以不能用了。直接用cloudflare 的ssl就行。

I Have Cloudflare activated in my site to hide the real IP of the VPS. In Addition to that I’ve also installed cloudflare apache mod so that I get correct IP addresses of my site visitors.

So, now., when trying to renew the certificate it is giving me errors., I can’t renew before disabling CloudFlare so the IP turns to the real one., and I really think this is not possible to maintain it every 3 months,

Is there any fix for the problem ?

OK, so you’re using the tls-sni-01 challenge to verify your domain. That isn’t going to work with CloudFlare active.

The best solution, IMHO, is to use the webroot challenge. That challenge works with a single file, which will pass through CloudFlares CDN services.


For the basic CloudFlare plans, there isn’t a way to import your own certificate, so you won’t be able to use a Let’s Encrypt certificate on the publicly-visible CloudFlare service, unless you pay for a plan that supports this option.

Many CloudFlare users won’t even benefit from a Let’s Encrypt certificate, because CloudFlare can give you its own certificate for use with your origin server (the server that you run that CloudFlare is proxying for). CloudFlare will accept that CloudFlare-issued certificate for HTTPS connections between its CDN service and your origin server, and it will issue its own publicly-trusted certificate for HTTPS connections between end-users and the CDN service.

If you do want to get a Let’s Encrypt certificate for the origin server, even though there might not be much of a reason to do so, you should note that the TLS-SNI-01 verification method doesn’t work if the Let’s Encrypt CA isn’t connecting directly to the origin service (which is true if you have CloudFlare in front of your site when you get the certificate!). Other verification methods, HTTP-01 and DNS-01, will work in this case by letting you post files on your site or update DNS records for your site.

来自:https://community.letsencrypt.org/t/how-to-use-cloudflare-along-with-lets-encrypt/29221

centos特有软件-邮件服务-mutt

1. 安装

sudo apt-get install msmtp

2. 设置配置文件

  • 新建~/.msmtprc
    account default
    host 发送邮件服务器名称
    port 25
    from 发信人
    auth plain
    user 发信人邮箱账号
    password 发信人邮箱密码
    logfile ~/.msmtp.log 日志存放位置
  • 新建~/.muttrc
    set sendmail=”/usr/bin/msmtp” msmtp 安装位置 (可以使用which msmtp获取)
    set use_from=yes
    set realname=”XX” 发信人名称
    set from=”XX” 发信人邮箱账号
    set envelope_from=yes
    set editor=”vim -nw”

3. 修改.muttrc 的权限

sudo chmod 0600 ~/.msmtprc
否则会提示:
“.msmtprc: contains secrets and therefore must have no more than user read/write permissions”

4. 发送邮件

  • echo “测试test” | mutt -s “test” [email protected]
    有邮件内容:直接发送,不会打开vim和邮件发送客户端
  • mutt [email protected] -s ‘test send mail’
    没有邮件内容:会打开vim编辑器和邮件客户端

5、使用mutt写邮件可这样:(还没测试过)

$ mutt -a <附件> -s <主题>
$ To: 输入收件人地址
启动vi写信,
写完信保存退出
:wq
然后 y 发信

参考:
https://www.jianshu.com/p/9187d4206d2f
http://www.chinastor.com/a/jishu/sendmail/0G391F2014.html

centos特有软件-邮件服务-sendEmail

sendEmail软件

闲麻烦 也可以直接使用sendEmail来发送邮件。
sendEmail是一款轻量级,巧小,无需安装的邮件发送命令。只需下载,解压就可以使用,不要和sendmail搞混掉了。官网地址:http://caspian.dotconf.net/menu/Software/SendEmail/

[root@Zabbix_Server ~]# wget http://caspian.dotconf.net/menu/Software/SendEmail/sendEmail-v1.56.tar.gz
[root@Zabbix_Server ~]#  tar zxvf sendEmail-v1.56.tar.gz 
[root@Zabbix_Server ~]# cp -a sendEmail-v1.56/sendEmail /usr/local/bin/
[root@Zabbix_Server ~]# ll /usr/local/bin/sendEmail 
-rwxr-xr-x 1 root root 80213 Sep 30  2009 /usr/local/bin/sendEmail
[root@Zabbix_Server ~]#  sendEmail -h

-f 表示发送者的邮箱
-t 表示接收者的邮箱
-cc 表示抄送发给谁
-bcc 表示暗抄送给谁
-o message-content-type=html   邮件内容的格式,html表示它是html格式
-o message-charset=utf8        邮件内容编码
-s 表示SMTP服务器的域名或者ip
-u 表示邮件的主题
-xu 表示SMTP验证的用户名
-xp 表示SMTP验证的密码(注意,这个密码貌似有限制,例如我用d!5neyland就不能被正确识别)
-m 邮件的内容
-a 要发送的附件

[root@Zabbix_Server sendEmail-v1.56]# /usr/local/bin/sendEmail -s smtp.51cto.com -xu [email protected] -xp 51cto2016 -f [email protected] -t [email protected] -u test -m 123456 -o message-content-type=text -o message-charset=gb2312 

Sep 20 10:20:19 zabbix_server sendEmail[6090]: Email was sent successfully!
[root@Zabbix_Server sendEmail-v1.56]#

发送成功之后会有如下提示:
Jul 29 15:02:53 e10074 sendEmail[26347]: Email was sent successfully!