canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费
canal 作为 MySQL binlog 增量获取和解析工具,可将变更记录投递到 MQ 系统中,比如 Kafka/RocketMQ,可以借助于 MQ 的多语言能力
【第四节为业务代码说明】
canal官网https://github.com/alibaba/canal/
早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。
当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x
做了一个教培机构的运营管理平台(以下称为A),机构还有另外一个系统是专门做教学服务的授课平台(以下称为B)。在业务场景下B平台中,所有的基础业务数据都来自于A平台。
所以当A平台数据增加,修改,删除等等发生业务扭转时都需要通知B平台。
业务数据修改的地方太多,如果将同步触发写在代码中地方太多找不清楚也会不便于后期维护,所以开始了解canal数据源监听。
[mysqld]
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
注意 : 关闭所有机器的防火墙,同时注意启动可以相互telnet ip 端口
官方参考:https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart
将canal.deployer-1.1.4.tar.gz 上传到服务器并解压
#################################################
## mysql serverId , v1.0.26+ will autoGen
canal.instance.mysql.slaveId=12345
# enable gtid use true/false
canal.instance.gtidon=false
# position info
canal.instance.master.address=192.168.1.20:3306
# username/password,数据库的用户名和密码
canal.instance.dbUsername=root
canal.instance.dbPassword=root
canal.instance.connectionCharset = UTF-8
# enable druid Decrypt database password
canal.instance.enableDruid=false
# table regex (白名单)
#canal.instance.filter.regex=.*\\..*
canal.instance.filter.regex = 库名.表名,库名.表名
test.user,test.dept
# table black regex(黑名单)
#canal.instance.filter.black.regex=mysql\\..*,db_user_0\\..*
canal.instance.filter.black.regex=mysql\\..*,test2_eplus\\..*
# mq config 配置MQ的参数
# 配置使用的topic,和topic的分区数
canal.mq.topic=example
# dynamic topic route by schema or table regex
#canal.mq.dynamicTopic=mytest1.user,mytest2\\..*,.*\\..*
canal.mq.partition=0
# ...
# 可选项: tcp(默认), kafka, RocketMQ
canal.serverMode = kafka
# ...
# kafka/rocketmq 集群配置: 192.168.1.117:9092,192.168.1.118:9092,192.168.1.119:9092
canal.mq.servers = 127.0.0.1:6667
canal.mq.retries = 0
# flagMessage模式下可以调大该值, 但不要超过MQ消息体大小上限
canal.mq.batchSize = 16384
canal.mq.maxRequestSize = 1048576 消息大小,超过会抛出异常( org.apache.kafka.common.errors.RecordTooLargeException)
# flatMessage模式下请将该值改大, 建议50-200
canal.mq.lingerMs = 1
canal.mq.bufferMemory = 33554432
# Canal的batch size, 默认50K, 由于kafka最大消息体限制请勿超过1M(900K以下)
canal.mq.canalBatchSize = 50
# Canal get数据的超时时间, 单位: 毫秒, 空为不限超时
canal.mq.canalGetTimeout = 100
# 是否为flat json格式对象
canal.mq.flatMessage = false (为true时,运行代码过程中会出现反序列化失败)
canal.mq.compressionType = none
canal.mq.acks = all
# kafka消息投递是否使用事务
canal.mq.transaction = false
参考https://github.com/alibaba/canal/wiki/Kafka-QuickStart
将kafka_2.11-1.1.1.tgz上传到服务器,并解压
vim /opt/kafka/config/server.properties
主要更改:
zookeeper.connect=10.168.3.145:2181
listeners=PLAINTEXT://:9092
advertised.listeners=PLAINTEXT://10.168.3.145:9092
host.name=0.0.0.0
delete.topic.enable=true
log.dirs=/opt/kafka/logs
清空log可以参考:https://blog.csdn.net/qq_39657597/article/details/84307541
./bin/kafka-topics --delete --zookeeper 10.168.3.145:2181(zk地址) --topic example (topic名字)
启动:
sh bin/kafka-server-start.sh -daemon config/server.properties &
关闭:
sh bin/kafka-server-stop.sh
kafka同时支持内网外网:
方法一:
用hostname
注掉listeners,然后advertised.listeners 改为:
advertised.listeners=PLAINTEXT://hostname:9092
内网外网客户端,都需要把所在机器的hosts文件,写入hostname对应ip,内网对应内网ip,外网对应外网ip即可
这种前提是外网端口也是9092,需要跟内网对应的一样;
方法二:
注掉listeners,然后advertised.listeners 改为:
advertised.listeners=PLAINTEXT://外网ip:外网端口
内网自动支持。
这种方式注意事项:有安全隐患,并且kafka集群之间节点的连接会走外网, 网络抖动,导致服务出现不可用,因此按需选择
canal.client下有对应的MQ数据消费的样例工程,包含数据编解码的功能
中间夹着很多业务处理的代码,可以用于参考。
选几个重要的地方说明一下。
public CanalKafkaClient(String zkServers, String servers, String topic, Integer partition, String groupId){
connector = new KafkaCanalConnector(servers, topic, partition, groupId, 10, false);
}
printEntry(message.getEntries());
消费数据,处理业务逻辑。
根据操作类型,表名来做不同的业务处理
将变更的数据,存到表中供B平台同步信息,也可以使用MQ来实现。其实就是消息队列,只不过我这里偷懒用数据库做了
protected void printEntry(List<Entry> entrys) {
...
//获取数据的操作类型,用作不同操作进入不通的方法
EventType eventType = rowChage.getEventType();
UpdateJWDTO updateJWDTO = new UpdateJWDTO();
String tableName = entry.getHeader().getTableName();//获取表名
List<UpdateJWDTO> jwdtoList = new ArrayList<UpdateJWDTO>();
List<Column> columns = new ArrayList<Column>();
//循环结果集
if(eventType == EventType.UPDATE){
for (RowData rowData : rowChage.getRowDatasList()) {
columns = rowData.getAfterColumnsList();
updateJWDTO = updateColumn(tableName,columns);
if(updateJWDTO.getUpdateTableId() != null){
jwdtoList.add(updateJWDTO);
}
}
}
...
}
private static UpdateJWDTO updateColumn(String tableName,List columns)
当数据进行修改时,判断修改的值是不是教学系统需要的值
是则进行数据封装,保存到临时表
如果是需要实时通知的,可以直接通过接口方式进行通知,如:用户密码修改的操作
String filerName = column.getName();//获取字段名
boolean updateState = column.getUpdated();//获取字段是不是被改了
columns.get(15);//可以直接获取当前数据的值,15为数据库字段表的下标值,下标从0开始。例如:数据库字段为 id,name,age。那么name的值就是columns.get(1);
/**
* 当数据进行修改时,判断修改的值是不是教学系统需要的值
*
* @author ls
* @date 2018-12-4
*/
private static UpdateJWDTO updateColumn(String tableName,List<Column> columns) {
UpdateJWDTO updateJWDTO = new UpdateJWDTO();
try {
for (Column column : columns) {
boolean updateState = column.getUpdated();
String filerName = column.getName();
//执行修改操作的时候调用教学接口
if(tableName.equalsIgnoreCase("class_manage")){
if((filerName.equalsIgnoreCase("CLASS_NAME")||filerName.equalsIgnoreCase("ENGLISHNAME")||filerName.equalsIgnoreCase("IS_ENABLED")
||filerName.equalsIgnoreCase("OS_ID")||filerName.equalsIgnoreCase("PK_ADMISSIONS_SEASON")
||filerName.equalsIgnoreCase("PK_USER_1")||filerName.equalsIgnoreCase("PK_ASS")
||filerName.equalsIgnoreCase("CLASS_STATE")) && updateState){
/**
* 当修改表为班级时,先判断班级状态 115 建班审核通过 116 开课 117 结课
*/
if(columns.get(15) != null && columns.get(15).getValue() != null){ // 班级状态 CLASS_STATE
String classState = columns.get(15).getValue().toString();
if(classState.equals("116") || classState.equals("117") ){
updateJWDTO.setTableNum(QsteachConstants.CLASS_MANAGE);
putUpdateJWDTO(updateJWDTO,tableName,columns);
}
}
}
}else if(tableName.equalsIgnoreCase("student")){
//学员
if((filerName.equalsIgnoreCase("STU_NAME") ||filerName.equalsIgnoreCase("CONTACT_INFO")
||filerName.equalsIgnoreCase("PK_STU_STATE") || filerName.equalsIgnoreCase("ZD_STU_TYPE") ||filerName.equalsIgnoreCase("ENGLISHNAME")
||filerName.equalsIgnoreCase("PASSWORD") ||filerName.equalsIgnoreCase("STUDY_NUMBER")
||filerName.equalsIgnoreCase("CID") ||filerName.equalsIgnoreCase("GENDER")
||filerName.equalsIgnoreCase("BIRTHDAY")) && updateState){
if(columns.get(14) != null && columns.get(14).getValue() != null){//学员状态 ZD_STU_TYPE
String studentType = columns.get(14).getValue().toString();
if(studentType.equals("9")){
updateJWDTO.setTableNum(QsteachConstants.STUDENT);
putUpdateJWDTO(updateJWDTO,tableName,columns);
}
}
if(filerName.equalsIgnoreCase("PASSWORD")){
String jwId = columns.get(0).getValue();
String type ="2";
Tms.omsClientUpdatePassWord(type, jwId);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return updateJWDTO;
}
package tms;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import com.alibaba.otter.canal.client.kafka.KafkaCanalConnector;
import com.alibaba.otter.canal.protocol.Message;
import com.alibaba.otter.canal.protocol.CanalEntry.Column;
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
/**
* Kafka client example
*
* @author machengyuan @ 2018-6-12
* @version 1.0.0
*/
public class CanalKafkaClient extends BaseCanalClient{
protected final static Logger logger = LoggerFactory.getLogger(CanalKafkaClient.class);
public static String topic = "example";
public static Integer partition = null;
public static String groupId = "g4";
public static String servers = "127.0.0.1:9092";
public static String zkServers = "127.0.0.1:2181";
private KafkaCanalConnector connector;
private static volatile boolean running = false;
private Thread thread = null;
private Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
logger.error("parse events has an error", e);
}
};
public CanalKafkaClient(String zkServers, String servers, String topic, Integer partition, String groupId){
connector = new KafkaCanalConnector(servers, topic, partition, groupId, 10, false);
}
public static void main(String[] args) {
try {
/*在main方法配置logback文件,kafka debug日志不会频繁刷 ----start TODO 线上根据自身项目情况,如果不需要可以删掉此段代码--------------- 配置logback,kafka debug日志不会频繁刷 ----end-----------------------------*/
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
try {
String path = CanalKafkaClient.class.getResource("/") + "logback.xml";
System.out.println(path);
configurator.doConfigure("src/main/resource/logback.xml");
} catch (JoranException e) {
e.printStackTrace();
}
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
final CanalKafkaClient kafkaCanalClient = new CanalKafkaClient(zkServers,servers,topic,partition,groupId);
logger.info("## start the kafka consumer: {}-{}", topic, groupId);
kafkaCanalClient.start();
logger.info("## the canal kafka consumer is running now ......");
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
logger.info("## stop the kafka consumer");
kafkaCanalClient.stop();
} catch (Throwable e) {
logger.warn("##something goes wrong when stopping kafka consumer:", e);
} finally {
logger.info("## kafka consumer is down.");
}
}
});
while (running);
} catch (Throwable e) {
logger.error("## Something goes wrong when starting up the kafka consumer:", e);
System.exit(0);
}
}
public void start() {
Assert.notNull(connector, "connector is null");
thread = new Thread(new Runnable() {
public void run() {
process();
}
});
thread.setUncaughtExceptionHandler(handler);
thread.start();
running = true;
}
public void stop() {
if (!running) {
return;
}
running = false;
if (thread != null) {
try {
thread.join();
} catch (InterruptedException e) {
// ignore
}
}
}
private void process() {
while (!running) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
while (running) {
try {
connector.connect();
connector.subscribe();
while (running) {
try {
List<Message> messages = connector.getListWithoutAck(100L, TimeUnit.MILLISECONDS); // 获取message
if ( CollectionUtils.isEmpty(messages) ){
// logger.info("empty, sleeping for 1 second");
Thread.sleep(1000);
continue;
}
for (Message message : messages) {
long batchId = message.getId();
int size = message.getEntries().size();
if (batchId == -1 || size == 0) {
// 这个分支应该不会进( 因为现在已经是kafka方式,并不再是client主动拉取canal,DB有数据更新后canal主动推到kafka)
continue;
} else {
// TODO 这两行是打日志,线上要注掉,此类去掉extends BaseCanalClient
//printSummary(message, batchId, size);
//printEntry(message.getEntries());
// TODO 这里写业务逻辑,处理方式跟老的相同
//System.out.println("========"+messages);
// message.getEntries()
//消费数据,处理业务逻辑
printEntry(message.getEntries());
// logger.info(message.toString());
}
}
connector.ack(); // 提交确认
} catch (Exception e) {
logger.error(e.getMessage(), e);
Tms.simpleMailSend("[email protected]","tms同步数据接口调用失败",e.toString());
e.printStackTrace();
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
connector.unsubscribe();
connector.disconnect();
}
//消费数据,处理业务逻辑
protected void printEntry(List<Entry> entrys) {
for (Entry entry : entrys) {
if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
continue;
}
RowChange rowChage = null;
try {
rowChage = RowChange.parseFrom(entry.getStoreValue());
} catch (Exception e) {
e.printStackTrace();
}
try {
EventType eventType = rowChage.getEventType();//操作类型
UpdateJWDTO updateJWDTO = new UpdateJWDTO();
String tableName = entry.getHeader().getTableName();//获取表名
List<UpdateJWDTO> jwdtoList = new ArrayList<UpdateJWDTO>();
List<Column> columns = new ArrayList<Column>();
//循环结果集
if(eventType == EventType.UPDATE){
for (RowData rowData : rowChage.getRowDatasList()) {
columns = rowData.getAfterColumnsList();
updateJWDTO = updateColumn(tableName,columns);
if(updateJWDTO.getUpdateTableId() != null){
jwdtoList.add(updateJWDTO);
}
}
}
if(eventType == EventType.INSERT){
for (RowData rowData : rowChage.getRowDatasList()) {
columns = rowData.getAfterColumnsList();
updateJWDTO = insertColumn(tableName,columns);
if(updateJWDTO.getUpdateTableId() != null){
jwdtoList.add(updateJWDTO);
}
}
}
if(eventType == EventType.DELETE){
for (RowData rowData : rowChage.getRowDatasList()) {
columns = rowData.getBeforeColumnsList();
updateJWDTO = deleteColumn(tableName,columns);
if(updateJWDTO.getUpdateTableId() != null){
jwdtoList.add(updateJWDTO);
}
}
}
if(jwdtoList.size() > 0){
String insertSchoolSql = "insert into UPDATEJWDTO (UPDATETABLEID,TABLENUM,OPERATEFLAG,REMARK,STATUS,CREATE_DATE,GROUPID) values";
//将内容加入数据库
for (UpdateJWDTO jwdto : jwdtoList) {
insertSchoolSql = insertSchoolSql + "("+jwdto.getUpdateTableId()+","+jwdto.getTableNum()+",'"
+jwdto.getOperateFlag()+"','"+jwdto.getRemark()+"','"+jwdto.getStatus()+"',now(),'"
+jwdto.getUpdateTableId()+jwdto.getOperateFlag()+jwdto.getTableNum()+"'),";
}
insertSchoolSql =insertSchoolSql.substring(0, insertSchoolSql.length()-1);
Ds.getJdbcTemplate4Mysql().update(insertSchoolSql);
System.out.println(insertSchoolSql);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 当数据进行添加时
* @author ls
* @date 2018-12-5
*/
private static UpdateJWDTO insertColumn(String tableName,List<Column> columns){
UpdateJWDTO updateJWDTO = new UpdateJWDTO();
try {
for (Column column : columns) {
if(tableName.equalsIgnoreCase("T_0_USER_INFO")){
//人员表
if(columns.get(29) != null && columns.get(29).getValue()!= null){//是否是老师 IF_TEACHER
String teacherId = columns.get(29).getValue().toString();
if(teacherId.equals("2")){
updateJWDTO.setTableNum(QsteachConstants.T_0_USER_INFO);
putInsertJWDTO(updateJWDTO,tableName,columns);
}
}
}else if(tableName.equalsIgnoreCase("ORDER_FORM")){ //监听订单添加 调用余额、优惠券消耗方法 - hdx 20191209
if("ZD_OF_TYPE".equalsIgnoreCase(column.getName())) {
String zd_of_type = columns.get(13).getValue(); //订单类型 785教材销售
if("785".equals(zd_of_type)) {
String orderId = columns.get(0).getValue();
Tms.handleAccountAndCouponForOrderFromTms(orderId);
}
}
//转班转校订单新增调用转班发起的接口 lyh
if("TRANSF_TYPE".equalsIgnoreCase(column.getName())) {
String transfType = columns.get(66).getValue();
if ("1183".equals(transfType)||"1184".equals(transfType)) {
String orderId = columns.get(0).getValue();
String userId = columns.get(6).getValue();
//String stuId = columns.get(5).getValue();
String parentOrderId = columns.get(49).getValue();
Tms.changeClassApplyTms(orderId,parentOrderId,userId);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return updateJWDTO;
}
/**
* 当数据进行删除时
* @author ls
* @date 2018-12-5
*/
private static UpdateJWDTO deleteColumn(String tableName,List<Column> columns){
UpdateJWDTO updateJWDTO = new UpdateJWDTO();
try {
for (Column column : columns) {
if(tableName.equalsIgnoreCase("T_0_USER_INFO")){
//人员
if(columns.get(29) != null && columns.get(29).getValue()!= null){//是否是老师 IF_TEACHER
String teacherId = columns.get(29).getValue().toString();
if(teacherId.equals("2")){
updateJWDTO.setTableNum(QsteachConstants.T_0_USER_INFO);
putDeleteJWDTO(updateJWDTO,tableName,columns);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return updateJWDTO;
}
/**
* 当数据进行修改时,判断修改的值是不是教学系统需要的值
* 是则进行数据封装,保存到临时表
* @author ls
* @date 2018-12-4
*/
private static UpdateJWDTO updateColumn(String tableName,List<Column> columns) {
UpdateJWDTO updateJWDTO = new UpdateJWDTO();
try {
for (Column column : columns) {
boolean updateState = column.getUpdated();
String filerName = column.getName();
//执行修改操作的时候调用教学接口
if(tableName.equalsIgnoreCase("class_manage")){
if((filerName.equalsIgnoreCase("CLASS_NAME")||filerName.equalsIgnoreCase("ENGLISHNAME")||filerName.equalsIgnoreCase("IS_ENABLED")
||filerName.equalsIgnoreCase("OS_ID")||filerName.equalsIgnoreCase("PK_ADMISSIONS_SEASON")
||filerName.equalsIgnoreCase("PK_USER_1")||filerName.equalsIgnoreCase("PK_ASS")
||filerName.equalsIgnoreCase("CLASS_STATE")) && updateState){
/**
* 当修改表为班级时,先判断班级状态 115 建班审核通过 116 开课 117 结课
*/
if(columns.get(15) != null && columns.get(15).getValue() != null){ // 班级状态 CLASS_STATE
String classState = columns.get(15).getValue().toString();
if(classState.equals("116") || classState.equals("117") ){
updateJWDTO.setTableNum(QsteachConstants.CLASS_MANAGE);
putUpdateJWDTO(updateJWDTO,tableName,columns);
}
}
}
}else if(tableName.equalsIgnoreCase("student")){
//学员
if((filerName.equalsIgnoreCase("STU_NAME") ||filerName.equalsIgnoreCase("CONTACT_INFO")
||filerName.equalsIgnoreCase("PK_STU_STATE") || filerName.equalsIgnoreCase("ZD_STU_TYPE") ||filerName.equalsIgnoreCase("ENGLISHNAME")
||filerName.equalsIgnoreCase("PASSWORD") ||filerName.equalsIgnoreCase("STUDY_NUMBER")
||filerName.equalsIgnoreCase("CID") ||filerName.equalsIgnoreCase("GENDER")
||filerName.equalsIgnoreCase("BIRTHDAY")) && updateState){
if(columns.get(14) != null && columns.get(14).getValue() != null){//学员状态 ZD_STU_TYPE
String studentType = columns.get(14).getValue().toString();
if(studentType.equals("9")){
updateJWDTO.setTableNum(QsteachConstants.STUDENT);
putUpdateJWDTO(updateJWDTO,tableName,columns);
}
}
if(filerName.equalsIgnoreCase("PASSWORD")){
String jwId = columns.get(0).getValue();
String type ="2";
Tms.omsClientUpdatePassWord(type, jwId);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return updateJWDTO;
}
/**
* 赋值
* @author ls
* @date 2018-12-4
*/
private static void putUpdateJWDTO(UpdateJWDTO updateJWDTO,String tableName,List<Column> columns) {
String updateRemark = "对"+tableName+"表,执行了修改操作,主键ID为:"+Long.valueOf(columns.get(0).getValue());
/**
* 班级修改为公开课时,单独处理接口
*/
if(tableName.equalsIgnoreCase("class_manage")){
String classState = columns.get(15).getValue().toString();
if(classState.equals("116")){
updateJWDTO.setOperateFlag("all");
}else{
updateJWDTO.setOperateFlag("update");
}
}else{
updateJWDTO.setOperateFlag("update");
}
if(updateJWDTO.getUpdateTableId() == null){
updateJWDTO.setUpdateTableId(Long.valueOf(columns.get(0).getValue()));
}
updateJWDTO.setRemark(updateRemark);
updateJWDTO.setStatus("0");
}
/**
* 赋值
* @author ls
* @date 2018-12-4
*/
private static void putDeleteJWDTO(UpdateJWDTO updateJWDTO,String tableName,List<Column> columns) {
String updateRemark = "对"+tableName+"表,执行了删除操作,主键ID为:"+Long.valueOf(columns.get(0).getValue());
updateJWDTO.setOperateFlag("delete");
if(updateJWDTO.getUpdateTableId() == null){
updateJWDTO.setUpdateTableId(Long.valueOf(columns.get(0).getValue()));
}
updateJWDTO.setRemark(updateRemark);
updateJWDTO.setStatus("0");
}
/**
* 赋值
* @author ls
* @date 2018-12-4
*/
private static void putInsertJWDTO(UpdateJWDTO updateJWDTO,String tableName,List<Column> columns) {
String updateRemark = "对"+tableName+"表,执行了添加操作,主键ID为:"+Long.valueOf(columns.get(0).getValue());
updateJWDTO.setOperateFlag("insert");
if(updateJWDTO.getUpdateTableId() == null){
updateJWDTO.setUpdateTableId(Long.valueOf(columns.get(0).getValue()));
}
updateJWDTO.setRemark(updateRemark);
updateJWDTO.setStatus("0");
}
/**
* 查询单条数据
* @author ls
* @date 2019-1-9
*/
public static Map<String,Object> selectOne(String tableName,String id){
String sql = "select * from " + tableName + " where ";
if(tableName.equalsIgnoreCase("t_0_user_info")){
sql = sql + " user_id = " + id;
}else if(tableName.equalsIgnoreCase("class_manage")){
sql = sql + " c_m_id = " + id;
}else if(tableName.equalsIgnoreCase("student")){
sql = sql + " student_id = " + id;
}else if(tableName.equalsIgnoreCase("class_schedule")){
sql = sql + " c_s_id = " + id;
}else if(tableName.equalsIgnoreCase("class_course")){
sql = sql + " c_c_id = " + id;
}else if(tableName.equalsIgnoreCase("SC_CLASS_TEA")){
sql = sql + " S_C_T_ID = " + id;
}
try {
return Ds.getJdbcTemplate4Mysql().queryForMap(sql);
} catch (Exception e) {
return null;
}
}
}
觉得有用的话,点赞一下呀!