当前位置:网站首页>Personal imitation SSM framework
Personal imitation SSM framework
2022-07-07 05:54:00 【Qingcheng】
Personal imitation SSM frame
1、Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wnx.mall.tiny</groupId>
<artifactId>web-my-ssm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>web-my-ssm</name>
<description> Personal imitation SSM frame </description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.14.RELEASE</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
<!-- Reflection can get the real method name -->
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、Spring The configuration file
Put in resources\applicationContext.xml
<?xml version="1.0" encoding="utf-8"?>
<beans>
<bean id="pmsBrandMapper" class="com.wnx.mall.tiny.mapper.impl.PmsBrandMapperImpl"/>
<bean id="PmsBrandService" class="com.wnx.mall.tiny.service.impl.PmsBrandServiceImpl">
<property name="pmsBrandMapper" ref="pmsBrandMapper"/>
</bean>
<bean id="brand" class="com.wnx.mall.tiny.controller.PmsBrandController">
<property name="fruitService" ref="fruitService"/>
</bean>
</beans>
3、Web.xml To configure
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<!-- Configure context parameters -->
<context-param>
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>d
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
<!--Spring The location of the configuration file -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
</web-app>
4、 Context load listener ContextLoaderListener
be responsible for Create... When the context starts IOC Containers , Then save it to application Scope
package com.wnx.myssm.mylistner;
import com.wnx.myssm.myioc.BeanFactory;
import com.wnx.myssm.myioc.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/** * Context load listener */
@WebListener
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//1. Create... When the context starts IOC Containers , Then save it to application Scope
ServletContext application = sce.getServletContext();
String path = application.getInitParameter("contextConfigLocation");
BeanFactory beanFactory = new ClassPathXmlApplicationContext(path);
application.setAttribute("beanFactory",beanFactory);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
5、 Front controller DispatcherServlet
package com.wnx.myssm.mysrpingmvc;
import com.wnx.myssm.myioc.BeanFactory;
import com.wnx.myssm.utils.StringUtil;
import lombok.SneakyThrows;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/** * all *.do Your request will enter the Servlet!!! */
@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {
private BeanFactory beanFactory ;
public DispatcherServlet(){
}
public void init() throws ServletException {
//1.Servlet At the bottom of the build, you will call Init() Method , Integrate ViewBaseServlet, Going to call ViewBaseServlet Of Init()
super.init();
//2. from application Scope to get IOC Containers
ServletContext application = getServletContext();
Object beanFactoryObj = application.getAttribute("beanFactory");
if(beanFactoryObj!=null){
beanFactory = (BeanFactory)beanFactoryObj ;
}else{
throw new RuntimeException("IOC Container acquisition failed !");
}
}
@SneakyThrows
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. obtain Bean ID
String servletPath = request.getServletPath();
servletPath = servletPath.substring(1);
int lastDotIndex = servletPath.lastIndexOf(".do") ;
servletPath = servletPath.substring(0,lastDotIndex);
//2. according to ID Take out of the container Bean
Object controllerBeanObj = beanFactory.getBean(servletPath);
//3. Get method name
String operate = request.getParameter("operate");
if(StringUtil.isEmpty(operate)){
operate = "index" ; }
Method[] methods = controllerBeanObj.getClass().getDeclaredMethods();
for (Method method : methods) {
//4. obtain Handler Method object
if (operate.equals(method.getName())) {
Parameter[] parameters = method.getParameters();
Object[] parameterValues = new Object[parameters.length];
//5. complete Controller Method parameter binding
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
String parameterName = parameter.getName();
if ("request".equals(parameterName)) {
parameterValues[i] = request;
} else if ("response".equals(parameterName)) {
parameterValues[i] = response;
} else if ("session".equals(parameterName)) {
parameterValues[i] = request.getSession();
} else {
String parameterValue = request.getParameter(parameterName);
String typeName = parameter.getType().getName();
Object parameterObj = parameterValue;
if (parameterObj != null) {
if ("java.lang.Integer".equals(typeName)) {
parameterObj = Integer.parseInt(parameterValue);
}
}
if (parameterObj != null) {
if ("java.lang.Long".equals(typeName)) {
parameterObj = Long.parseLong(parameterValue);
}
}
parameterValues[i] = parameterObj;
}
}
//6. Reflection execution method
method.setAccessible(true);
Object returnObj = method.invoke(controllerBeanObj, parameterValues);
//7. The view
String methodReturnStr = (String) returnObj;
if (methodReturnStr.startsWith("redirect:")) {
String redirectStr = methodReturnStr.substring("redirect:".length());
response.sendRedirect(redirectStr);
} else {
super.processTemplate(methodReturnStr, request, response);
}
}
}
}
}
6、 view resolver ViewBaseServlet
package com.wnx.myssm.mysrpingmvc;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ViewBaseServlet extends HttpServlet {
private TemplateEngine templateEngine;
@Override
public void init() throws ServletException {
// 1. obtain ServletContext object
ServletContext servletContext = this.getServletContext();
// 2. establish Thymeleaf Parser object
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
// 3. Set parameters to the parser object
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setPrefix(servletContext.getInitParameter("view-prefix"));
templateResolver.setSuffix(servletContext.getInitParameter("view-suffix"));
templateResolver.setCacheTTLMs(60000L);
templateResolver.setCacheable(true);
templateResolver.setCharacterEncoding("utf-8");
// 4. Create template engine object
templateEngine = new TemplateEngine();
// 5. Set the template parser for the template engine object
templateEngine.setTemplateResolver(templateResolver);
}
protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 1. Set the content type and character set of the response body
resp.setContentType("text/html;charset=UTF-8");
// 2. establish WebContext object
WebContext webContext = new WebContext(req, resp, getServletContext());
// 3. Process template data
templateEngine.process(templateName, webContext, resp.getWriter());
}
}
7、IOC Container context ClassPathXmlApplicationContext
- abstract Bean factory
package com.wnx.myssm.myioc;
/** * Bean Build factory */
public interface BeanFactory {
Object getBean(String id);
}
- Realization :ClassPathXmlApplicationContext
package com.wnx.myssm.myioc;
import com.wnx.myssm.utils.StringUtil;
import lombok.SneakyThrows;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String,Object> beanMap = new HashMap<>();
@SneakyThrows
public ClassPathXmlApplicationContext(){
this("applicationContext.xml");
}
@SneakyThrows
public ClassPathXmlApplicationContext(String path){
if(StringUtil.isEmpty(path)){
throw new RuntimeException("IOC The container's configuration file does not specify ..."); }
//1. according to Resource Under the table of contents applicationContext.xml, Construct document objects
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder() ;
Document document = documentBuilder.parse(inputStream);
//2. Scan all Bean label
NodeList beanNodeList = document.getElementsByTagName("bean");
for(int i = 0 ; i<beanNodeList.getLength() ; i++){
Node beanNode = beanNodeList.item(i);
if(beanNode.getNodeType() == Node.ELEMENT_NODE){
//1. according to Bean label , Construct objects from reflections
Element beanElement = (Element)beanNode ;
String beanId = beanElement.getAttribute("id");
String className = beanElement.getAttribute("class");
Class beanClass = Class.forName(className);
Object beanObj = beanClass.newInstance() ;
//2. Deposit in Map Containers
beanMap.put(beanId , beanObj) ;
}
}
//3. assemble bean Dependencies between
for(int i = 0 ; i<beanNodeList.getLength() ; i++){
Node beanNode = beanNodeList.item(i);
if(beanNode.getNodeType() == Node.ELEMENT_NODE) {
Element beanElement = (Element) beanNode;
String beanId = beanElement.getAttribute("id");
NodeList beanChildNodeList = beanElement.getChildNodes();
for (int j = 0; j < beanChildNodeList.getLength() ; j++) {
//4. Take the dependent from the container Bean Inject into the dependent Bean in
Node beanChildNode = beanChildNodeList.item(j);
if(beanChildNode.getNodeType()==Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())){
Element propertyElement = (Element) beanChildNode;
String propertyName = propertyElement.getAttribute("name");
String propertyRef = propertyElement.getAttribute("ref");
Object refObj = beanMap.get(propertyRef);
Object beanObj = beanMap.get(beanId);
Class beanClazz = beanObj.getClass();
Field propertyField = beanClazz.getDeclaredField(propertyName);
propertyField.setAccessible(true);
propertyField.set(beanObj,refObj);
}
}
}
}
}
/** * according to ID obtain Bean * @param id ID * @return Bean */
@Override
public Object getBean(String id) {
return beanMap.get(id);
}
}
8、 Configure character encoding filter
package com.wnx.myssm.myfilter;
import com.wnx.myssm.utils.StringUtil;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/** * Character encoding filter Filter *.do Request */
@WebFilter(urlPatterns = {
"*.do"},initParams = {
@WebInitParam(name = "encoding",value = "UTF-8")})
public class CharacterEncodingFilter implements Filter {
private String encoding = "UTF-8";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String encodingStr = filterConfig.getInitParameter("encoding");
if(StringUtil.isNotEmpty(encodingStr)){
encoding = encodingStr ;
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
((HttpServletRequest)servletRequest).setCharacterEncoding(encoding);
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
9、 Persistence layer frame BaseMapper
package com.wnx.mall.tiny.mapper;
import com.wnx.myssm.mymapper.ConnUtil;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseMapper<T> {
private final String DRIVER = "com.mysql.cj.jdbc.Driver";
private final String URL = "jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&useSSL=false";
private final String USER = "root";
private final String PWD = "root" ;
private Connection conn ;
private PreparedStatement psmt ;
private ResultSet rs ;
private Class entityClass ;
public BaseMapper(){
//1. Get program runtime ,T The type of actual reference .
Type genericType = getClass().getGenericSuperclass();
Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
Type actualType = actualTypeArguments[0];
// 2. Construct the T Class object of
try {
entityClass = Class.forName(actualType.getTypeName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/** * Get database connection * @return A database connection */
private Connection getConn(){
return ConnUtil.getConn();
}
/** * Release database related resources * @param rs Result set object * @param psmt Precompiled statement object * @param conn Database connection */
private void close(ResultSet rs, PreparedStatement psmt, Connection conn){
try {
if (rs != null) {
rs.close();
}
if(psmt!=null){
psmt.close();
}
if(conn!=null && !conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/*** * Placeholders for preprocessing statement objects ? Set parameters * @param psmt Preprocess the statement object * @param params Parameters * @throws SQLException SQL abnormal */
private void setParams(PreparedStatement psmt , Object... params) throws SQLException {
if(params!=null && params.length>0){
for (int i = 0; i < params.length; i++) {
psmt.setObject(i+1,params[i]);
}
}
}
/*** * Perform database update operation * @param sql Database operation SQL * @param params Update parameters * @return Rows affected */
protected int executeUpdate(String sql , Object... params){
boolean insertFlag = false ;
try {
conn = getConn();
psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
setParams(psmt,params);
int count = psmt.executeUpdate() ;
rs = psmt.getGeneratedKeys();
if(rs.next()){
return ((Long)rs.getLong(1)).intValue();
}
return count ;
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(rs,psmt,conn);
}
return 0;
}
/** * Give... By reflection technology obj Object's property Attribute propertyValue value * @param obj object model * @param property model Field * @param propertyValue model value */
private void setValue(Object obj , String property , Object propertyValue){
//1. Get the class of the object
Class clazz = obj.getClass();
try {
//2. Get the member variable according to the member variable name
Field field = clazz.getDeclaredField(property);
//3. Reflection assignment
if(field!=null){
field.setAccessible(true);
field.set(obj,propertyValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/** * Execute complex queries , Returns, for example, statistical results * @param sql Database operation SQL * @param params Update parameters * @return An array of objects */
protected Object[] executeComplexQuery(String sql , Object... params){
try {
//1. Execute the query
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//2. Construct column containers
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Object[] columnValueArr = new Object[columnCount];
//3. The query results are put into the column container
if(rs.next()){
for(int i = 0 ; i<columnCount;i++){
Object columnValue = rs.getObject(i+1);
columnValueArr[i]=columnValue;
}
//4. Return column container
return columnValueArr ;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
/** * Execute the query , Returns a single entity object * @param sql Database operation SQL * @param params Query parameters * @return Entity Model */
protected T load(String sql , Object... params){
try {
//1. Query operation
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//2. Object Assignment
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
if(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);
//3. The transformation of hump naming
while (columnName.contains("_")) {
int index = columnName.indexOf("_");
String target = columnName.substring(index + 1, index + 2);
columnName = columnName.replace(("_" + target), target.toUpperCase());
}
Object columnValue = rs.getObject(i+1);
setValue(entity,columnName,columnValue);
}
//3. Returns the object
return entity ;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
/*** * Execute the query , return List * @param sql Database operation SQL * @param params Query parameters * @return Set of entities List */
protected List<T> executeQuery(String sql , Object... params){
List<T> list = new ArrayList<>();
try {
//1. Execute the query
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//2. Object Assignment
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);
//3. The transformation of hump naming
while (columnName.contains("_")) {
int index = columnName.indexOf("_");
String target = columnName.substring(index + 1, index + 2);
columnName = columnName.replace(("_" + target), target.toUpperCase());
}
Object columnValue = rs.getObject(i+1);
setValue(entity,columnName,columnValue);
}
//4. Add to collection
list.add(entity);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
//5. Back to the assembly
return list ;
}
}
10、 Transaction control TransactionManager
package com.wnx.myssm.mytransaction;
import com.wnx.myssm.mymapper.ConnUtil;
import java.sql.Connection;
import java.sql.SQLException;
public class TransactionManager {
// Open transaction
public static void beginTrans() throws SQLException {
ConnUtil.getConn().setAutoCommit(false);
}
// Commit transaction
public static void commit() throws SQLException {
Connection conn = ConnUtil.getConn();
conn.commit();
ConnUtil.closeConn();
}
// Roll back the transaction
public static void rollback() throws SQLException {
Connection conn = ConnUtil.getConn();
conn.rollback();
ConnUtil.closeConn();
}
}
11、 Thread knowledge
Use a connection Connection To say things , One request corresponds to one thread . Rewrite the get database connection class
- ConnUtil
package com.wnx.myssm.mymapper;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnUtil {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true";
private static final String USER = "root";
private static final String PWD = "root";
/** * Create database connection * @return Back to database connection */
private static Connection createConn() {
try {
Class.forName(DRIVER);
return DriverManager.getConnection(URL, USER, PWD);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return null;
}
/** * Get database connection * @return Database connection */
public static Connection getConn() {
//1. If there is a connection with a local thread , Create a .
Connection conn = threadLocal.get();
if (conn == null) {
conn = createConn();
threadLocal.set(conn);
}
return threadLocal.get();
}
/** * Close database connection * @throws SQLException SQL abnormal */
public static void closeConn() throws SQLException {
Connection conn = threadLocal.get();
if(conn==null){
return ;
}
if(!conn.isClosed()){
conn.close();
threadLocal.set(null);
}
}
}
Once something goes wrong , Let the current database connection rollback immediately .
- OpenSessionInViewFilter
package com.wnx.myssm.myfilter;
import com.wnx.myssm.mytransaction.TransactionManager;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.sql.SQLException;
@WebFilter("*.do")
public class OpenSessionInViewFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try{
TransactionManager.beginTrans();
System.out.println(" Open transaction ....");
filterChain.doFilter(servletRequest, servletResponse);
TransactionManager.commit();
System.out.println(" Commit transaction ...");
}catch (Exception e){
e.printStackTrace();
try {
TransactionManager.rollback();
System.out.println(" Roll back the transaction ....");
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
@Override
public void destroy() {
}
}
边栏推荐
- Simple case of SSM framework
- Mac version PHP installed Xdebug environment (M1 version)
- I didn't know it until I graduated -- the principle of HowNet duplication check and examples of weight reduction
- 集群、分布式、微服务的区别和介绍
- PowerPivot - DAX (function)
- 《HarmonyOS实战—入门到开发,浅析原子化服务》
- pytorch_ 01 automatic derivation mechanism
- bat 批示处理详解
- Hcip seventh operation
- 往图片添加椒盐噪声或高斯噪声
猜你喜欢
Introduction to distributed transactions
Forkjoin is the most comprehensive and detailed explanation (from principle design to use diagram)
Interview questions and salary and welfare of Shanghai byte
Add salt and pepper noise or Gaussian noise to the picture
cf:C. Column Swapping【排序 + 模拟】
Lombok plug-in
C#可空类型
话说SQLyog欺骗了我!
Web authentication API compatible version information
ML之shap:基于adult人口普查收入二分类预测数据集(预测年收入是否超过50k)利用shap决策图结合LightGBM模型实现异常值检测案例之详细攻略
随机推荐
原生小程序 之 input切换 text与password类型
PTA 天梯赛练习题集 L2-004 搜索树判断
STM32按键状态机2——状态简化与增加长按功能
Mybaits multi table query (joint query, nested query)
nVisual网络可视化
线性回归
[云原生]微服务架构是什么?
《HarmonyOS实战—入门到开发,浅析原子化服务》
SAP Spartacus checkout 流程的扩展(extend)实现介绍
What are the common message queues?
SQL Server 2008 各种DateTime的取值范围
《2022中国低/无代码市场研究及选型评估报告》发布
Differences and introduction of cluster, distributed and microservice
得物客服一站式工作台卡顿优化之路
Five core elements of architecture design
PTA TIANTI game exercise set l2-003 moon cake test point 2, test point 3 Analysis
PTA ladder game exercise set l2-002 linked list de duplication
linear regression
Flask1.1.4 Werkzeug1.0.1 源碼分析:啟動流程
SAP ABAP BDC(批量数据通信)-018