Mybatis generator source code learning and modification
Required jar package: generator-mybatis-generator-1.3.2.jar
Background:
The company's database is divided into sub databases. During query, the customerId must be modified, otherwise the query efficiency will become low. The database table 60 +, almost every table of the new project has added new fields, and a new mapper file of mybatis needs to be generated.
Scheme:
It is planned to use the mybatis generator plug-in to generate entity classes, interfaces and xml.
Requirements:
The generated sql and interface not only generate the query of the primary key, but also carry the customerId field to improve the query rate.
The original mybatis generator plug-in does not meet the conditions. The mybatis generator plug-in can generate query select that depends on the primary key and update that depends on the selective modification of the primary key. Therefore, you need to modify the code in the mybatis generator plug-in.
Objectives:
By modifying the source code, the mapper of mybatis is generated
Solution:
Download the required mybatis generator plug-in source package and get it after decompression
Here, you only need to modify the files in the core
I'm so familiar with the simple maven project. I'll directly write the code. The goal is very clear. Select byprimarykey and updateByPrimaryKey are modified to sql statements that meet the conditions (and carry customerId)
xml generation code location:
The red part is the java code that generates xml
Principle:
These classes are generated by splicing StringBuilder.append() methods and finally by parsing elements, which can be understood as xml parsing.
How to modify the generated code of xml:
Here, modify the selectByPrimaryKey() method in mapper.xml, and updateByPrimaryKey() is the same
@Override public void addElements(XmlElement parentElement) { XmlElement answer = new XmlElement("select"); //$NON-NLS-1$ answer.addAttribute(new Attribute( "id", introspectedTable.getSelectByPrimaryKeyStatementId())); //$NON-NLS-1$ if (introspectedTable.getRules().generateResultMapWithBLOBs()) { answer.addAttribute(new Attribute("resultMap", //$NON-NLS-1$ introspectedTable.getResultMapWithBLOBsId())); } else { answer.addAttribute(new Attribute("resultMap", //$NON-NLS-1$ introspectedTable.getBaseResultMapId())); } String parameterType; if (introspectedTable.getRules().generatePrimaryKeyClass()) { parameterType = introspectedTable.getPrimaryKeyType(); } else { // PK fields are in the base class. If more than on PK // field, then they are coming in a map. if (introspectedTable.getPrimaryKeyColumns().size() > 1) { parameterType = "map"; //$NON-NLS-1$ } else { parameterType = introspectedTable.getPrimaryKeyColumns().get(0) .getFullyQualifiedJavaType().toString(); } } answer.addAttribute(new Attribute("parameterType", //$NON-NLS-1$ parameterType)); context.getCommentGenerator().addComment(answer); StringBuilder sb = new StringBuilder(); sb.append("select "); //$NON-NLS-1$ if (stringHasValue(introspectedTable .getSelectByPrimaryKeyQueryId())) { sb.append('\''); sb.append(introspectedTable.getSelectByPrimaryKeyQueryId()); sb.append("' as QUERYID,"); //$NON-NLS-1$ } answer.addElement(new TextElement(sb.toString())); answer.addElement(getBaseColumnListElement()); if (introspectedTable.hasBLOBColumns()) { answer.addElement(new TextElement(",")); //$NON-NLS-1$ answer.addElement(getBlobColumnListElement()); } sb.setLength(0); sb.append("from "); //$NON-NLS-1$ sb.append(introspectedTable .getAliasedFullyQualifiedTableNameAtRuntime()); answer.addElement(new TextElement(sb.toString())); boolean and = false; for (IntrospectedColumn introspectedColumn : introspectedTable .getPrimaryKeyColumns()) { sb.setLength(0); if (and) { sb.append(" and "); //$NON-NLS-1$ } else { sb.append("where "); //$NON-NLS-1$ and = true; } //Here is the last location for generating sql sb.append(MyBatis3FormattingUtilities .getAliasedEscapedColumnName(introspectedColumn)); sb.append(" = "); //$NON-NLS-1$ //The original code is sb. Append (mybatis3formattingutilities. Getparameterclause (introspected column)); sb.append(MyBatis3FormattingUtilities .getParameterClause1(introspectedColumn)); answer.addElement(new TextElement(sb.toString())); } if (context.getPlugins() .sqlMapSelectByPrimaryKeyElementGenerated(answer, introspectedTable)) { parentElement.addElement(answer); } }
Modify core splicing code
public static String getParameterClause( IntrospectedColumn introspectedColumn) { return getParameterClause(introspectedColumn, null); } public static String getParameterClause1( IntrospectedColumn introspectedColumn) { return getParameterClause1(introspectedColumn, null); } public static String getParameterClause1( IntrospectedColumn introspectedColumn, String prefix) { StringBuilder sb = new StringBuilder(); sb.append("#{"); //$NON-NLS-1$ sb.append(introspectedColumn.getJavaProperty(prefix)); sb.append(",jdbcType="); //$NON-NLS-1$ sb.append(introspectedColumn.getJdbcTypeName()); if (stringHasValue(introspectedColumn.getTypeHandler())) { sb.append(",typeHandler="); //$NON-NLS-1$ sb.append(introspectedColumn.getTypeHandler()); } sb.append('}'); sb.append(" and CUSTOMER_ID = #{customerId,jdbcType=VARCHAR}"); return sb.toString(); } public static String getParameterClause( IntrospectedColumn introspectedColumn, String prefix) { StringBuilder sb = new StringBuilder(); sb.append("#{"); //$NON-NLS-1$ sb.append(introspectedColumn.getJavaProperty(prefix)); sb.append(",jdbcType="); //$NON-NLS-1$ sb.append(introspectedColumn.getJdbcTypeName()); if (stringHasValue(introspectedColumn.getTypeHandler())) { sb.append(",typeHandler="); //$NON-NLS-1$ sb.append(introspectedColumn.getTypeHandler()); } sb.append('}'); return sb.toString(); }
be careful:
getParameterClause() and getParameterClause() are the source code
getParameterClause1() and getParameterClause1() are the source code
Copy the code directly and add sb. Append ("and customer_id = #{customerid, JDBC type = varchar}") at the end;
Similarly, modifying the updateByPrimaryKey() method in mapper.xml is also true and reusable
Effect drawing after generation
Modification of mybatis interface:
Original java interface code
MalltTrade selectByPrimaryKey(String tradeId);
Need to generate
MalltTrade selectByPrimaryKey(Map map);
Here is the location where the interface code is generated
Read code:
If the condition is true: single primary key; if false: joint primary key.
Simply look at true first
In the second line of code, fullyqualified javatype needs to map the parameters we need, and malltrade selectbyprimarykey (map); Method to see its type
annoying!
The package of Map is import java.util.Map;
And Map are not in the same package, and the changes here are relatively large, so this interface is modified in another way.
io stream processing in java
Direct code:
public void handle(String filename){ RandomAccessFile raf = null; try { raf = new RandomAccessFile(filename, "rw"); String line = null; long lastPoint = 0; //Remember the last offset int i=0; int m=3; StringBuffer stringBuffer = new StringBuffer(); while ((line = raf.readLine()) != null) { final long ponit = raf.getFilePointer(); if(line.contains("selectByPrimaryKey")){ //You can't modify the string here. It reads and writes at the same time. There is a problem with the offset. For example, one more character and one less character will cause file serialization. If you don't believe it, you can try it. raf.seek(lastPoint); raf.writeBytes(line); } //Import Map, import if (line.contains("import com.sitech.mios.modules.order.dao.po")){ System.out.println(i); line=line+"\nimport java.util.Map;\n"; } //Why not use replace when modifying parameters? For the federated primary key, the form of replace is MalltDataDictionary selectByPrimaryKey(@Param("xxx") xxx, @ param ("YYY") XXX); Forget to save it, but try to generate it yourself. There are too many parentheses and it's too troublesome to use regular. Anyway, I can't write this regular, h if(line.contains("selectByPrimaryKey")){ String[] split = line.split("\\("); String str=split[0]+"(Map map); ";//line.replace(split[1], "Map map); "); line=str; } stringBuffer.append(line+"\n"); lastPoint = ponit; i++; } String s = stringBuffer.toString(); //Target file location, same as above File file = new File(filename); FileWriter fout = new FileWriter(file);// Create file output stream fout.write(s); fout.close();// Close output stream } catch (Exception e) { e.printStackTrace(); } finally { try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } }
String filename is the location of mapper.java
Take it, take it, it's a perfect finish!