<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>解决方案 on Java 技术探秘</title>
    <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</link>
    <description>Recent content in 解决方案 on Java 技术探秘</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 21 Oct 2021 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>会员体系中，积分过期的设计方案</title>
      <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/%E4%BC%9A%E5%91%98%E4%BD%93%E7%B3%BB%E4%B8%AD%E7%A7%AF%E5%88%86%E8%BF%87%E6%9C%9F%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%96%B9%E6%A1%88/</link>
      <pubDate>Thu, 21 Oct 2021 00:00:00 +0000</pubDate>
      <guid>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/%E4%BC%9A%E5%91%98%E4%BD%93%E7%B3%BB%E4%B8%AD%E7%A7%AF%E5%88%86%E8%BF%87%E6%9C%9F%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%96%B9%E6%A1%88/</guid>
      <description>背景：积分项目，每次添加的积分都有一个有效期，有效期为一年，如2017-01-02添加了一条积分记录，到2018-01-02这条记录应该是过期的。当前项目设计有两张表：积分明细表（存放积分添加、使用明细）、积分总额表（用户当前的积分额度）。由于每条积分的过期时间各不相同，如何正确地将过期的积分作废？消费时，如何优先使用即将过期的积分？&#xA;1.问题的提出 刚开始系统有两张表：积分明细表、积分总额表，积分总额直接由积分明细表统计。&#xA;以下是积分明细表，需要将内容展示给用户，让用户知道自己积分的添加、消耗情况：&#xA;记录id 会员id 积分值 添加时间 过期时间 备注 1 1 10 2017-01-02 2018-01-02 新增积分 2 1 20 2017-01-04 2018-01-04 新增积分 3 1 -30 2017-01-08 2018-01-08 使用积分 假设id为1的会在2017-01-08后，再无积分添加与消耗的情况。&#xA;现在有一张积分总额表，记录的了会员的积分额度，由于积分是过期的，那么按不同时间来统计，就会出现以下情况：&#xA;在2018-01-01统计时，id为1的会员积分额度是0，这没问题。&#xA;会员id 积分总值 更新时间 1 0 2018-01-01 那在2018-01-02统计时呢，记录id为1的记录已经过期了，只统计记录id为2与3的记录，会出现以下情况：&#xA;会员id 积分总值 更新时间 1 -10 2018-01-02 在2018-01-04统计时，记录id为1与3的记录已经过期了，只统计记录id为3的记录，差额就更大了：&#xA;会员id 积分总值 更新时间 1 -30 2018-01-04 只有在2018-01-08统计时，记录id为1、2、3的记录已经过期了，积分值才会正常：&#xA;会员id 积分总值 更新时间 1 0 2018-01-08 从上面的情况来看，单纯从积分明细表来统计，会出现积分值为负数的情况。&#xA;2.解决方案 项目当前的方案中，积分明细表记录了用户使用添加与使用情况，需要展现给用户，所以无法在这上面下手，为此新添加了一张表来记录当前可用积分明细。该表的关键字段如下：&#xA;字段 含义 积分值 该记录的积分值 添加时间 该记录的添加时间 过期时间 该记录的过期时间 如，在2017-01-02该会员的可用积分记录为</description>
    </item>
    <item>
      <title>idea下，Jetty采用main方法启动web项目</title>
      <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/idea%E4%B8%8Bjetty%E9%87%87%E7%94%A8main%E6%96%B9%E6%B3%95%E5%90%AF%E5%8A%A8web%E9%A1%B9%E7%9B%AE/</link>
      <pubDate>Wed, 21 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/idea%E4%B8%8Bjetty%E9%87%87%E7%94%A8main%E6%96%B9%E6%B3%95%E5%90%AF%E5%8A%A8web%E9%A1%B9%E7%9B%AE/</guid>
      <description>对于maven多模块的spring web项目，本地开发时，启动的方式一般有如下几种：&#xA;使用容器（tomcat/jetty/resin等），该方式需要ide支持，而社区版的idea并不支持； maven插件（jetty/tomcat），该方式只需在web模块的pom文件中加入插件依赖，然后运行 mvn jetty:run 或 mvn tomcat7:run 即可，不过对于多模块项目而言，代码时改动需要使用maven进行构建，而maven构建需耗时良久； jetty的main()方法启动，该方式启动时，并不需要使用maven进行构建，代码改动时仅需重新编译改动的源文件，且社区版的idea支持良好，本地开发时，是个不错的选择。 1. maven引入包 &amp;lt;!-- jetty相关依赖包，注意scope为test--&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.eclipse.jetty&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;jetty-webapp&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;9.3.2.v20150730&amp;lt;/version&amp;gt; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.eclipse.jetty&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;jetty-annotations&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;9.3.2.v20150730&amp;lt;/version&amp;gt; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.eclipse.jetty&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;apache-jsp&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;9.3.2.v20150730&amp;lt;/version&amp;gt; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.eclipse.jetty&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;apache-jstl&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;9.3.2.v20150730&amp;lt;/version&amp;gt; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;lt;/dependency&amp;gt; 2. 编写启动类 由于引入包时，scope为test，因此该类需位于src/test/java下。&#xA;import org.eclipse.jetty.jsp.JettyJspServlet; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.webapp.WebAppContext; import java.io.File; public class JettyStart { public static void main(String[] args) throws Exception { //添加你的模块名，对于maven多模块项目，需要指定 String moduleName = &amp;#34;module&amp;#34;; String dir = System.</description>
    </item>
    <item>
      <title>springboot 多数据源下，开启事务后，数据源切换失败的处理</title>
      <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/springboot-%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E4%B8%8B%E5%BC%80%E5%90%AF%E4%BA%8B%E5%8A%A1%E5%90%8E%E6%95%B0%E6%8D%AE%E6%BA%90%E5%88%87%E6%8D%A2%E5%A4%B1%E8%B4%A5%E7%9A%84%E5%A4%84%E7%90%86/</link>
      <pubDate>Sat, 01 May 2021 00:00:00 +0000</pubDate>
      <guid>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/springboot-%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E4%B8%8B%E5%BC%80%E5%90%AF%E4%BA%8B%E5%8A%A1%E5%90%8E%E6%95%B0%E6%8D%AE%E6%BA%90%E5%88%87%E6%8D%A2%E5%A4%B1%E8%B4%A5%E7%9A%84%E5%A4%84%E7%90%86/</guid>
      <description>springboot 多数据源下，开启事务后，数据源切换失败的处理 1. 问题的产生 在之前的文章中，整合了spring多数据源后，开始进行了愉快地编码中。不过这种&amp;quot;愉快&amp;quot;并没有持续多久，就碰到了一个诡异的问题：数据源切换突然不起作用了。经多次代码比对，发现无法切换的方法上加了个注解：@Transactional.&#xA;2. 验证 首先，对无@Transactional注解的代码进行访问：&#xA;@Override public List&amp;lt;User&amp;gt; selectByQuery(UserQuery query) { //省略其他代码 ... } 访问http://localhost:8084/api/user/get?appId=3，结果如下：&#xA;[ { &amp;#34;uid&amp;#34;: 1, &amp;#34;nick&amp;#34;: &amp;#34;db3_张三&amp;#34; }, { &amp;#34;uid&amp;#34;: 2, &amp;#34;nick&amp;#34;: &amp;#34;db3_李四&amp;#34; }, { &amp;#34;uid&amp;#34;: 3, &amp;#34;nick&amp;#34;: &amp;#34;db3_王五&amp;#34; } ] 可以看到，结果正常。&#xA;接着，添加@Transactional注解，再次访问：&#xA;@Override @Transactional(rollbackFor = Exception.class) public List&amp;lt;User&amp;gt; selectByQuery(UserQuery query) { //省略其他代码 ... } 访问http://localhost:8084/api/user/get?appId=3，结果如下：&#xA;[ { &amp;#34;uid&amp;#34;:1, &amp;#34;nick&amp;#34;:&amp;#34;main_张三&amp;#34; }, { &amp;#34;uid&amp;#34;:2, &amp;#34;nick&amp;#34;:&amp;#34;main_李四&amp;#34; }, { &amp;#34;uid&amp;#34;:3, &amp;#34;nick&amp;#34;:&amp;#34;main_王五&amp;#34; } ] 可以看到，获取到的是main数据源中的数据。&#xA;3. 分析 这里引进csdn上一位博主《springboot+mybatis解决多数据源切换事务控制不生效的问题》的分析：</description>
    </item>
    <item>
      <title>java抽奖工具类：按概率抽奖</title>
      <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/java%E6%8A%BD%E5%A5%96%E5%B7%A5%E5%85%B7%E7%B1%BB%E6%8C%89%E6%A6%82%E7%8E%87%E6%8A%BD%E5%A5%96/</link>
      <pubDate>Thu, 22 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/java%E6%8A%BD%E5%A5%96%E5%B7%A5%E5%85%B7%E7%B1%BB%E6%8C%89%E6%A6%82%E7%8E%87%E6%8A%BD%E5%A5%96/</guid>
      <description>在一些抽奖活动中，会有按概率抽取奖品的操作，本文将提供一个抽奖概率的解决方案。&#xA;假设抽奖集合如下： 奖品id 概率 1 10% 2 10% 3 20% 4 20% 生成集合 生成的连续集合为{(0.0, 10.0],(10.0, 30.0],(30.0, 60.0]}，如下： 奖品id 区间 1 (0.0, 10.0] 2 (10.0, 20.0] 3 (20.0, 40.0] 4 (40.0, 60.0] 最大的概率值 maxElement = 60.0，这个值下面会用到。&#xA;生成随机数 生成方法为 random.nextDouble() * maxElement，maxElement 就是上一步得到的。&#xA;判断随机数在哪个区间内，返回该区间对应的奖品id 假如 生成了随机数12.001，则它属于(10.0, 20.0]，对应的奖品id为2.&#xA;代码如下：&#xA;LotteryUtil&#xA;public class LotteryUtil { private List&amp;lt;Continuous&amp;gt; lotteryList; private double maxElement; /** * 得到一个抽奖对象 * @param map 抽奖概率，key:奖品id，value:概率 * @param &amp;lt;T&amp;gt; * @return */ public static&amp;lt;T&amp;gt; LotteryUtil getInstance(Map&amp;lt;T, Double&amp;gt; map) { return new LotteryUtil(map); } /** * 构造抽奖集合 * @param map 为奖品的概率 */ private &amp;lt;T&amp;gt; LotteryUtil(Map&amp;lt;T, Double&amp;gt; map) { if(map.</description>
    </item>
    <item>
      <title>spring&#43;redis自主实现分布式session</title>
      <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/spring&#43;redis%E8%87%AA%E4%B8%BB%E5%AE%9E%E7%8E%B0%E5%88%86%E5%B8%83%E5%BC%8Fsession%E9%9D%9Espring-session%E6%96%B9%E5%BC%8F/</link>
      <pubDate>Sun, 13 Sep 2020 00:00:00 +0000</pubDate>
      <guid>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/spring&#43;redis%E8%87%AA%E4%B8%BB%E5%AE%9E%E7%8E%B0%E5%88%86%E5%B8%83%E5%BC%8Fsession%E9%9D%9Espring-session%E6%96%B9%E5%BC%8F/</guid>
      <description>背景：最近对一个老项目进行改造，使其支持多机部署，其中最关键的一点就是实现多机session共享。项目有多老呢，jdk版本是1.6，spring版本是3.2，jedis版本是2.2。&#xA;1.方案的确定 接到这项目任务后，理所当然地google了，一搜索，发现解决方案分为两大类：&#xA;tomcat的session管理 spring-session 对于“tomcat的session管理”，很不幸，线上代码用的是resin，直接pass了；&#xA;对于“spring-session”，这是spring全家桶系列，项目中正好使用了spring，可以很方便集成，并且原业务代码不用做任何发动，似乎是个不错的选择。但是，在引入spring-session过程中发生了意外：项目中使用的jedis版本不支持！项目中使用的jedis版本是2.2,而spring-session中使用的jedis版本是2.5，有些命令像&amp;quot;set PX/EX NX/XX&amp;quot;，项目中使用的redis是不支持的，但spring-session引入的jedis支持，直接引入的话，风险难以把控，而升级项目中的redis版本的话，代价就比较高了。&#xA;综上所述，以上两个方案都行不能，既然第三方组件行不通，那就只能自主实现了。&#xA;通过参考一些开源项目的实现，自主实现分布式session的关键点有以下几点：&#xA;使用servlet的filter功能来接管session； 使用redis来管理全局session 2.使用filter来接管session 为了实现此功能，我们定义如下几个类：&#xA;SessionFilter：servlet的过滤器，替换原始的session DistributionSession：分布式session，实现了HttpSession类； SessionRequestWrapper：在filter中用来接管session； 类的具体实现如下：&#xA;SessionFilter类&#xA;/** * 该类实现了Filter */ public class SessionFilter implements Filter { /** redis的相关操作 */ @Autowired private RedisExtend redisExtend; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //这里将request转换成自主实现的SessionRequestWrapper //经过传递后，项目中获取到的request就是SessionRequestWrapper ServletRequest servletRequest = new SessionRequestWrapper((HttpServletRequest)request, (HttpServletResponse)response, redisExtend); chain.doFilter(servletRequest, response); } @Override public void destroy() { } } ServletRequestWrap类</description>
    </item>
    <item>
      <title>springboot &#43; druid 实现数据源下动态切换</title>
      <link>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/springboot-&#43;-druid-%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E6%BA%90%E4%B8%8B%E5%8A%A8%E6%80%81%E5%88%87%E6%8D%A2/</link>
      <pubDate>Wed, 03 Jun 2020 00:00:00 +0000</pubDate>
      <guid>https://www.szlinkroutes.com/categories/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/springboot-&#43;-druid-%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E6%BA%90%E4%B8%8B%E5%8A%A8%E6%80%81%E5%88%87%E6%8D%A2/</guid>
      <description>springboot + druid 实现数据源下动态切换 1. 项目背景 最近接到一个需求：为多个业务系统开发统一的管理后台，这几个业务系统的相关业务惊人地相似，用的是同一份代码，只是地区、受众不同，因此服务器、数据库都单独分开了。&#xA;项目很明显要用到多数据源，经过在google多方打探，终于了解到基于AbstractRoutingDataSource的多数据源解决方案了。废话不多说，上代码介绍我的实现方式。&#xA;2. 代码实现 2.1 引入多数据源 在 application.yml 引入多数据源配置，这里使用的是阿里的 Druid 连接池：&#xA;# 数据源配置 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: # 主库数据源 main: url: jdbc:mysql://127.0.0.1:3306/main?useUnicode=true&amp;amp;characterEncoding=utf8&amp;amp;zeroDateTimeBehavior=convertToNull&amp;amp;useSSL=true&amp;amp;serverTimezone=GMT%2B8 username: root password: 123 # 应用数据源 app: # db1 db1: url: jdbc:mysql://127.0.0.1:3306/db1?useUnicode=true&amp;amp;characterEncoding=utf8&amp;amp;zeroDateTimeBehavior=convertToNull&amp;amp;useSSL=true&amp;amp;serverTimezone=GMT%2B8 username: root password: 123 # db2 db2: url: jdbc:mysql://127.0.0.1:3306/db2?useUnicode=true&amp;amp;characterEncoding=utf8&amp;amp;zeroDateTimeBehavior=convertToNull&amp;amp;useSSL=true&amp;amp;serverTimezone=GMT%2B8 username: root password: 123 # ds3 db3: url: jdbc:mysql://127.0.0.1:3306/db3?useUnicode=true&amp;amp;characterEncoding=utf8&amp;amp;zeroDateTimeBehavior=convertToNull&amp;amp;useSSL=true&amp;amp;serverTimezone=GMT%2B8 username: root password: 123 这里一共引入了4个数据源：main、db1、db2、db3&#xA;main: 管理后台的数据源，存放管理后台相关数据，如用户登录数据、系统菜单等 db1: 业务系统1的数据源 db2: 业务系统2的数据源 db3: 业务系统3的数据源 2.</description>
    </item>
  </channel>
</rss>
