Using @Component inject the bean to the Spring IoC container.
Using @Value read application configurations of Spring into non-static fields.
Implements InitializingBean override afterPropertiesSet() method. Assigning non-static field values to static field values in afterPropertiesSet() method.
Compare date in where clauses of MyBatis mapper XML query.
<iftest="beginTime != null and beginTime != ''"> createTime >= #{beginTime} and </if>
Error Info
nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String ### Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String ### Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
Solutions
remove beginTime != '' in the <if> element of MyBatis mapper XML file.
<iftest="beginTime != null"> createTime >= #{beginTime} and </if>
Reasons
When you pass Date objects as a parameter to MyBatis mapper XML query, you can’t compare the Date object with a String object in MyBatis <if> elements.
@Deprecated// programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists. @FunctionalInterface @Override// Indicates that a method declaration is intended to override a method declaration in a supertype. @SuppressWarnings// Indicates that the named compiler warnings should be suppressed in the annotated element (and in all program elements contained in the annotated element). @SafeVarargs// A programmer assertion that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter.
Spring Projects
Spring
Bean declaration
@Component @Controller @Service @Repository
Make a bean belong to a particular profile
@Profile("dev")
@Profile({"dev","test"})
// Only can contains one !string. Can't be like {"!dev","!test"} @Profile("!dev")
@PathVariable @RequestParam @RequestParam@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date datetime @RequestParam@DateTimeFormat(pattern = "HH:mm:ss") LocalTime time @ModelAttribute @RequestBody @RequestHeader
Response
@ResponseBody @ResponseHeader @ResponseStatus
Convert Request Parameter Types
/** * This method used in your Controller, * or you can put the method in your BaseController. */ @InitBinder publicvoidinitBinder(WebDataBinder binder) { // Convert field type from string to Date binder.registerCustomEditor(Date.class, newPropertyEditorSupport() { @Override publicvoidsetAsText(String text) { setValue(DateUtils.parseDate(text)); } }); }
By default all RuntimeExceptions rollback transaction whereas checked exceptions don’t. This is an EJB legacy. You can configure this by using rollbackFor() and noRollbackFor() annotation parameters: @Transactional(rollbackFor=Exception.class). This will rollback transaction after throwing any exception.
@Configuration: This annotation marks a class as a Configuration class for Java-based configuration. This is particularly important if you favor Java-based configuration over XML configuration.
@ComponentScan: This annotation enables component-scanning so that the web controller classes and other components you create will be automatically discovered and registered as beans in Spring’s Application Context.
@EnableAutoConfiguration: This annotation enables the magical auto-configuration feature of Spring Boot, which can automatically configure a lot of stuff for you.
@NotNull// a constrained CharSequence, Collection, Map, or Array is valid as long as it's not null, but it can be empty @NotEmpty// a constrained CharSequence, Collection, Map, or Array is valid as long as it's not null and its size/length is greater than zero @NotBlank// a constrained String is valid as long as it's not null and the trimmed length is greater than zero. @Null @Size// The annotated element size must be between the specified boundaries (included). @Pattern// The annotated CharSequence must match the specified regular expression. @Email
@Future// The annotated element must be an instant, date or time in the future. @FutureOrPresent @Past// The annotated element must be an instant, date or time in the past. @PastOrPresent
@JsonIgnore// for field @JsonIgnoreProperties({"fieldname1", "fieldname2"})// for POJO class @JsonInclude// annotation used to define if certain "non-values" (nulls or empty values) should not be included when serializing
@Data: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields, and @RequiredArgsConstructor.
Generate a null-check statement
publicNonNullExample(@NonNull Person person) { super("Hello"); this.name = person.getName(); }
Result code
publicNonNullExample(@NonNull Person person) { super("Hello"); if (person == null) { thrownewNullPointerException("person is marked @NonNull but is null"); } this.name = person.getName(); }
Automatic resource management: Call your close() methods safely with no hassle.
publicstaticvoidmain(String[] args)throws IOException { @CleanupInputStreamin=newFileInputStream(args[0]); @CleanupOutputStreamout=newFileOutputStream(args[1]); byte[] b = newbyte[10000]; while (true) { intr= in.read(b); if (r == -1) break; out.write(b, 0, r); } }
To sneakily throw checked exceptions without actually declaring this in your method’s throws clause
@SneakyThrows(UnsupportedEncodingException.class) public String utf8ToString(byte[] bytes) { returnnewString(bytes, "UTF-8"); }
When I using MyBatis-Plus’ com.baomidou.mybatisplus.extension.plugins.pagination.Page object as one of parameters passing mapper XML to find my page data, there are some errors.
org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 0,10' at line 58 ### The error may exist in file [D:\jtg\Repositories\manage-console-app\target\classes\mapper\modules\sysmp\CrmCustomerMapper.xml] ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### SQL: select ... limit 0, 10 LIMIT ?,? ### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 0,10' at line 58 ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 0,10' at line 58
Solutions
Using yourself defined Page object as the parameter, don’t use MyBatis-Plus Page object.
Reasons
When you using MyBatis-Plus Page object as parameter passing to mapper XML, The MyBatis-Plus will automate add the string LIMIT ?,? to end of the mapper XML SQL.
List<Integer> list = new ArrayList(Arrays.asList(1, 2, 3));
Initialize Set variables
// Using Another Collection Instance Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
// Using Anonymous Class Set<Integer> set = new HashSet() {{ add(1); add(2); }};
// Using Stream Since Java 8 Set<String> set3 = Stream.of("a", "b", "c") .collect(Collectors.toCollection(HashSet::new));
Initialize Maps variables
// Using Anonymous Class (Not recommend, Double Brace Initialization should not be used. Replace of to use map.put(key, value).) Map<Integer, String> map = new HashMap<Integer, String>() {{ put(1, "one"); put(2, "two"); put(3, "three"); }};
// Using Stream Since Java 8 Map<String, Integer> map2 = Stream.of(new Object[][] { { "key1", 1 }, { "key2", 2 }, }).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));
// Using a Stream of Map.Entry Map<String, Integer> map3 = Stream.of( new AbstractMap.SimpleEntry<>("key1", 1), new AbstractMap.SimpleEntry<>("key2", 2)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
// JDK 8 (Don't expose internal_list reference of unmodifiableList(List internale_list)). Arrays.asList() can't increase size, but it can modify its elements. public static final List UNMODIFY_LIST = Collections.unmodifiableList(Arrays.asList(1, 2, 3));
// JDK 9 (Recommend, less space cost) public static final List stringList = List.of("a", "b", "c");
Initialize Immutable Set
// JDK 8 public static final Set<String> stringSet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c")));
// JDK 9 (Recommend) public static final Set<String> stringSet2 = Set.of("a", "b", "c");
Initialize Immutable Map
// Immutable Map, JDK 8 public static final Map<Integer, String> UNMODIFY_MAP = Collections.unmodifiableMap( new HashMap<Integer, String>() { { put(1, "one"); put(2, "two"); put(3, "three"); }; });
// java 9, return ImmutableCollections (Recommend) public static final Map<Integer, String> my_map2 = Map.of(1, "one", 2, "two");
// java 10, return ImmutableCollections (Recommend) public static final Map<Integer, String> my_map3 = Map.ofEntries( entry(1, "One"), entry(2, "two"), entry(3, "three"));
Enumeration Type vs Constants
If number of a set of constant is fixed, you should use enum type.
If number of a set of constant is increasing and variable, you should use constant variables.
public static final int MONDAY = 0; public static final int TUESDAY = 1; public static final int WEDNESDAY = 2; public static final int THURSDAY = 3; public static final int FRIDAY = 4; public static final int SATURDAY = 5; public static final int SUNDAY = 6;
Type Formatting
Integer formatting
// Specifying length. Stringstr2= String.format("|%10d|", 101); // | 101| // Left-justifying within the specified width. Stringstr3= String.format("|%-10d|", 101); // |101 | // Filling with zeroes. Stringstr4= String.format("|%010d|", 101); // |0000000101|
Strings= String.format("name is %s", name); // Specify Maximum Number of Characters String.format("|%.5s|", "Hello World"); // |Hello| // Fill with zeros String.format("%32s", Integer.toBinaryString(value)).replace(' ', '0')
If the template string contain %, you need replace with %%. For example,
String.format("%s increase 7%%", "Stock"); // Stock increase 7% String.format("name like '%%%s%%'", "Jack"); // name like '%Jack%'
Sometimes we need to access our web projects running on local environments by domain names. We can reverse proxy a virtual domain by Nginx. Then we can use configured domain names to visit our local projects.
Warning: Ensure you are not using an HTTP proxy client such as v2rayN before accessing virtual domain URLs.
Stop Nginx
CMD of Windows
cd D:\nginx-1.18.0
# fast shutdown nginx -s stop
# graceful shutdown nginx -s quit
Git bash
cd D:\nginx-1.18.0
# fast shutdown ./nginx.exe -s stop
# graceful shutdown ./nginx.exe -s quit
Reload the configuration of Nginx
CMD of Windows
cd D:\nginx-1.18.0 nginx -s reload
Git bash
cd D:\nginx-1.18.0 ./nginx.exe -s reload
Note
Ensure that the ports 80, 433… where Nginx is listening are not occupied.
Ensure you are not using an HTTP proxy client such as v2rayN before accessing virtual domain URLs.
You must use Nginx commands to start and stop Nginx. Else you can’t stop the Nginx. Unless the Nginx process is killed in the task manager-Windows details or the Windows system is restarted.
Before running start nginx, you must check if an Nginx server is running. If an Nginx server is running, you must run nginx -s stop first. Repeatedly running start nginx will start multiple Nginx servers, and you can’t stop all Nginx servers. Unless the Nginx process is killed in the task manager-Windows details or the Windows system is restarted.