说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务。我们遇到的情况是后者,网上找了很多,大都是根据 Jpa 来做多数据源解决方案,要不就是老的 Spring 多数据源解决方案,还有的是利用 Aop 动态切换,感觉有点小复杂,其实我只是想找一个简单的多数据支持而已,折腾了两个小时整理出来,供大家参考。
View DetailsJava 2D API 的文本功能包括:
使用抗锯齿处理和微调(hinting)以达到更好的输出质量
可以使用系统安装的所有字体
可以将对图形对象的操作(旋转、缩放、着色、剪切等等)应用到文本上。
支持向字符串添加内嵌属性(如字体、尺寸、深浅,甚至图像)
支持双向文本(启用从右到左的字符顺序,就象您在阿拉伯语和希伯来语中可能遇到的一样)
第一光标和第二光标能够浏览同时包含从右到左和从左到右字符顺序的文本。
先进的字体度量功能,超过旧的 java.awt.FontMetrics 类中的相应功能
排版功能可以实现单词换行和调整多行文本
1 Maven依赖
1 2 3 4 5 6 7 8 9 10 11 |
<!--第一种方式导入校验依赖--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <!--第二种方式导入校验依赖--> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> </dependency> |
2 值校验 2.1 @Null注解 被注解的元素必须为null
1 2 |
@Null(message = "必须为null") private String username; |
2.2 @NotNull注解 被注解的元素必须不为null
1 2 |
@NotNull(message = "必须不为null") private String username; |
2.3 @NotBlank注解 验证注解的元素值不为空(不为null、去除首位空格后长度为0) ,并且类型为String。
1 2 |
@NotBlank(message = "必须不为空") private String username; |
2.4 @NotEmpty注解 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) ,并且类型为String。
1 2 |
@NotEmpty(message = "必须不为null且不为空") private String username; |
2.5 @AssertTrue注解 被注解的元素必须为true,并且类型为boolean。
1 2 |
@AssertTrue(message = "必须为true") private boolean status; |
2.6 @AssertFalse注解 被注解的元素必须为false,并且类型为boolean。
1 2 |
@AssertFalse(message = "必须为false") private boolean status; |
3 范围校验 3.1 @Min注解 被注解的元素其值必须大于等于最小值,并且类型为int,long,float,double。
1 2 |
@Min(value = 18, message = "必须大于等于18") private int age; |
3.2 @Max注解 被注解的元素其值必须小于等于最小值,并且类型为int,long,float,double。
1 2 |
@Max(value = 18, message = "必须小于等于18") private int age; |
3.3 @DecimalMin注解 验证注解的元素值大于等于@DecimalMin指定的value值,并且类型为BigDecimal。
1 2 |
@DecimalMin(value = "150", message = "必须大于等于150") private BigDecimal height; |
3.4 @DecimalMax注解 验证注解的元素值小于等于@DecimalMax指定的value值 ,并且类型为BigDecimal。
1 2 |
@DecimalMax(value = "300", message = "必须大于等于300") private BigDecimal height; |
3.5 @Range注解 验证注解的元素值在最小值和最大值之间,并且类型为BigDecimal,BigInteger,CharSequence,byte,short,int,long。
1 2 |
@Range(max = 80, min = 18, message = "必须大于等于18或小于等于80") private int age; |
3.6 @Past注解 被注解的元素必须为过去的一个时间,并且类型为java.util.Date。
1 2 3 |
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Past(message = "必须为过去的时间") private Date createDate; |
3.7 @Future注解 被注解的元素必须为未来的一个时间,并且类型为java.util.Date。
1 2 3 |
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Future(message = "必须为未来的时间") private Date createDate; |
4 长度校验 4.1 @Size注解 被注解的元素的长度必须在指定范围内,并且类型为String,Array,List,Map。
1 2 |
@Size(max = 11, min = 7, message = "长度必须大于等于7或小于等于11") private String mobile; |
4.2 @Length注解 验证注解的元素值长度在min和max区间内 ,并且类型为String。
1 2 |
@Length(max = 11, min = 7, message = "长度必须大于等于7或小于等于11") private String mobile; |
5 格式校验 5.1 @Digits注解 验证注解的元素值的整数位数和小数位数上限 ,并且类型为float,double,BigDecimal。
1 2 |
@Digits(integer=3,fraction = 2,message = "整数位上限为3位,小数位上限为2位") private BigDecimal height; |
[…]
View DetailsMybatis Generator简称 MBG,是一个专门为 MyBatis和 ibatis框架使用者提供的代码生成器。也可以快速的根据数据表生成对应的pojo类、Mapper接口、Mapper文件,甚至生成QBC风格的查询对象。
一般在项目中,根据MyBatis Generator的XML配置文件设置生成简单的CRUD,但是复杂的查询或者有关关联的操作还是需要我们写SQL完成。
View Details完全闭合的标签推荐使用正则表达式,因为是轻量级的。
如果是从数据库中查出截断的html文本,最好使用Jsoup组件,支持去除未闭合的标签。
有的时候需要获取当前时间所在自然周中的起始和截止时间,或者某个时间段内里的每一天的日期 1、先来解决获取自然周中的起止时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/** * 获取当前时间所在自然周的起止日期 * * @return */ public static Map<String, String> weekBeginningAndEnding() { Map<String, String> map = new HashMap<>(); //获取当前自然周中每天的日期集合 Date date = new Date(); DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Calendar c = new GregorianCalendar(); c.setFirstDayOfWeek(Calendar.MONDAY); //这里设置一周开始时间是星期一 c.setTime(date); c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday String beginTime = format.format(c.getTime()); //获取当前自然周的起始时间 map.put("begin", beginTime); c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday String endTime = format.format(c.getTime()); //当前自然周的截止时间 map.put("end", endTime); return map; } |
2、根据时间段来获取当前时间段内的每一天
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/** * 获取开始和结束之间的每一天 * * @param beginTime 开始时间 * @param endTime 结束时间 * @param type 返回列表中的时间格式 * @return 返回日期字符串列表 */ public static List<String> weekDays(Date beginTime, Date endTime,String type) { DateFormat format=new SimpleDateFormat(type); //设置开始时间 Calendar calStart = Calendar.getInstance(); calStart.setTime(beginTime); //设置结束时间 Calendar calEnd = Calendar.getInstance(); calEnd.setTime(endTime); //返回的日期集合 List<String> dateList = new ArrayList<String>(); //每次循环给calStart日期加一天,直到calBegin.getTime()时间等于dEnd dateList.add(format.format(calStart.getTime())); while (endTime.after(calStart.getTime())) { //根据日历的规则,为给定的日历字段添加或减去指定的时间量 calStart.add(Calendar.DAY_OF_MONTH, 1); dateList.add(format.format(calStart.getTime())); } return dateList; } |
如果对你有用,点个赞吧!!! from:https://blog.csdn.net/weixin_44826433/article/details/110677362
View Details第一种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * 获取当前日期是星期几<br> * * @param date * @return 当前日期是星期几 */ public String getWeekOfDate(Date date) { String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; Calendar cal = Calendar.getInstance(); cal.setTime(date); int w = cal.get(Calendar.DAY_OF_WEEK) - 1; if (w < 0) w = 0; return weekDays[w]; } |
第二种方法: 使用SimpleDateFormat格式化日期
1 2 3 4 |
Date date = new Date(); SimpleDateFormat dateFm = new SimpleDateFormat("EEEE"); String currSun = dateFm.format(date); System.out.println(currSun); |
注:格式化字符串存在区分大小写 对于创建SimpleDateFormat传入的参数:EEEE代表星期,如“星期四”;MMMM代表中文月份,如“七月”;MM代表月份,如“07”;yyyy代表年份,如“2017”;dd代表天,如“05” from:https://blog.csdn.net/u013456370/article/details/74373410
View Details先看效果: xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?xml version="1.0" encoding="utf-8" ?> <auibinsurancecallback> <policyinfo> <transtype>TKTS</transtype> <eticketno>xxx</eticketno> <flightnumber>xxx</flightnumber> <flightdate>2019-10-16</flightdate> <operatetime>2019-10-16 17:20:00</operatetime> <insureno>1910161720056066735</insureno> <agreeno>102160199</agreeno> <policyno/> <policyurl><![CDATA[]]></policyurl> </policyinfo> <returninfo> <serialnumber>2019103015284949545354</serialnumber> <retruncode>0</retruncode> <errormessage><![CDATA[]]></errormessage> </returninfo> <list> <item> <name>john</name> <age>22</age> <log> <record>1</record> <record>2</record> </log> </item> <item> <name>lucy</name> <age>23</age> <log> <record> <id>1</id> <event>event1</event> </record> <record> <id>2</id> <event>event2</event> </record> </log> </item> </list> <list2> <item> <name>lily</name> <age>24</age> </item> </list2> </auibinsurancecallback> |
json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
{ "auibinsurancecallback": { "policyinfo": { "transtype": "TKTS", "eticketno": "xxx", "flightnumber": "xxx", "flightdate": "2019-10-16", "operatetime": "2019-10-16 17:20:00", "insureno": "1910161720056066735", "agreeno": "102160199", "policyno": "", "policyurl": "" }, "returninfo": { "serialnumber": "2019103015284949545354", "retruncode": "0", "errormessage": "" }, "list": { "item": [ { "name": "john", "age": "22", "log": { "record": [ { "record": "1" }, { "record": "2" } ] } }, { "name": "lucy", "age": "23", "log": { "record": [ { "id": "1", "event": "event1" }, { "id": "2", "event": "event2" } ] } } ] }, "list2": { "item": { "name": "lily", "age": "24" } } } } |
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j --> <dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.4</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 --> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.42</version> </dependency> |
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
package org.longsheng.util; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import java.util.ArrayList; import java.util.List; /** * Xml转JSON工具包 */ @Slf4j public class XmlToJsonUtil { /** * 转换为json字符串 * * @param xmlString xml字符串 * @return json字符串 */ public static String toJsonString(String xmlString) { JSONObject result = toJson(xmlString); if (result == null) { return null; } return result.toString(); } /** * 转换为json对象 * * @param xmlString xml字符串 * @return json对象 */ public static JSONObject toJson(String xmlString) { try { Document doc = DocumentHelper.parseText(xmlString); return toJson(doc); } catch (DocumentException e) { log.error("{}===>{}===>exception: {} | {}", Thread.currentThread().getStackTrace()[1].getClassName(), Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage(), e.getStackTrace()); } return null; } /** * 转换为json对象 * * @param document xml对象 * @return json对象 */ public static JSONObject toJson(Document document) { if (document == null) { return null; } try { Element root = document.getRootElement(); List<Element> elements = root.elements(); JSONObject jsonObject = new JSONObject(); jsonObject.put(root.getName(), elementToJson(elements)); return jsonObject; } catch (Exception e) { log.error("{}===>{}===>exception: {} | {}", Thread.currentThread().getStackTrace()[1].getClassName(), Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage(), e.getStackTrace()); } return null; } /** * 递归读取节点,并简单判定节点状态(值、对象、列表三种状态) * * @param elements * @return */ public static JSONObject elementToJson(List<Element> elements) { if (elements == null || elements.isEmpty()) { return null; } JSONObject result = new JSONObject(); // single object if (elements.size() == 1) { Element element = elements.get(0); List<Element> children = element.elements(); result.put(element.getName(), children.isEmpty() ? element.getText() : elementToJson(children)); return result; } // multi-object if (!elements.get(0).getName().equals(elements.get(1).getName())) { result.clear(); List<Element> children; for (Element element : elements) { children = element.elements(); result.put(element.getName(), children.isEmpty() ? element.getText() : elementToJson(children)); } return result; } // array list List<JSONObject> jsonList = new ArrayList<>(); List<Element> children; for (Element element : elements) { children = element.elements(); result = new JSONObject(); if (children.isEmpty()) { result.put(element.getName(), element.getText()); } else { result = elementToJson(children); } jsonList.add(result); } result = new JSONObject(); result.put(elements.get(0).getName(), jsonList); return result; } /** * 从json对象中获取指定名称的json数组 * * @param jsonObject json对象 * @param nodeName json数组节点名称 * @return json数组 */ public static JSONArray getArray(JSONObject jsonObject, String nodeName) { if (jsonObject == null || nodeName == null || nodeName.isEmpty()) { return null; } Object node = jsonObject.get(nodeName); if (node == null) { return null; } JSONArray result = new JSONArray(); if (node instanceof JSONObject) { result.add(node); return result; } if (node instanceof ArrayList) { result = jsonObject.getJSONArray(nodeName); } return result; } public static void main(String[] args) { String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + "<auibinsurancecallback>\n" + "\t<policyinfo>\n" + "\t\t<transtype>TKTS</transtype>\n" + "\t\t<eticketno>xxx</eticketno>\n" + "\t\t<flightnumber>xxx</flightnumber>\n" + "\t\t<flightdate>2019-10-16</flightdate>\n" + "\t\t<operatetime>2019-10-16 17:20:00</operatetime>\n" + "\t\t<insureno>1910161720056066735</insureno>\n" + "\t\t<agreeno>102160199</agreeno>\n" + "\t\t<policyno/>\n" + "\t\t<policyurl><![CDATA[]]></policyurl>\n" + "\t</policyinfo>\n" + "\t<returninfo>\n" + "\t\t<serialnumber>2019103015284949545354</serialnumber>\n" + "\t\t<retruncode>0</retruncode>\n" + "\t\t<errormessage><![CDATA[]]></errormessage>\n" + "\t</returninfo>\n" + "\t<list>\n" + "\t\t<item>" + "\t\t\t<name>john</name>" + "\t\t\t<age>22</age>" + "\t\t\t<log>" + "\t\t\t\t<record>1</record>" + "\t\t\t\t<record>2</record>" + "\t\t\t</log>" + "\t\t</item>\n" + "\t\t<item>" + "\t\t\t<name>lucy</name>" + "\t\t\t<age>23</age>" + "\t\t\t<log>" + "\t\t\t\t<record>" + "\t\t\t\t\t<id>1</id>" + "\t\t\t\t\t<event>event1</event>" + "\t\t\t\t</record>" + "\t\t\t\t<record>" + "\t\t\t\t\t<id>2</id>" + "\t\t\t\t\t<event>event2</event>" + "\t\t\t\t</record>" + "\t\t\t</log>" + "\t\t</item>\n" + "\t</list>\n" + "\t<list2>\n" + "\t\t<item>" + "\t\t\t<name>lily</name>" + "\t\t\t<age>24</age>" + "\t\t</item>\n" + "\t</list2>\n" + "</auibinsurancecallback>"; JSONObject json = toJson(xml); System.out.println(xml); System.out.println(); assert json != null; System.out.println(json.toJSONString()); JSONArray array1 = getArray(json.getJSONObject("auibinsurancecallback").getJSONObject("list"), "item"); JSONArray array2 = getArray(json.getJSONObject("auibinsurancecallback").getJSONObject("list2"), "item"); System.out.println(); System.out.println(array1.toJSONString()); System.out.println(array2.toJSONString()); } } |
View Details
依赖
1 2 |
// https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter implementation group: 'com.alibaba.boot', name: 'nacos-config-spring-boot-starter', version: '0.2.12' |
配置文件 application.yml
1 2 3 4 5 |
nacos: config: server-addr: 127.0.0.1:8848 username: xxxx password: xxxxxx |
注解 @NacosPropertySource
1 2 3 4 5 6 7 8 9 10 |
@SpringBootApplication @MapperScan("com.w3cnet.xxx.repository") @NacosPropertySource(dataId = "xxx-prod.yml", autoRefreshed = true) public class XxxxApplication { public static void main(String[] args) { SpringApplication.run(XxxxApplication.class, args); } } |
注解 @NacosValue
1 2 |
@NacosValue(value = "${xxx.url}", autoRefreshed = true) private String xxxUrl; |
参考资料:https://nacos.io/zh-cn/docs/quick-start-spring-boot.html
View Details