CountDownLatch 批量更改使用,

代码

复制代码
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.first.pet.platform.entity.PlatformAddress;
import com.first.pet.platform.mapper.PlatformAddressMapper;
import com.first.pet.platform.service.IPlatformAddressServiceTest;
import com.first.pet.threadPool.ThreadPoolUtils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author yangquan
 * @since 2023-09-26
 */
@Service
public class IPlatformAddressServiceTestImpl extends ServiceImpl<PlatformAddressMapper, PlatformAddress> implements IPlatformAddressServiceTest {

	@Resource
	private PlatformAddressMapper platformAddressMapper;

	//每次查询500条数据操作

	/**
	 * 组装数据
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void assembleAddressData() throws InterruptedException {
		//        1.创建任务计数器  参数为设置任务数量
		//开三个线程,一个线程执行500条
		CountDownLatch countDownLatch = new CountDownLatch(4);

		//        2.开启三个线程  分别执行三个查询
		//        查询 性别信息
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {

				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 1500,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);

				platformAddressMapper.updateDataById(platformAddress);
				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();
			}
		});
		//        查询 地区分布
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {

				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 2000,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);
				platformAddressMapper.updateDataById(platformAddress);


				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();

			}
		});

		//        查询 注册量
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {
				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 2500,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);
				platformAddressMapper.updateDataById(platformAddress);

				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();
			}
		});

		//        查询 注册量
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {
				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 3000,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);
				platformAddressMapper.updateDataById(platformAddress);

				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();
			}
		});

		//        await() 当计数器为0的时候 主线程向下执行 没有这一步的话,如果一旦主线程向下执行
		// return map map中可能有的开启的线程还没有执行完毕,即返回的不是线程执行后的结果
		countDownLatch.await();
	}


	private List<PlatformAddress> getPlatformAddress(List<PlatformAddress> platformAddresses) {
		platformAddresses.stream().forEach(e -> {
			e.setInitials(ToFirstChar(e.getAddressName()).toUpperCase());
			e.setCompleteSpelling(ToPinyin(e.getAddressName()));
		});
		return platformAddresses;
	}

	public static void main(String[] args) {
		String ss = ToFirstChar("安徽省");
		System.out.println(ss);
	}


	/**
	 * 获取字符串拼音的第一个字母
	 *
	 * @param chinese
	 * @return
	 */
	public static String ToFirstChar(String chinese) {
		String pinyinStr = "";
//		char[] newChar = chinese.toCharArray();  //转为单个字符
		char[] newChar = new char[]{chinese.toCharArray()[0]};  //转为单个字符
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < newChar.length; i++) {
			if (newChar[i] > 128) {
				try {
					pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0].charAt(0);
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pinyinStr += newChar[i];
			}
		}
		return pinyinStr;
	}

	/**
	 * 汉字转为拼音
	 *
	 * @param chinese
	 * @return
	 */
	public static String ToPinyin(String chinese) {
		String pinyinStr = "";
		char[] newChar = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < newChar.length; i++) {
			if (newChar[i] > 128) {
				try {
					pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0];
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pinyinStr += newChar[i];
			}
		}
		return pinyinStr;
	}

}

批量更改数据sql

复制代码
<update id="updateDataById" parameterType="java.util.List">
    <foreach collection="list" item="item" separator=";">
        update platform_address set initials=#{item.initials},complete_Spelling = #{item.completeSpelling}
        where id =#{item.id}
    </foreach>
</update>

数据库连接 必须配置,否则不能批量更改,以下是参考链接

https://blog.csdn.net/carbuser_xl/article/details/127045359

复制代码
 url: jdbc:mysql://rm:5888/first_pet_dev?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true

拼音依赖

复制代码
  <dependency>
            <groupId>com.belerweb</groupId>
            <artifactId>pinyin4j</artifactId>
            <version>2.5.0</version>
        </dependency>

线程池工具类

复制代码
import org.apache.tomcat.util.threads.ThreadPoolExecutor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 描述:
 * 线程池工具类
 * - 所有线程的创建与使用请调用此类的方法
 *
 * @author zhaofeng
 * @date 2023-08-29
 */
public class ThreadPoolUtils {

    /**
     * http异步请求
     * 耗时相对较长,取核心数*2
     * 阻塞时间60秒
     * 空闲时间超过60秒后销毁线程
     */
    public static final ThreadPoolExecutor httpThreadPool = new ThreadPoolImpl(
            8, 16, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy()
    );

    /**
     * 数据库操作请求
     * 相较http请求耗时较短
     * 取核心线程数*1
     * 阻塞时间60秒
     */
    public static final ThreadPoolExecutor sqlThreadPool = new ThreadPoolImpl(
            4, 8, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy()
    );

}

汉字转拼音写法,参考链接

复制代码
https://blog.csdn.net/SoumnsJ/article/details/89146371
相关推荐
sky_ph几秒前
JAVA-GC浅析(二)G1(Garbage First)回收器
java·后端
IDRSolutions_CN22 分钟前
PDF 转 HTML5 —— HTML5 填充图形不支持 Even-Odd 奇偶规则?(第二部分)
java·经验分享·pdf·软件工程·团队开发
hello早上好25 分钟前
Spring不同类型的ApplicationContext的创建方式
java·后端·架构
虾球xz1 小时前
CppCon 2015 学习:CLANG/C2 for Windows
开发语言·c++·windows·学习
码上库利南1 小时前
Windows开机自动启动中间件
windows
HelloWord~1 小时前
SpringSecurity+vue通用权限系统2
java·vue.js
让我上个超影吧1 小时前
黑马点评【基于redis实现共享session登录】
java·redis
BillKu2 小时前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥2 小时前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii2 小时前
12.7Swing控件6 JList
java