当前位置:   article > 正文

Springboot笔记(6):Springboot数据访问/雷神_springboot3 语雀 雷神

springboot3 语雀 雷神

目录

0、写在前面

1、SQL

1.1、数据源的自动配置-HikariDataSource

1.1.1、导入JDBC场景

1.1.2、分析自动配置

1.1.3、修改配置项

1.1.4、测试

总结:

2、使用Druid数据源

2.1、druid官方github地址

2.2、自定义方式

2.3、使用官方starter方式

3、整合MyBatis操作

3.1、第三方的依赖: *-spring-boot-starter

3.2、配置模式

3.3、mybatis配置模式步骤

3.4、mybatis注解模式

3.5、混合模式

3.6、最佳实战:

4、整合 MyBatis-Plus 完成CRUD

4.1、什么是MyBatis-Plus

4.2、整合MyBatis-Plus

4.3、CRUD功能


0、写在前面

笔记:06、数据访问 · 语雀

1、SQL

正常数据访问按照

  • 添加场景:spring-boot-starter-data-xxx
  • 场景会添加自动配置:xxxautoConfiguration
  • 添加组件数据库连接池:dataSource
  • 数据库驱动
  • 数据库连接信息:properties配置项

第一步:导入数据库相关场景

第二步:配置数据库连接信息的配置项

1.1、数据源的自动配置-HikariDataSource

1.1.1、导入JDBC场景

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-jdbc</artifactId>
  4. </dependency>

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-jdbc</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-jdbc</artifactId>
  8. <version>2.3.2.RELEASE</version>
  9. <scope>compile</scope>
  10. </dependency>
  11. 数据库连接池
  12. <dependency>
  13. <groupId>com.zaxxer</groupId>
  14. <artifactId>HikariCP</artifactId>
  15. <version>3.4.5</version>
  16. <scope>compile</scope>
  17. </dependency>

数据库驱动?

    为什么导入JDBC场景,官方不导入驱动?mysql-connector-java

因为官方不知道我们接下要操作什么数据库,不同的数据库对应的数据库驱动不同。

数据库版本和驱动版本对应

我的数据库版本:5.7.20

版本仲裁:mysql官方做了版本仲裁,驱动默认版本8.0.21

 故需要将数据库版本5.7.20和驱动版本5.1.49 对应:

  1. <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. <version>5.1.49</version>
  5. </dependency>

修改mysql驱动版本方法:

  1. 1、直接依赖引入具体版本(maven的就近依赖原则)
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. <version>5.1.49</version>
  6. </dependency>
  7. 2、重新声明版本(maven的属性的就近优先原则)
  8. <dependency>
  9. <groupId>mysql</groupId>
  10. <artifactId>mysql-connector-java</artifactId>
  11. </dependency>
  12. <properties>
  13. <java.version>1.8</java.version>
  14. <mysql.version>5.1.49</mysql.version>
  15. </properties>

1.1.2、分析自动配置

自动配置的类

  • 1、DataSourceAutoConfiguration :数据源的自动配置
    • 修改数据源相关的配置:spring.datasource写到配置文件application.yml即可。
    • 数据库连接池的配置,是自己容器中没有DataSource才自动配置的。
    • 底层配置好的连接池是:HikariDataSource 数据源。
  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
  3. @ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
  4. @EnableConfigurationProperties(DataSourceProperties.class)
  5. @Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
  6. public class DataSourceAutoConfiguration {
  7. @Configuration(proxyBeanMethods = false)
  8. @Conditional(PooledDataSourceCondition.class)
  9. @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
  10. @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
  11. DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
  12. DataSourceJmxConfiguration.class })
  13. protected static class PooledDataSourceConfiguration {
  14. }

分析:

  • @ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory"):表示如果通过响应式编程的话就不使用DataSourceAutoConfiguration,如果不使用响应式编程就使用DataSourceAutoConfiguration配置。
  • @EnableConfigurationProperties(DataSourceProperties.class):表示开启事件绑定功能,在DataSourceProperties里绑定spring.datasource
  • @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }):表示如果自己没有中没有数据源,系统会自动配置。

DataSourceProperties:spring.datasource 表示修改数据源的话,只需要在这里修改即可

  1. 源码:
  2. @ConfigurationProperties(prefix = "spring.datasource")
  3. public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
  4. private String driverClassName;
  5. private String url;
  6. private String username;
  7. private String password;
  8. private String jndiName;
  9. }
  • 2、DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置
  • 3、JdbcTemplateAutoConfiguration:JdbcTemplate的自动配置可以来对数据库进行crud
    • 可以修改配置项@ConfigurationProperties(prefix = "spring.jdbc") 来修改JdbcTemplate
    • @Bean、@Primary JdbcTemplate;容器中有这个组件
  • 4、JndiDataSourceAutoConfiguration jndi的自动配置
  • 5、XADataSourceAutoConfiguration分布式事务相关的

默认是Hikari数据源:

    也可以通过spring.datasource.type  = com.zaxxer.hikari.HikariDataSource来手动开启数据源为Hikari

  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnClass(HikariDataSource.class)
  3. @ConditionalOnMissingBean(DataSource.class)
  4. @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
  5. matchIfMissing = true)
  6. static class Hikari {
  7. @Bean
  8. @ConfigurationProperties(prefix = "spring.datasource.hikari")
  9. HikariDataSource dataSource(DataSourceProperties properties) {
  10. HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
  11. if (StringUtils.hasText(properties.getName())) {
  12. dataSource.setPoolName(properties.getName());
  13. }
  14. return dataSource;
  15. }
  16. }

1.1.3、修改配置项

  1. spring:
  2. datasource:
  3. url: jdbc:mysql://localhost:3306/db_account
  4. username: root
  5. password: 123456
  6. driver-class-name: com.mysql.jdbc.Driver
  7. jdbc:
  8. template:
  9. query-timeout: 3 #3s超时
  10. # main:
  11. # allow-bean-definition-overriding: true
  12. # type: com.zaxxer.hikari.HikariDataSource

1.1.4、测试

  1. @Slf4j
  2. @SpringBootTest
  3. class Boot05WebAdminApplicationTests {
  4. @Autowired
  5. JdbcTemplate jdbcTemplate;
  6. @Test
  7. void contextLoads() {
  8. // jdbcTemplate.queryForObject("select * from account_tbl")
  9. // jdbcTemplate.queryForList("select * from account_tbl",)
  10. Long aLong = jdbcTemplate.queryForObject("select count(*) from account_tbl", Long.class);
  11. log.info("记录总数:{}",aLong);
  12. }
  13. }

总结:

连接数据库时只需要在pom添加场景(默认添加了Hikari数据源),然后在配置文件些连接信息即可。当然也可以添加其他数据源。

2、使用Druid数据源

2.1、druid官方github地址

https://github.com/alibaba/druid

整合第三方技术的两种方式

  • 自定义
  • 找starter

2.2、自定义方式

1、创建数据源(加依赖+加配置bean)

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>druid</artifactId>
  4. <version>1.1.17</version>
  5. </dependency>
  6. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
  7. destroy-method="close">
  8. <property name="url" value="${jdbc.url}" />
  9. <property name="username" value="${jdbc.username}" />
  10. <property name="password" value="${jdbc.password}" />
  11. <property name="maxActive" value="20" />
  12. <property name="initialSize" value="1" />
  13. <property name="maxWait" value="60000" />
  14. <property name="minIdle" value="1" />
  15. <property name="timeBetweenEvictionRunsMillis" value="60000" />
  16. <property name="minEvictableIdleTimeMillis" value="300000" />
  17. <property name="testWhileIdle" value="true" />
  18. <property name="testOnBorrow" value="false" />
  19. <property name="testOnReturn" value="false" />
  20. <property name="poolPreparedStatements" value="true" />
  21. <property name="maxOpenPreparedStatements" value="20" />
  22. </bean>

2、使用配置类代替配置bean

  • @ConfigurationProperties("spring.datasource"):将配置文件中的属性绑定到对象中
  1. @Configuration
  2. public class MyDataSourceConfig {
  3. //默认的自动配置是判断容器中没有才会配
  4. //@ConditionOnMissingBean(DataSource.class)
  5. @Bean
  6. @ConfigurationProperties("spring.datasource")//读取application.yml中的内容
  7. public DataSource dataSource(){
  8. DruidDataSource druidDataSource = new DruidDataSource();
  9. return druidDataSource;
  10. }
  11. }
  12. spring:
  13. datasource:
  14. url: jdbc:mysql://localhost:3306/mybatis
  15. username: root
  16. password: 123456
  17. driver-class-name: com.mysql.jdbc.Driver
  18. jdbc:
  19. template:
  20. query-timeout: 3

3、测试

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class SpringBootLoggingApplicationTests {
  4. @Autowired
  5. DataSource dataSource;
  6. @Autowired
  7. JdbcTemplate jdbcTemplate;
  8. @Test
  9. public void context(){
  10. Long aLong = jdbcTemplate.queryForObject("select count(*) from user", Long.class);
  11. LOGGER.info("记录总数:{}",aLong);
  12. //2021-12-08 00:09:11.984 INFO 30552 --- [ main] c.c.s.SpringBootLoggingApplicationTests : 记录总数:8
  13. LOGGER.info("数据源类型:{}",dataSource.getClass());
  14. //2021-12-08 00:20:13.188 INFO 31026 --- [ main] c.c.s.SpringBootLoggingApplicationTests : 数据源类型:class com.zaxxer.hikari.HikariDataSource$$EnhancerBySpringCGLIB$$ef95382c
  15. //2021-12-08 00:32:50.702 INFO 31548 --- [ main] c.c.s.SpringBootLoggingApplicationTests : 数据源类型:class com.alibaba.druid.pool.DruidDataSource
  16. }
  17. }

2.3、使用官方starter方式

1、引入druid-starter

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>druid-spring-boot-starter</artifactId>
  4. <version>1.1.17</version>
  5. </dependency>

2、分析自动配置

  • 扩展配置项 spring.datasource.druid
  • DruidSpringAopConfiguration.class, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
  • DruidStatViewServletConfiguration.class, 监控页的配置:spring.datasource.druid.stat-view-servlet;默认开启
  • DruidWebStatFilterConfiguration.class, web监控配置;spring.datasource.druid.web-stat-filter;默认开启
  • DruidFilterConfiguration.class}) 所有Druid自己filter的配置
  1. private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";
  2. private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";
  3. private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";
  4. private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";
  5. private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";
  6. private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";
  7. private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";
  8. private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";

3、配置示例

  1. spring:
  2. datasource:
  3. url: jdbc:mysql://localhost:3306/db_account
  4. username: root
  5. password: 123456
  6. driver-class-name: com.mysql.jdbc.Driver
  7. druid:
  8. aop-patterns: com.atguigu.admin.* #监控SpringBean
  9. filters: stat,wall # 底层开启功能,stat(sql监控),wall(防火墙)
  10. stat-view-servlet: # 配置监控页功能
  11. enabled: true
  12. login-username: admin
  13. login-password: admin
  14. resetEnable: false
  15. web-stat-filter: # 监控web
  16. enabled: true
  17. urlPattern: /*
  18. exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
  19. filter:
  20. stat: # 对上面filters里面的stat的详细配置
  21. slow-sql-millis: 1000
  22. logSlowSql: true
  23. enabled: true
  24. wall:
  25. enabled: true
  26. config:
  27. drop-table-allow: false

3、整合MyBatis操作

MyBatis · GitHub

SpringBoot官方的Starter:spring-boot-starter-*

3.1、第三方的依赖: *-spring-boot-starter

  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>2.1.4</version>
  5. </dependency>

image.png

3.2、配置模式

  • 全局配置文件
  • SqlSessionFactory: 自动配置好了
  1. public interface SqlSessionFactory {
  2. SqlSession openSession();
  3. }
  • SqlSession:自动配置了 SqlSessionTemplate 组合了SqlSession(crud)
  1. public class SqlSessionTemplate implements SqlSession, DisposableBean {
  2. private final SqlSessionFactory sqlSessionFactory;
  3. private final SqlSession sqlSessionProxy;
  4. }
  5. public interface SqlSession extends Closeable {
  6. <T> T selectOne(String var1);
  7. }
  • @Import(AutoConfiguredMapperScannerRegistrar.class
  • Mapper: 只要我们写的操作MyBatis的接口标注了 @Mapper 就会被自动扫描进来
  1. @Configuration
  2. @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
  3. @ConditionalOnSingleCandidate(DataSource.class)
  4. @EnableConfigurationProperties({MybatisProperties.class}): MyBatis配置项绑定类
  5. @AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
  6. public class MybatisAutoConfiguration implements InitializingBean {
  7. @Bean
  8. @ConditionalOnMissingBean
  9. public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
  10. }
  11. public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
  12. }
  13. }
  14. @ConfigurationProperties(prefix = "mybatis"):配置文件以mybatis开头
  15. public class MybatisProperties{
  16. }

mybatis的全局配置文件

SQL映射文件

插件:mybatisX能够直接指向sql映射文件

3.3、mybatis配置模式步骤

  • 导入mybatis官方starter
  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>2.1.4</version>
  5. </dependency>
  • 编写mapper接口。标准@Mapper注解
  1. @Mapper
  2. public interface UserMapper {
  3. public User getUser(Long id);
  4. }
  • 编写sql映射文件并绑定mapper接口:MybatisMapper.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <!--mapper为根元素,namespace指定了命名空间-->
  5. <mapper namespace="com.crane.springboot.mapper.UserMapper">
  6. <!--验证用户登录-->
  7. <select id="getUser" resultType="com.crane.springboot.domain.User">
  8. SELECT * FROM user WHERE id=#{id}
  9. </select>
  10. </mapper>
  • 全局配置文件 mybatis-config.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 开启驼峰命名 :数据库字段名user_id 和对象属性对象 userId-->
  7. <settings>
  8. <setting name="mapUnderscoreToCamelCase" value="true"/>
  9. </settings>
  10. </configuration>
  • 在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息 (建议 配置在mybatis.configuration)

application.yml

  1. spring:
  2. datasource:
  3. url: jdbc:mysql://localhost:3306/mybatis
  4. username: root
  5. password: 123456
  6. driver-class-name: com.mysql.jdbc.Driver
  7. jdbc:
  8. template:
  9. query-timeout: 3
  10. # main:
  11. # allow-bean-definition-overriding: true
  12. # type: com.zaxxer.hikari.HikariDataSource
  13. # 配置mybatis规则
  14. mybatis:
  15. # config-location: classpath:mybatis/mybatis-config.xml
  16. mapper-locations: classpath:mybatis/mapper/*.xml
  17. configuration:
  18. map-underscore-to-camel-case: true
  • controller/service/domain
  1. @Controller
  2. @Slf4j
  3. public class UserController {
  4. @Autowired
  5. private UserService userService;
  6. //http://localhost:8080/user?id=1
  7. //{"id":1,"name":"xiao","pwd":123}
  8. @ResponseBody
  9. @GetMapping("/user")
  10. public User getUserById(@RequestParam("id") Long id){
  11. return userService.gerUserById(id);
  12. }
  13. }
  14. @Service
  15. public class UserService {
  16. @Autowired
  17. UserMapper userMapper;
  18. public User gerUserById(Long id){
  19. return userMapper.getUser(id);
  20. }
  21. }
  22. @Data
  23. public class User {
  24. private Long id;
  25. private String name;
  26. private Integer pwd;
  27. }

注意:

      可以删除全局配置文件mybatis-config.xml。将全局配置文件中的内容放到 application.yml中配置即可:配置 private Configuration configuration;

mybatis.configuration下面的所有,就是相当于改mybatis全局配置文件中的值:

  1. # 配置mybatis规则
  2. mybatis:
  3. mapper-locations: classpath:mybatis/mapper/*.xml
  4. configuration:
  5. map-underscore-to-camel-case: true
  6. 可以不写全局;配置文件,所有全局配置文件的配置都放在configuration配置项中即可

3.4、mybatis注解模式

  1. @Mapper
  2. public interface UserMapper {
  3. @Select("select * from city where id=#{id}")
  4. public User getById(Long id);
  5. public void insert(User user);
  6. }

3.5、混合模式

  1. @Mapper
  2. public interface UserMapper {
  3. @Select("SELECT * FROM user WHERE id=#{id}")
  4. public User getUser(Long id);
  5. public void insert(User user);
  6. }
  7. <?xml version="1.0" encoding="UTF-8" ?>
  8. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  9. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  10. <!--mapper为根元素,namespace指定了命名空间-->
  11. <mapper namespace="com.crane.springboot.mapper.UserMapper">
  12. <insert id="insert">
  13. insert into user(`name`,`pwd`) values (#{name},#{pwd})
  14. </insert>
  15. </mapper>

controller

  1. @Controller
  2. @Slf4j
  3. public class UserController {
  4. @Autowired
  5. private UserService userService;
  6. @ResponseBody
  7. @PostMapping("/save/user")
  8. public User saveUser(User user){
  9. userService.saveUser(user);
  10. return user;
  11. }
  12. }

postman模拟表单提交post

返回自增的id值

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.crane.springboot.mapper.UserMapper">
  5. <insert id="insert" useGeneratedKeys="true" keyProperty="id">
  6. insert into user(`name`,`pwd`) values (#{name},#{pwd})
  7. </insert>
  8. </mapper>

insert可以改成注解形式

  1. @Mapper
  2. public interface UserMapper {
  3. @Select("SELECT * FROM user WHERE id=#{id}")
  4. public User getUser(Long id);
  5. @Insert("insert into user(`name`,`pwd`) values (#{name},#{pwd})")
  6. @Options(useGeneratedKeys = true, keyProperty = "id")
  7. public void insert(User user);
  8. }

3.6、最佳实战:

  • 引入mybatis-starter
  • 配置application.yaml中,指定mapper-location位置即可
  • 编写Mapper接口并标注@Mapper注解
  • 简单方法直接注解方式
  • 复杂方法编写mapper.xml进行绑定映射

@MapperScan("com.admin.mapper") 简化:

可以在启动类上添加@MapperScan(“...”), 其他的接口就可以不用标注@Mapper注解

  1. @SpringBootApplication
  2. @MapperScan("com.crane.springboot")
  3. @Slf4j
  4. public class HelloWorldMainApplication {
  5. public static void main(String[] args) {
  6. //该类必须是@SpringBootApplication标注的类
  7. ConfigurableApplicationContext applicationContext = SpringApplication.run(HelloWorldMainApplication.class);
  8. System.out.println("正常启动");
  9. log.info("系统正常启动");
  10. }
  11. }

4、整合 MyBatis-Plus 完成CRUD

4.1、什么是MyBatis-Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

mybatis plus 官网

建议安装 MybatisX 插件

4.2、整合MyBatis-Plus

  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>mybatis-plus-boot-starter</artifactId>
  4. <version>3.4.1</version>
  5. </dependency>

自动配置

  • MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。mybatis-plus:xxx 就是对mybatis-plus的定制
  • SqlSessionFactory 自动配置好。底层是容器中默认的数据源
  • mapperLocations 自动配置好的。有默认值。
    • classpath*:/mapper/**/*.xml;任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件建议以后sql映射文件,放在 mapper下。该路径是mybatis约定好的。
  • 容器中也自动配置好了 SqlSessionTemplate
  • @Mapper 标注的接口也会被自动扫描;建议直接
  • @MapperScan("com.atguigu.admin.mapper") 批量扫描就行

优点:

  • 只需要我们的Mapper继承 BaseMapper 就可以拥有crud能力

4.3、CRUD功能

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/120999
推荐阅读
相关标签
  

闽ICP备14008679号