当前位置:网站首页>SSM integrated notes easy to understand version
SSM integrated notes easy to understand version
2022-07-06 10:51:00 【Bolus acidophilus】
Video link :【 Sangeng thatched cottage 】SSM Integrate easy to understand version
List of articles
1.SSM Integrate
1.0 Step analysis
Let's first analyze how to put Spring,SpringMVC,Mybatis Put it all together .
1.0.1 step
①Spring On Integration Mybatis
adopt Service layer Dao Layer injection Spring In the container
② Import configuration SpringMVC
hold Controller Layer injection SpringMVC In the container
③ Give Way web Automatically read when the project starts Spring Profile to create Spring Containers
have access to ContextLoaderListener To achieve Spring Container creation .
1.0.2 Common doubts
Why use two containers ?
because Controller If you don't put it in MVC There will be no effect in the container , Unable to process request . and Service If you don't put it in Spring In the container , Declarative transactions cannot be used .
SpringMVC In container Controller Need to rely on Service, Can from Spring Get the dependent Service The object ?
Spring The container is equivalent to the parent container ,MVC The container is equivalent to a sub container . In addition to using the objects in its own container, a child container can also use the objects in its parent container .
How to realize such a parent-child container relationship ?
See the video of the source code analysis stage for details . But now we can use code to simulate .
When did you make two containers have this parent-child relationship ?
stay ContextLoaderListener in , After the container is created, it will be stored in servletContext Domain . In this way DispatcherServlet Startup time , Created SpringMVC The container will be removed from servletContext Get Spring Container object , Set to its parent container , In this way, the child container can get the bean 了 . See the source code analysis video for details .
SpringMVC In container Controller Need to rely on Service, Can from Spring Get the dependent Service The object ?
How to realize such a parent-child container relationship ?
1.1 preparation
Introduce all dependencies
<!--Spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--AOP Related dependencies -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!-- mybatis Integrate to Spring The integration package -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!--mybatis rely on -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--log4j rely on , Print mybatis journal -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Paging query ,pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.0.0</version>
</dependency>
<!--mysql drive -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid data source -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- spring Integrate junit Dependence -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<!-- servlet rely on -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp rely on -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!--springmvc Dependence -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!-- jackson, To help carry out json transformation -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!--commons Upload files , If you need the file upload function , You need to add this dependency -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
Database initialization statement
CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis_db` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `mybatis_db`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `user`(`id`,`username`,`age`,`address`) values (1,'UZI',19,' Shanghai '),(2,'PDD',25,' Shanghai ');
1.2 Related configuration
① Integrate Spring and Mybatis
stay resources Create under directory Spring Core profile : applicationContext.xml The contents are as follows
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- Component scan , exclude controller-->
<context:component-scan base-package="com.sangeng">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>
<!-- Read properties file -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- Create connection pool injection container -->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
</bean>
<!--spring Integrate mybatis Creation and acquisition of post control SqlSessionFactory The object of -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sessionFactory">
<!-- Configure connection pool -->
<property name="dataSource" ref="dataSource"></property>
<!-- To configure mybatis The path to the configuration file -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!--mapper Scan configuration , Scanned mapper Objects will be injected Spring In the container -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="mapperScannerConfigurer">
<property name="basePackage" value="com.sangeng.dao"></property>
</bean>
<!-- Turn on aop Annotation support -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- Declarative transaction related configuration -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
stay resources Create under directory jdbc.properties file , The contents are as follows :
jdbc.url=jdbc:mysql://localhost:3306/mybatis_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root
stay resources Create under directory mybatis-config.xml , The contents are as follows :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- Specify the use of log4j Print Mybatis journal -->
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- Configure alias package -->
<typeAliases>
<package name="com.sangeng.domain"></package>
</typeAliases>
<plugins>
<!-- Be careful : Plug in for paging assistant , Configuration in general mapper Before -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- To designate a dialect -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
</configuration>
stay resources Create under directory log4j.properties , The contents are as follows :
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
②SpringMVC introduce
stay resources Create under directory spring-mvc.xml , The contents are as follows :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- SpringMVC Just scan controller Bag can -->
<context:component-scan base-package="com.sangeng.controller"/>
<!-- Solve the problem of static resource access , If not mvc:annotation-driven Can result in inaccessibility handler-->
<mvc:default-servlet-handler/>
<!-- Solve the response garbled code -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- Configure the view parser The front and rear ends are not separated, and the project is used -->
<!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver"> <!– Prefix required for splicing –> <property name="prefix" value="/WEB-INF/page/"></property> <!– Suffix to splice –> <property name="suffix" value=".jsp"></property> </bean>-->
<!-- Configure interceptors -->
<!-- <mvc:interceptors> <mvc:interceptor> <!– –> <mvc:mapping path="/**"/> <!– Configure the path to exclude interception –> <mvc:exclude-mapping path="/"/> <!– Configure interceptor object injection container –> <bean class=""></bean> </mvc:interceptor> </mvc:interceptors>-->
<!-- File upload parser Be careful :id It has to be for multipartResolver If you need to upload files, you can release the corresponding configuration -->
<!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">-->
<!--<!– Set the default character encoding –>-->
<!--<property name="defaultEncoding" value="utf-8"/>-->
<!--<!– The maximum total size of the file to be uploaded at one time , Unit is byte –>-->
<!--<property name="maxUploadSize" value="#{1024*1024*100}"/>-->
<!--<!– The maximum size of each uploaded file , Unit is byte –>-->
<!--<property name="maxUploadSizePerFile" value="#{1024*1024*50}"/>-->
<!--</bean>-->
</beans>
modify web.xml file
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- by DispatcherServlet Provide initialization parameters Set up springmvc The path to the configuration file name Is constant , Must be contextConfigLocation value refer to SpringMVC The location of the configuration file -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- Specifies that the project is initialized as soon as it starts DispatcherServlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!-- / At present servlet Mapping Division jsp All requests except ( Contains static resources ) *.do Express .do The end of the request path can be SpringMVC Handle ( Old projects will appear ) /* At present servlet Map all requests ( Contains static resources ,jsp), Its configuration should not be used DispatcherServlet -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Scrambling filter , from SpringMVC Provide -->
<!-- Handle post Ask for random code -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<!-- name Fixed ,value Set values as needed -->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- All requests are set utf-8 The coding -->
<url-pattern>/*</url-pattern>
</filter-mapping>
③Spring Integration into web project
Give Way web It can be created when the project starts Spring Containers . have access to Spring The monitor provided ContextLoaderListener, So we need to web.xml Configure this listener in , And configuration Spring The path to the configuration file .
<!-- To configure spring Profile path for -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Configure listeners , It can be created when the application is deployed spring Containers -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
1.3 To write Controller,Service,Dao
Let's write according to id Query the user interface to test
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public User findById(@PathVariable("id") Integer id){
User user = userService.findById(id);
return user;
}
}
public interface UserService {
User findById(Integer id);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public User findById(Integer id) {
return userDao.findById(id);
}
}
public interface UserDao {
/** * according to id Query the user * @param id * @return */
User findById(Integer id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sangeng.dao.UserDao">
<select id="findById" resultType="com.sangeng.domain.User">
select * from user where id = #{id}
</select>
</mapper>
2. Case study
2.0 Unified response format
We should ensure that the data format returned by all interfaces in a project is unified . In this way, it is more convenient for both front-end and mobile development to conduct unified processing after obtaining our data .
So we define the following result encapsulation classes
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> {
/** * Status code */
private Integer code;
/** * Prompt information , If there is an error , The front end can get this field to prompt */
private String msg;
/** * The query result data , */
private T data;
public ResponseResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
}
The previous interface is modified to :
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public ResponseResult findById(@PathVariable("id") Integer id){
User user = userService.findById(id);
if(user==null){
// Description: there is no corresponding user
return new ResponseResult(500," There is no such user ");
}
return new ResponseResult(200," Successful operation ",user);
}
}
2.1 Query all users
@RestController
public class UserController {
@Autowired
private UserService userService;
// Omit other extraneous code
@GetMapping("/user")
public ResponseResult findAll(){
List<User> list = userService.findAll();
return new ResponseResult(200," Successful operation ",list);
}
}
public interface UserService {
User findById(Integer id);
List<User> findAll();
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
// Omit other extraneous code
public List<User> findAll() {
return userDao.findAll();
}
}
public interface UserDao {
// Omit other extraneous code
List<User> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sangeng.dao.UserDao">
<select id="findAll" resultType="com.sangeng.domain.User">
select * from user
</select>
</mapper>
2.2 Paging query users
The result of paging query should include not only the found user data, but also the current number of pages , Number of entries per page , Total number of records these paging data .
Paging data encapsulation class
public class PageResult<T> {
private Integer currentPage;
private Integer pageSize;
private Integer total;
private List<T> data;
public PageResult(Integer currentPage, Integer pageSize, Integer total, List<T> data) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.total = total;
this.data = data;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{pageSize}/{pageNum}")
public ResponseResult findByPage(@PathVariable("pageSize") Integer pageSize,@PathVariable("pageNum") Integer pageNum){
PageResult pageResult = userService.findByPage(pageSize,pageNum);
return new ResponseResult(200," Successful operation ",pageResult);
}
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public PageResult findByPage(Integer pageSize, Integer pageNum) {
PageHelper.startPage(pageNum,pageSize);
List<User> list = userDao.findAll();
PageInfo pageInfo = new PageInfo(list);
PageResult pageResult = new PageResult(pageInfo.getPageNum(),pageInfo.getPageSize(), (int) pageInfo.getTotal(),list);
return pageResult;
}
}
2.3 Insert user
Controller layer
@PostMapping("/user")
public ResponseResult insertUser(@RequestBody User user){
userService.insertUser(user);
return new ResponseResult(200," Successful operation ");
}
Service layer
stay Service Add method definitions in the interface
void insertUser(User user);
Implement this method in the implementation class :
public void insertUser(User user) {
userDao.insertUser(user);
}
Dao layer
Defining methods in an interface
void insertUser(User user);
stay mapper In the mapping file
<insert id="insertUser">
insert into user values(null,#{username},#{age},#{address})
</insert>
test
{
"username":" Sangeng thatched cottage ","age":15,"address":" Excuse me, "}
2.4 Delete user
Controller layer
@DeleteMapping("/user/{id}")
public ResponseResult deleteUser(@PathVariable("id") Integer id){
userService.deleteUser(id);
return new ResponseResult(200," Successful operation ");
}
Service layer
stay Service Add method definitions in the interface
void deleteUser(Integer id);
Implement this method in the implementation class :
public void deleteUser(Integer id) {
userDao.deleteUser(id);
}
Dao layer
Defining methods in an interface
void deleteUser(Integer id);
stay mapper In the mapping file
<delete id="deleteUser">
delete from user where id = #{id}
</delete>
2.5 Update user
Controller layer
@PutMapping("/user")
public ResponseResult updateUser(@RequestBody User user){
userService.updateUser(user);
return new ResponseResult(200," Successful operation ");
}
Service layer
stay Service Add method definitions in the interface
void updateUser(User user);
Implement this method in the implementation class :
public void updateUser(User user) {
userDao.updateUser(user);
}
Dao layer
Defining methods in an interface
void updateUser(User user);
stay mapper In the mapping file
<update id="updateUser">
update user set username = #{username},age = #{age},address = #{address} where id = #{id}
</update>
3. Exception handling
We can use @ControllerAdvice Realize unified handling of exceptions . When an exception occurs, it can also return a response JSON.
The code is as follows :
@ControllerAdvice
public class SGControllerAdvice {
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult handleException(Exception e){
return new ResponseResult(500,e.getMessage());
}
}
4. Interceptor
public class SGHandlerInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
<!-- Configure interceptors -->
<mvc:interceptors>
<mvc:interceptor>
<!-- -->
<mvc:mapping path="/**"/>
<!-- Configure the path to exclude interception -->
<!--<mvc:exclude-mapping path="/"/>-->
<!-- Configure interceptor object injection container -->
<bean class="com.sangeng.interceptor.SGHandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
5. Declarative transactions
The corresponding configuration has been made , As long as service Just annotate the method
@Transactional
public void test() {
userDao.insertUser(new User(null,"test1",11,"cc"));
// System.out.println(1/0);
userDao.insertUser(new User(null,"test2",12,"cc2"));
}
6.AOP
Be careful , Use it by yourself AOP When enhancing , It should be right Service enhanced . Not right Controller enhanced , Because the faceted class will be put into the parent container , And ours Controller It's in a sub container . Parent container cannot access child container .
And if we need to be right Controller enhanced , Using interceptors will also be easier to use .
@Aspect
@Component
public class SGAspect {
// Defining cut-off points
@Pointcut("execution(* com.sangeng.service..*.*(..))")
public void pt(){
}
// enhanced
@Before("pt()")
public void before(){
System.out.println("before");
}
}
边栏推荐
- Kubesphere - deploy the actual combat with the deployment file (3)
- Why is MySQL still slow to query when indexing is used?
- MySQL33-多版本并发控制
- Generate PDM file from Navicat export table
- Timestamp with implicit default value is deprecated error in MySQL 5.6
- Use JUnit unit test & transaction usage
- @controller,@service,@repository,@component区别
- Pytorch LSTM实现流程(可视化版本)
- [leectode 2022.2.13] maximum number of "balloons"
- [unity] simulate jelly effect (with collision) -- tutorial on using jellysprites plug-in
猜你喜欢
保姆级手把手教你用C语言写三子棋
Other new features of mysql18-mysql8
Some problems in the development of unity3d upgraded 2020 VR
windows下同时安装mysql5.5和mysql8.0
Mysql27 index optimization and query optimization
Mysql28 database design specification
CSDN问答标签技能树(一) —— 基本框架的构建
Esp8266 at+cipstart= "", "", 8080 error closed ultimate solution
MySQL 29 other database tuning strategies
Mysql35 master slave replication
随机推荐
CSDN博文摘要(一) —— 一个简单的初版实现
MySQL30-事务基础知识
In fact, the implementation of current limiting is not complicated
Idea import / export settings file
Water and rain condition monitoring reservoir water and rain condition online monitoring
Pytoch LSTM implementation process (visual version)
Opencv uses freetype to display Chinese
MySQL完全卸载(Windows、Mac、Linux)
Global and Chinese markets for aprotic solvents 2022-2028: Research Report on technology, participants, trends, market size and share
Bytetrack: multi object tracking by associating every detection box paper reading notes ()
A brief introduction to the microservice technology stack, the introduction and use of Eureka and ribbon
C language string function summary
MySQL24-索引的数据结构
该不会还有人不懂用C语言写扫雷游戏吧
Kubernetes - problems and Solutions
解决:log4j:WARN Please initialize the log4j system properly.
Windows cannot start the MySQL service (located on the local computer) error 1067 the process terminated unexpectedly
CSDN Q & a tag skill tree (V) -- cloud native skill tree
Postman Interface Association
CSDN问答标签技能树(二) —— 效果优化