当前位置: 首页 > article >正文

Java框架Spring(一)

一、Spring 是什么

Spring 是一个轻量级的,IOC和AOP的一站式Java 开发框架,是为了简化企业级应用开发而生的。

名词解释:

        轻量级:框架体积小(核心模块)

        IOC:Inversion of Control,直译过来是控制反转,把创建对象的控制权,反转给spring框架。以前,在程序中需要对象都是自己new。例如new StudentDao对象。

        AOP:Aspect Oriented Programming, 直译过来就是面向切面编程。AOP 是一种编 程思想,是面向对象编程(OOP)的一种补充。

        将程序中一些公共的非业务代码分离提取出来开,然后在业务代码执行时,给他们横切进来。底层使用的是动态代理的机制实现。在我们的业务代码不显示调用,但是执行业务代码,会通过代理对象调用非业务代码

        一站式:除了核心的IOC和AOP功能之外,还对数据访问层,web层都有封装,所以是一站式的

二、spring的HelloWorld 

1、使用的model类

package com.wbc.SpringPro.model;

public class Admin {
    private String account;
    private String password;

    public Admin(String account, String password) {
        this.account = account;
        this.password = password;
    }

    public Admin() {
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

 2、spring 核心功能jar包

<!-- spring-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

3、spring的配置文件

在src/main/resources创建spring.xml文件作为配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--在spring配置文件中 注册spring管理的类 -->
    <bean id="admin" class="com.wbc.SpringPro.model.Admin"></bean>
</beans>

4、Spring的helloWorld

package com.wbc.SpringPro.test;

import com.wbc.SpringPro.model.Admin;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
        /*
        ClassPathXmlApplicationContext是spring框架中的一个具体的实现类,负责生成管理程序中的对象
        可以看作是一个容器,所以一般把spring框架称为spring容器或是IOC容器
        new ClassPathXmlApplicationContext("spring.xml");用于生成spring容器
        getBean("配置文件的id",.class文件) 从spring框架(spring容器)中获取需要的对象


        控制反转---一种编程思想
            把生成对象的控制权,反转给spring框架,矿建负责对整个对象的整个生命周期
            对外提供获取对象的方法,我们在程序中哪里需要就在哪里获取即可
        */
        ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
            Admin admin = applicationContext.getBean("admin", Admin.class);
            Admin admin1 = (Admin) applicationContext.getBean("admin");
            System.out.println(admin);
            System.out.println(admin1);

    }
}

 5、相关说明、

ClassPathXmlApplicationContext是spring框架中的一个具体的实现类,负责生成管理程序中的对象
可以看作是一个容器,所以一般把spring框架称为spring容器或是IOC容器

new ClassPathXmlApplicationContext("spring.xml");用于生成spring容器

getBean("配置文件的id",.class文件) 从spring框架(spring容器)中获取需要的对象
也可以不传入。class文件,但在接收时需要强转
控制反转---一种编程思想
    把生成对象的控制权,反转给spring框架,矿建负责对整个对象的整个生命周期
    对外提供获取对象的方法,我们在程序中哪里需要就在哪里获取即可

三、spring的Bean管理

        bean对象:由于把对象统一交给spring管理后,spring会对对象进行功能的增强,所以在spring框架中生成的对象,统一称为bean对象,用去区分是自己new的还是框架生成的。

        spring的bean管理有两种方式

1、基于xml配置方式

<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype"></bean>
使用bean标签配置需要让Spring管理的类
id="对象名称" 可以在getBean中获得到spring生成的对象
class="需要让spring管理的地址"
scope="配置bean对象的作用域"
    scope="singleton" 单例的  在spring启动时就会创建对象,且始终只创建一个对象
    scope="prototype" 原型的(多例的) 在每次获得对象时,都创建一个新的对象

IOC指的是让spring框架创建对象,创建对象的同时,还有一个动作称为依赖注入

依赖注入:在创建对象的时候,为对象赋值

依赖注入有两种方式 1、通过属性注入(set方法) 2、通过构造方法注入 

(1)通过属性注入

<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype">
    <!--调用的是类中的set方法-->
    <property name="account" value="admin"></property>
    <property name="password" value="111"></property>
</bean>

 需要注意的是,框架使用set get方法,需要我们在类中的成员变量和成员方法名称命名规范

(2)通过构造方法注入

<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype">
    <!--调用构造方法的依赖注入-->
    <constructor-arg name="account" value="admin"></constructor-arg>
    <constructor-arg name="password" value="111"></constructor-arg>
</bean> 

(3)例:在test中通过service调用dao的方法

将AdminDao当作属性添加在AdminService中,并提供set和get方法

package com.wbc.SpringPro.service;

import com.wbc.SpringPro.dao.AdminDao;
import com.wbc.SpringPro.model.Admin;

public class AdminService {
    AdminDao adminDao ;
    public void saveAdmin() {
        adminDao.saveAdmin();
    }

    public AdminDao getAdminDao() {
        return adminDao;
    }

    public void setAdminDao(AdminDao adminDao) {
        this.adminDao = adminDao;
    }
}

 AdminDao的定义

package com.wbc.SpringPro.dao;

import com.wbc.SpringPro.model.Admin;

public class AdminDao {
    public  void saveAdmin() {
        System.out.println("保存admin");
    }
}

通过bean标签配置在spring中

  • name属性指定要注入的属性名称。
  • ref属性指定要注入的bean的ID(在Spring上下文中已经定义的其他bean)。即,ref="adminDao"表示将名为adminDao的bean注入到当前bean的adminDao属性中。
<bean id="adminDao" class="com.wbc.SpringPro.dao.AdminDao"></bean>

<bean id="adminService" class="com.wbc.SpringPro.service.AdminService">
    <!--name是adminService的属性名 ref表示要注入的上下文中存在的bean的id-->
    <property name="adminDao" ref="adminDao"></property>
</bean>

 通过adminService调用

package com.wbc.SpringPro.test;

import com.wbc.SpringPro.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
        AdminService adminService = (AdminService) applicationContext.getBean("adminService", AdminService.class);
        adminService.saveAdmin();
    }
}

2、使用注解进行配置

(1)开启注册扫描

<context:component-scan base-package="包名"> </context:component-scan>

 (2)通过注解配置

@Component(value = "admin")
@Scope(value = "prototype")
/*等同于在配置文件中添加<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype"></bean>*/

@Componen 通用类

@Service       service层

@Repository  dao层

以上注解都可以实现创建对象功能,只是为了后续扩展功能,在不同的层使用不 同的注解标记

@Scope(value=“prototype”) 原型

@Scope(value=“ singleton ”) 单例  

package com.wbc.SpringPro.service;

import com.wbc.SpringPro.dao.AdminDao;
import com.wbc.SpringPro.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service(value = "adminService")

public class AdminService {

    @Autowired//自动注入
    AdminDao adminDao ;
    public void saveAdmin() {
        adminDao.saveAdmin();
    }

    public AdminDao getAdminDao() {
        return adminDao;
    }

    public void setAdminDao(AdminDao adminDao) {
        this.adminDao = adminDao;
    }
}
package com.wbc.SpringPro.dao;

import com.wbc.SpringPro.model.Admin;
import org.springframework.stereotype.Repository;

@Repository(value = "adminDao")
public class AdminDao {
    public  void saveAdmin() {
        System.out.println("保存admin");
    }
}
package com.wbc.SpringPro.test;

import com.wbc.SpringPro.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
        AdminService adminService = (AdminService) applicationContext.getBean("adminService", AdminService.class);
        adminService.saveAdmin();
    }
}

(3)自动注入

在属性上方通过注释的方式自动依赖注入

        自动注入有两种值的匹配方式:
            1、通过属性的类型进行查找
                @Autowired(String提供):
                        用于在属性和属性的set方法上,如果写在属性上,set方法可以不需要
                        Autowired注解默认情况下要注入的值不能为空(required=true)
                @Resource(jdk提供):
                        注入的值也不能为空,既可以通过属性的类型查找,又可以通过对象名查找
            2、通过对象的名字进行查找
                @Qualifier(value = "对象的名字")String提供
                @Resource(name = "adminDao")jdk提供

3、注解配置于xml配置的优缺点

注解优点: 方便,直观,高效(代码少,没有配置文件的书写那么复杂)。

注解缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。

xml 优点:配置和代码是分离的,在 xml 中做修改,无需编译代码,只需重启服务器即可将新的                       配置加载。

xml缺点:编写麻烦,效率低,大型项目过于复杂。 

三、Spring 数据访问层管理

1、Spring管理JDBC

(1)添加依赖项

<!-- spring-jdbc-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.16</version>
</dependency>

<!--阿里数据源 数据库链接管理组件-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

(2) 在spring配置文件中,通过bean标签添加对象的配置,使spring来管理对象

<!--
    阿里巴巴数据库链接管理对象,负责生成数据库链接对象,以及提供了数据库链接池功能
    让spring管理数据库链接对象 相比myBatis的数据连接池,druid的功能更加灵活
-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmd?serverTimezone=Asia/Shanghai"></property>
    <property name="username" value="root"></property>
    <property name="password" value="Wbc11280"></property>
    <property name="initialSize" value="10"></property><!--初始化连接数量-->
    <property name="maxActive" value="20"></property><!--最大连接数量-->
</bean>

<!--
    配置spring中对jdbc进行封装的操作类 jdbcTemplate
    在jdbcTemplace中注入druiDataSourse属性
-->
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
    <property name="dataSource" ref="druidDataSource"></property>
</bean>

(3)在dao层方法内执行sql

package com.wbc.SpringPro.dao;

import com.wbc.SpringPro.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

@Repository(value = "adminDao")
public class AdminDao {

    @Autowired
    JdbcTemplate jdbcTemplate;
    public  void saveAdmin() {
        /*System.out.println("保存admin");*/
        jdbcTemplate.execute("create table ..."); //主要执行创建表的ddl语句,没有返回值 
        jdbcTemplate.update("insert into admin(account,password,gender) values(?,?,?)","张三","111","男");
        List<Admin> adminList=jdbcTemplate.query("select * from admin", new RowMapper<Admin>(){
            @Override
            public Admin mapRow(ResultSet resultSet, int i) throws SQLException {
                Admin admin=new Admin();
                admin.setAccount(resultSet.getString("account"));
                admin.setPassword(resultSet.getString("password"));
                return admin;
            }
        });
        System.out.println(adminList);
    }
}

执行成功

2、spring整合Mybaits

(1)为什么myBatis要整合阿里巴巴Druid连接池 

  1. 性能优化:Druid是一个高性能的JDBC连接池,能够提供良好的性能表现,通过连接池技术可以有效地重用数据库连接,从而减少连接的创建和销毁开销。

  2. 监控和统计:Druid提供了丰富的监控和统计功能,能够实时监控数据库连接的使用情况、SQL执行情况等,有助于开发者快速发现并解决性能瓶颈和问题。

  3. 灵活配置:Druid支持多种配置选项,可以根据应用的需求进行灵活配置,如设置最小和最大连接数、连接超时时间等,以适应不同的使用场景。

  4. 安全性:Druid提供了SQL监控和防止SQL注入等安全特性,可以更好地保护数据库的安全。

  5. 易于集成:MyBatis已经提供了与Druid的良好集成支持,开发者可以方便地配置和使用Druid作为数据源,无需过多的修改。

(2)spring整合myBatis和Druid 

Spring集成Mybatis其核心是将SqlSessionFactory交由Spring管理,并由 Spring管理对dao接口的代理实现。

我们从新创建一个JavaEE项目

jdk选择java8并添加web依赖

 

1)导入jar包
<?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.wbc.ssm</groupId>
    <artifactId>ssm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>ssm</name>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.9.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>8.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- spring-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

        <!-- spring-jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <!--阿里数据源 数据库链接管理组件-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!--mybatis-spring-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.2</version>
        </dependency>



        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>provided</scope>
        </dependency>



    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>
</project>

 (2)搭建myBatis全局配置文件

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">


<configuration>
    <!--myBatis全局配置文件-->
    <!--    配置日志-->
    <settings>
        <!--        开启工作日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--        将数据库中的下划线连接名称在java中自动转为驼峰体-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--在SqlMapperConfig.xml 中启用二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <!--    为类配置别名-->
    <typeAliases>
        <!--        为java中的类起别名-->
        <package name="com.wbc.ssm.model"/>
    </typeAliases>
    <!--    配置数据库连接关键信息配置到spring.xml中-->
    <!--mapper映射也配置到spring.xml-->


</configuration>

(3)搭建spring全局配置文件

<?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"
       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">
    <!--开启spring注解的扫描功能 指定扫描包-->
    <context:component-scan base-package="com.wbc.ssm"> </context:component-scan>
    <!--
        阿里巴巴数据库链接管理对象,负责生成数据库链接对象,以及提供了数据库链接池功能
        让spring管理数据库链接对象 相比myBatis的数据连接池,druid的功能更加灵活
    -->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmd?serverTimezone=Asia/Shanghai"></property>
        <property name="username" value="root"></property>
        <property name="password" value="Wbc11280"></property>
        <property name="initialSize" value="10"></property><!--初始化连接数量-->
        <property name="maxActive" value="20"></property><!--最大连接数量-->
    </bean>

    <!--spring 管理sqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="druidDataSource"></property><!--将druid配置进dataSource-->
        <property name="configLocation"
                  value="classpath:mybatis.xml"></property><!--配置myBatis配置文件-->
        <!--扫描Mapper映射文件-->
        <!--Mapper/*Mapper.xml表示Mapper包下的所有映射-->
        <property name="mapperLocations" value="classpath:Mapper/*Mapper.xml">
        </property>
    </bean>

    <!--生成dao层接口下的所有代理对象-->
    <!--因此在dao层接口写不需要通过@Repository配置-->
    <bean id="mapperFactory"
          class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wbc.ssm.dao"></property><!--指定包名-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">
        </property>
    </bean>
</beans>
由于通过spring 管理sqlSessionFactory对象所以不需要再手动获取sqlSessionFactory对象

 

(4)创建model类
package com.wbc.ssm.model;

import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component
public class Admin implements Serializable {
    private int id;
    private String account;
    private String password;

    //lombok组件 在编译期间动态生成get、set方法


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Admin{" +
                "id=" + id +
                ", account='" + account + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
(5)创建dao层
package com.wbc.ssm.dao;

import com.wbc.ssm.model.Admin;

public interface LoginDao {

    Admin login(Admin admin);
}
(6)创建dao层的映射文件
<?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">

<!--namespace需要和接口路径对应-->
<mapper namespace="com.wbc.ssm.dao.LoginDao">
        <!--cache标签设置mapper开启二级缓存 flushInterval可以设置销毁时间,毫秒为单位 cache可以设置其他属性,包括是否只读,销毁策略等-->
     <cache></cache><!--开启缓存需要返回的model类实现序列化接口Serializable-->

    <select id="login" resultType="Admin">
        select id,account,password from admin where id = #{id}
    </select>
</mapper>
(7)创建service类调用dao层
package com.wbc.ssm.service;

import com.wbc.ssm.dao.LoginDao;
import com.wbc.ssm.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class LoginService {
    @Autowired
    LoginDao loginDao;
    public Admin login(Admin admin) {
        Admin admin1 = loginDao.login(admin);
        return admin1;
    }
}
(8)测试Test
package com.wbc.ssm.test;

import com.wbc.ssm.model.Admin;
import com.wbc.ssm.service.LoginService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        //调用xml配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        //获取service对象
        LoginService loginService = applicationContext.getBean("loginService", LoginService.class);
        //模拟web前端传入的数据
        Admin admin = new Admin();
        admin.setId(1);
        //调用方法查询
        Admin admin1 = loginService.login(admin);
        System.out.println(admin1);
    }
}

输出


http://www.kler.cn/a/282616.html

相关文章:

  • C++ | Leetcode C++题解之第560题和为K的子数组
  • 二五、pxe自动装机
  • Gitcode文件历史记录查看和还原
  • More effective C++:杂项
  • 基于Spring Boot的电子商务系统设计
  • c++入门--引用与指针,const与引用,NULL与nullptr
  • 向量数据库Faiss的搭建与使用|Faiss|向量数据库|高效检索|机器学习|大规模数据
  • 大模型Prompt提示设计简介(2):有效的建议
  • 在C语言中使用POSIX线程库(pthread)实现多线程编程
  • Redis多线程特性
  • CSS中禁用DOM事件
  • OpenCV绘图函数(12)绘制直线函数 line()的使用
  • 数学基础 -- 线性代数之向量基本概念
  • Flask+LayUI开发手记(五):树型表格实现数据展示与编辑
  • 开源 AI 智能名片 O2O 商城小程序在社交私域中的圈层价值
  • 数据库:笔记03SQL
  • geodatatool(地图资源工具)下载高德数据及数据共享
  • 设计模式之工厂模式和策略模式的区别
  • MFC工控项目实例之八选择下拉菜单添加打钩图标
  • 提高 Web 应用程序安全性的标准
  • Scrapy添加代理IP池:自动化爬虫的秘密武器
  • 大数据技术之Flume 参数调优(12)
  • selenium滚动到页面底部
  • 企业数据治理之主数据---供应商主数据
  • 关于测试工程师在性能测试工具jmeter的熟悉和精通
  • echarts 柱状图_堆叠柱状图_数据分区_常用图表配置_数据可视化