In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "a sub-table plug-in handwritten with Mybatis". In daily operation, I believe that many people have doubts about using Mybatis to write a sub-table plug-in. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "using Mybatis to write a sub-table plug-in". Next, please follow the editor to study!
Background
Things are dark, A Xing's superior leader is responsible for recording information business, the daily estimated amount of data is about 150000, so the introduction of sharding-jdbc as a sub-table.
After the superior leader finished the development of the business, he went through a wave of self-test, and after git push, he was busy with other things.
The framework of the project is SpringBoot+Mybaits
Something's wrong.
A Xing is responsible for the business has also been developed, skilled git pull, ready to self-test, unit test run, come back to the toilet to finish work, is so confident.
After coming back, take a look at the console, people are stupid, a red, the heart can not help but sigh "if this is a stock fund would be good."
When there is a problem, it is necessary to solve it. With the deepening of the investigation, I frowned and found that it was not simple. How could some of the previous codes have been reported wrong?
With the further investigation, we finally followed the Mybatis source code, and found that the culprit was caused by sharding-jdbc, because the data source was sharding-jdbc, and the subsequent execution of sql was caused by ShardingPreparedStatement.
This means that sharding-jdbc affects all business tables of the project, because in the end, database interaction is done by ShardingPreparedStatement, and some historical sql statements cannot be handled by ShardingPreparedStatement because of sql functions or other writing methods.
The key code is as follows
As soon as the problem was found, A Xing immediately gave it back to leader.
Alas, I still wanted to touch the fish, but it seems that there is no time to touch the fish, and there is one more task.
Analysis.
Unexpectedly, give it to A Xing to do it, just roll up your sleeves and dry it. First, take a look at the requirements of the sub-meter function.
Support custom sub-table policy
Can control the range of influence.
Versatility
The score table will be established in advance, so there is no need to consider the problem that the table does not exist, the core logic implementation, through the partition strategy to get the score table name, and then dynamically replace the score table name to sql.
Sub-table strategy
In order to support the sub-table policy, we need to define the abstract interface of the sub-table policy, as follows
/ * * @ Author programmer A Xing * @ Description subtable strategy interface * @ Date 2021-5-9 * / public interface ITableShardStrategy {/ * * @ author: programmer A Xing * @ description: generate the subtable name * @ param tableNamePrefix table prefix name * @ param value value * @ date: 2021-5-9 * @ return: java. Lang.String * / String generateTableName (String tableNamePrefix Object value) / * verify tableNamePrefix * / default void verificationTableNamePrefix (String tableNamePrefix) {if (StrUtil.isBlank (tableNamePrefix)) {throw new RuntimeException ("tableNamePrefix is null");}
The task of the generateTableName function is to generate the subtable name, with tableNamePrefix and value,tableNamePrefix as the prefixes in the input parameters, and value as the logical parameter to generate the subtable name.
The verificationTableNamePrefix function verifies that tableNamePrefix is required and is available to the implementation class.
For ease of understanding, the following is the id modeling strategy code, which takes two tables.
/ * * @ Author programmer A Xing * @ Description subtable strategy id * @ Date 2021-5-9 * / @ Component public class TableShardStrategyId implements ITableShardStrategy {@ Override public String generateTableName (String tableNamePrefix, Object value) {verificationTableNamePrefix (tableNamePrefix); if (value = = null | | StrUtil.isBlank (value.toString () {throw new RuntimeException ("value is null") } long id = Long.parseLong (value.toString ()); / / optimized return tableNamePrefix + "_" + (id% 2) can be cached here;}}
The value passed in is the id value, and the value after the module is taken with tableNamePrefix stitching id, the subtable name is returned.
Control the scope of influence
The sub-table policy has been abstracted, and the following is to consider the scope of control. We all know that in the Mybatis specification, each Mapper class corresponds to a business subject table, and the function of the Mapper class corresponds to the relevant sql of the business subject table.
A Xing thinks that you can annotate the Mapper class, which means that the business subject table corresponding to the Mpaaer class has sub-table requirements. From the specification, the host table corresponding to each function of the Mapper class is correct, but some students may not write it according to the specification.
Suppose that the Mpaaer class corresponds to table B, and a function of the Mpaaer class writes the sql of table A, or even historical problems, so annotations can be typed not only on the Mapper class, but also on any function of the Mapper class, and ensure that the small granularity covers the coarse granularity.
A Xing customizes the sub-table comments here, the code is as follows
/ * * @ Author programmer A Xing * @ Description subtable Note * @ Date 2021-5-9 * / @ Target (value = {ElementType.TYPE,ElementType.METHOD}) @ Retention (RetentionPolicy.RUNTIME) public @ interface TableShard {/ / table prefix String tableNamePrefix (); / / value String value () default "" / / whether it is a field name, if you need to resolve the value of the request parameter to change the field name (default no) boolean fieldFlag () default false; / / the corresponding subtable policy class Class parameterObjectClass = parameterObject.getClass (); Field declaredField = parameterObjectClass.getDeclaredField (value); declaredField.setAccessible (true); Object valueObject = declaredField.get (parameterObject) / / replace sql replaceSql (tableShard, valueObject, metaObject, boundSql);} else {/ / do not need to process parameterField / / replace sql replaceSql (tableShard, value, metaObject, boundSql);} / / execute the next plug-in logic return invocation.proceed () } @ Override public Object plugin (Object target) {/ / wraps the target class only when the target class is of type StatementHandler, otherwise it directly returns the target itself, reducing the number of times the target is represented by if (target instanceof StatementHandler) {return Plugin.wrap (target, this);} else {return target }} / * * @ param object * @ methodName: isBaseType * @ author: programmer A Xing * @ description: basic data type verification, true is False No * @ date: 2021-5-9 * @ return: boolean * / private boolean isBaseType (Object object) {if (object.getClass (). IsPrimitive () | | object instanceof String | | object instanceof Integer | | object instanceof Double | | object instanceof Float | | object instanceof Long | | object instanceof Boolean | | object instanceof Byte | | object instanceof Short) {return true } else {return false }} / * @ param tableShard subtable Note * @ param value value * @ param metaObject mybatis reflection object * @ author: programmer A Xing * @ description: replace sql * @ date: 2021-5-9 * @ return: void * / private void replaceSql (TableShard tableShard, Object value MetaObject metaObject, BoundSql boundSql) {String tableNamePrefix = tableShard.tableNamePrefix () / / get policy class Class / / corresponding LogDateMapper#queryList function select id as id, comment as comment,create_date as createDate from tb_log_date / corresponding LogDateMapper#save function insert into tb_log_date (id, comment,create_date) values (# {id}) # {comment} # {createDate})-/ / corresponding LogIdMapper#queryOne Function select id as id Comment as comment,create_date as createDate from tb_log_id where id = # {id} / / the corresponding save function insert into tb_log_id (id, comment,create_date) values (# {id}, # {comment}, # {createDate}) executes the following unit test
Date table unit test execution
@ Test void test () {LogDate logDate = new LogDate (); logDate.setId (snowflake.nextId ()); logDate.setComment ("Test content"); logDate.setCreateDate (new Date ()); / / insert logDateMapper.save (logDate); / / query List logDates = logDateMapper.queryList (); System.out.println (JSONUtil.toJsonPrettyStr (logDates));}
Output result
Id sub-table unit test execution
@ Test void test () {LogId logId = new LogId (); long id = snowflake.nextId (); logId.setId (id); logId.setComment ("Test"); logId.setCreateDate (new Date ()); / / insert logIdMapper.save (logId); / / query LogId logIdObject = logIdMapper.queryOne (id); System.out.println (JSONUtil.toJsonPrettyStr (logIdObject));}
Output result
Make a brief summary
This article can be used as a tutorial for the advanced use of Mybatis, through the Mybatis interceptor to achieve sub-table function, to meet the basic business needs, although relatively simple, but the expansion mechanism and design of Mybatis is worth learning and thinking.
At this point, the study of "handwriting a sub-table plug-in with Mybatis" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.