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

企业网上书店网站建设设计宁波seo企业网络推广

企业网上书店网站建设设计,宁波seo企业网络推广,网站要怎么做的吗,南昌哪里有网站建设一、JDBC复习 作业:在 MySQL 中,创建以下数据表,使用 JDBC 连接 MySQL 数据库。同时,实现数据表的增、删、改、查(根据ID查询、分页查询)操作。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19drop data…

一、JDBC复习

作业:在 MySQL 中,创建以下数据表,使用 JDBC 连接 MySQL 数据库。同时,实现数据表的增、删、改、查(根据ID查询、分页查询)操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
drop database if exists jdbc_test;
create database if not exists jdbc_test ;
use jdbc_test;
create table `staffs`(`id` int(10) primary key auto_increment,`name` varchar(24) not null comment '姓名',`age` int(10) default 18 comment '年龄',`phone` char(11) comment '联系方式',`sta_pos` varchar(20) comment '职位',`add_time` datetime default current_timestamp comment '入职时间',`update_time` datetime default current_timestamp comment '更新时间'
) engine=innodb charset=utf8 comment '员工记录表';
# 提示:需要自行下载连接MySQL的驱动程序insert into staffs(name,age,phone,sta_pos) values ('张三',18,'13417747371','工程师');
insert into staffs(name,age,phone,sta_pos) values ('李四',19,'13417747372','工程师');
insert into staffs(name,age,phone,sta_pos) values ('王五',20,'13417747373','教授');select * from staffs;

1、概念

JDBC(Java DataBase Connectity)是Java数据库连接技术的简称,提供连接各种常用数据库的能力;

它提供了操作数据库的接口(规范、标准)。JDBC实现由各数据库厂商提供(驱动程序);

所在包:java.sql

作用:用于连接 + 操作数据库

2、JDBC原理

image-20200428232538430

DriverManager

提供者:sun公司

作用:载入各种不同的JDBC驱动

JDBC 驱动

提供者:数据库厂商

作用:负责连接各种不同的数据库

JDBC<躯壳> VS 驱动程序<灵魂>

3、JDBC的常用对象(API)

image-20200428232538430

1)DriverManager

驱动管理器,管理驱动程序 – 载入各种不同的JDBC驱动程序

2)Connection

连接对象,实现数据库的连接并担任传送数据的任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package org.zing.util;import java.sql.*;/*** 使用 JDBC 连接 MySQL 数据库** @Author zqx* @Date 2023-03-05*/
public class DbUtil {/*** 连接驱动程序*/private static final String DRIVER = "com.mysql.cj.jdbc.Driver";/*** 连接URL*/private static final String URL = "jdbc:mysql://127.0.0.1:3306/jdbc_test?useUnicode=true;characterEncoding=utf8;serverTimezone=Asia/Shanghai";/*** 帐号*/private static final String USER = "root";/*** 密码*/private static final String PASS = "root";static {/** 加载驱动程序*/try {Class.forName(DRIVER);} catch (ClassNotFoundException e) {System.out.println("加载驱动程序失败...");e.printStackTrace();}}/*** 获取连接对象 -- Java程序 与 数据库之间的桥梁** @return*/public static Connection getConnection() {Connection conn = null;try {conn = DriverManager.getConnection(URL, USER, PASS);} catch (SQLException e) {System.out.println("获取连接对象失败...");e.printStackTrace();}return conn;}/*** 关闭相关的 JDBC 对象* <p>* DriverManager:驱动管理对象,获取连接对象* <p>* DriverManager.getConnection(URL, USER, PASS);* <p>* ResultSet:结果集对象 用于接收查询数据时,返回的结果* <p>* Statement:语句对象 用于执行SQL语句(PreparedStatement、CallableStatement)* 增、删、改:executeUpdate() 查询:executeQuery()* <p>* <p>* Connection:连接对象 建立JAVA程序与数据库之间的桥梁** @param rst* @param stmt 父类对象可以接收子类对象 - 多态* @param conn*/public static void close(ResultSet rst, Statement stmt, Connection conn) {if (rst != null) {try {rst.close();} catch (SQLException e) {e.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}public static void main(String[] args) {System.out.println(DbUtil.getConnection());}
}
3)Statement

语句对象,由 Connection 产生、负责执行 SQL 语句

3.1)Statement
1
Statement stmt = conn.createStatement() ;
3.2)PreparedStatement

效率高、安全性高、方便

1
2
3
4
5
6
7
8
9
10
//定义操作数据库的SQL语句->数据由?来占位
String sql = "select * from student where id=?";//预编译SQL语句
PreparedStatement pstmt = conn.prepareStatement(sql);//填充数据,语法如下:
// 语句对象.setXxx(占位符索引,数据) -> 从1开始
// Xxx:指是数据类型->Java的数据类型
pstmt.setInt(1, 5);
3.3)CallableStatement

用于执行存储过程

4、ResultSet

结果集对象,负责保存语句对象执行后所产生的查询结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ResultSet rst = stmt.executeQuery(sql) ;
//ResultSet rst = pstmt.executeQuery();//1.循环迭代各行记录
while(rst.next()) {		//2.获取每行中,各字段的数据,语法如下://方法一:结果集对象.getXxx(字段索引) -> 从1开始,且是根据select后的字段来获取//方法二:结果集对象.getXxx(字段名称) //注:Xxx指的是字段的数据类型 -> 必须对应Java的数据类型String stuNO = rst.getString(1) ;String cardID = rst.getString(3) ;//int id = rst.getInt("id") ;//String name = rst.getString("name") ;System.out.println(stuNO+"\t"+cardID);
}

5、ResultSetMetaData

元数据对象,可用于获取有关ResultSet对象中列的类型和属性的信息的对象。

1
2
3
4
5
6
// 1.实例化对象:结果集对象.getMetaData() ;
ResultSetMetaData metaData = rst.getMetaData() ;// 2.常用方法
// 2.1 结果集中包含列的数量:int getColumnCount():  
// 2.2获取指定列的别名,索引从1开始:String getColumnLabel(int column)

二、DbUtils

commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate、MyBatis框架的首选。

commons-dbutils API:

  • org.apache.commons.dbutils.QueryRunner:提供对sql语句操作的API
  • org.apache.commons.dbutils.ResultSetHandler:用于定义select操作后,怎样封装结果集
  • org.apache.commons.dbutils.DbUtils:工具类,定义了关闭资源与事务处理的方法

三、QueryRunner

该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。

QueryRunner类提供了两个构造方法:

  • 默认的构造方法
  • 需要一个 javax.sql.DataSource 来作参数的构造方法

常用方法

  • public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
  • public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException: 几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource) 或使用的setDataSource 方法中重新获得 Connection。
  • public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException : 执行一个不需要置换参数的查询操作。
  • public int update(Connection conn, String sql, Object[] params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
  • public int update(Connection conn, String sql) throws SQLException:用来执行一个不需要置换参数的更新操作。

四、ResultSetHandler

1.作用

该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。

2.ResultSetHandler接口的实现类

  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
  • ScalarHandler:它是用于单数据。如果:select count(*) from 表操作。

五、数据库连接池

数据库连接池是一种技术,用于管理应用程序与数据库之间的连接。连接池可以有效地减少数据库连接的开销,提高应用程序的性能和可伸缩性。

六、开源的数据源使用

1、DBCP

2、C3P0

作者使用了自己喜欢的一个机器人的代号命名

1)使用方法一

第一、引入jar包:c3p0-0.9.5.jar以及依赖的mchange-commons-java-0.2.9.jar

第二、创建ComboPooledDataSource对象

1
private static ComboPooledDataSource cpds = new ComboPooledDataSource();

第三、设置必须的属性

1
2
3
4
cpds.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver");
cpds.setJdbcUrl("jdbc:sqlserver://localhost:1433;database=jdbc");
cpds.setUser("sa");
cpds.setPassword("123456");

第四、根据情况,设置可选的属性

第五、获取连接对象

1
Connection conn = ds.getConnection() ;

第六、关闭连接对象

1
ds.close() ;
2)使用方法二

第一、引入jar包:c3p0-0.9.5.jar以及依赖的mchange-commons-java-0.2.9.jar

第二、配置c3p0-config.xml或c3p0.properties文件(存放在构建路径)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config><!-- 默认配置 --><default-config><property name="driverClass">com.mysql.cj.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbc_test?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai</property><property name="user">root</property><property name="password">root</property><!-- 连接池初始化时创建的连接数 --><property name="initialPoolSize">10</property><!-- 连接池保持的最小连接数 --><property name="minPoolSize">10</property><!-- 连接池中拥有的最大连接数 --><property name="maxPoolSize">100</property><!-- 连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接 --><property name="maxIdleTime">30</property><!-- 连接池用完,等待时间,设置0无限等待 --><property name="checkoutTimeout">30000</property><!-- 测试空闲连接的间隔时间 --><property name="idleConnectionTestPeriod">30</property><!-- 连接池为数据源缓存的PreparedStatement的总数 --><property name="maxStatements">200</property></default-config><!-- 功能同上,配置另一种情况。需要指定一个名称加以区分:other --><named-config name="other"><property name="driverClass">com.mysql.cj.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai</property><property name="user">root</property><property name="password">root</property><!-- 连接池初始化时创建的连接数 --><property name="initialPoolSize">10</property><!-- 连接池保持的最小连接数 --><property name="minPoolSize">10</property><!-- 连接池中拥有的最大连接数 --><property name="maxPoolSize">100</property><!-- 连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接 --><property name="maxIdleTime">30</property><!-- 连接池用完,等待时间,设置0无限等待 --><property name="checkoutTimeout">30000</property><!-- 测试空闲连接的间隔时间 --><property name="idleConnectionTestPeriod">30</property><!-- 连接池为数据源缓存的PreparedStatement的总数 --><property name="maxStatements">200</property></named-config>
</c3p0-config>

第三、创建ComboPooledDataSource对象,并指定配置参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class C3P0Util {/*** 定义C3P0数据源对象 - 使用默认配置创建ComboPooledDataSource对象*/private static ComboPooledDataSource cpds = new ComboPooledDataSource();// 使用某配置创建ComboPooledDataSource对象// private static ComboPooledDataSource cpds = new ComboPooledDataSource("other");public static DataSource getDataSource() {return cpds;}public static Connection getConnection() {try {return cpds.getConnection();} catch (SQLException e) {throw new RuntimeException(e);}}
}

第四、获取连接对象

1
Connection conn = ds.getConnection() ;

第五、关闭连接对象

1
ds.close() ;

3、Druid

https://github.com/alibaba/druid?tab=readme-ov-file

Druid是什么

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

下载

https://mvnrepository.com/

1
2
3
4
5
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid-version}</version>
</dependency>
1)使用方法一

第一、引入jar包

第二、创建ComboPooledDataSource对象

1
private static DruidDataSource dataSource = new DruidDataSource();

第三、设置必须的属性

1
2
3
4
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai");
dataSource.setUsername("root");
dataSource.setPassword("root");

第四、根据情况,设置可选的属性

第五、获取连接对象

1
Connection conn = dataSource.getConnection() ;

第六、关闭连接对象

1
conn.close() ;

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package org.zing.util;import com.alibaba.druid.pool.DruidDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;/*** @author zqx* @date 2025-02-24*/
public class DruidHelper {/*** 数据源对象*/private static DruidDataSource dataSource;/*** 获取数据源对象*/public static DataSource getDataSource() {if (dataSource == null) {initDataSource();}return dataSource;}/*** 初始化数据源*/private static void initDataSource() {try {// 实例化数据源对象dataSource = new DruidDataSource();// 基础配置dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai");dataSource.setUsername("root");dataSource.setPassword("root");// 初始化连接数量dataSource.setInitialSize(10);// 最小连接数dataSource.setMinIdle(10);// 最大等待时间dataSource.setMaxWait(6000);// 最大连接数dataSource.setMaxActive(100);// 连接有效性检测SQLdataSource.setValidationQuery("SELECT 1");// 空闲时检测连接有效性dataSource.setTestWhileIdle(true);} catch (Exception e) {throw new RuntimeException("初始化Druid连接池失败", e);}}/*** 从连接池获取连接对象*/public static Connection getConnection() {try {return getDataSource().getConnection();} catch (SQLException e) {throw new RuntimeException("获取连接对象失败", e);}}/*** 关闭连接,回收到连接池** @param conn 连接对象*/public static void close(Connection conn) {if (conn != null) {try {conn.close();} catch (SQLException e) {System.err.println("关闭数据库连接时发生异常");}}}
}
2)使用方法二

第一、引入jar包

第二、创建配置文件 druid.properties 文件(存放在构建路径)

1
2
3
4
5
6
7
8
9
10
11
12
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username=root
password=root
# 初始化连接数量
initialSize=10
# 最小连接数
minIdle=10
# 最大连接数
maxActive=100
# 最大等待时间
maxWait=6000

第三、创建 DataSource 对象,并指定配置参数

1
2
3
Properties prop = new Properties();
prop.load(DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

第四、获取连接对象

1
Connection conn = dataSource.getConnection() ;

第五、关闭连接对象

1
conn.close() ;

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package org.zing.util;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;/*** @author zqx* @date 2025-02-24*/
public class DruidUtil {/*** 数据源对象*/private static DataSource dataSource;/*** 获取数据源对象** @return 数据源对象*/public static DataSource getDataSource() {if (dataSource == null) {initDataSource();}return dataSource;}/*** 初始化数据源对象*/private static void initDataSource() {Properties prop = new Properties();try {prop.load(DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties"));dataSource = DruidDataSourceFactory.createDataSource(prop);} catch (Exception e) {throw new RuntimeException(e);}}/*** 从连接池获取连接对象** @return 连接对象*/public static Connection getConnection() {try {return getDataSource().getConnection();} catch (SQLException e) {throw new RuntimeException("获取连接对象失败", e);}}/*** 关闭连接,回收到连接池** @param conn 连接对象*/public static void close(Connection conn) {if (conn != null) {try {conn.close();} catch (SQLException e) {System.err.println("关闭数据库连接时发生异常");}}}}

七、DbUtils 增、删、改、查操作

第一:通过C3P0/DBCP获取数据源对象

告知DbUtils操作哪个服务中,哪个端口号的哪个数据库 - 连接池

第二:创建QueryRunner对象

1
QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()) ;

第三:定义要操作的SQL语句

1
String sql = "select id,name,age,phone,pos,add_time as addTime from staffs" ;

注意:使用别名解决实体对象属性名和数据表字段名不一致的问题

内省

第四:定义SQL语句需要的具体数据

1
Object[] params = new Object[]{数据1,数据2,...} ;

第五:执行SQL语句 —— 反射、封装处理

  • 查询操作:query(…)
  • 更新操作:update(…)
1
2
List<Staff> list = qr.query(sql, new BeanListHandler<Staff>(Staff.class));
Staff staff = qr.query(sql,new BeanHandler<>(Staff.class),id);

八、日期时间问题

1、JDBC 类型映射机制

数据库中的时间类型(如 DATETIMETIMESTAMP)通过 JDBC 驱动转换为 Java 类型时,不同版本的驱动处理方式不同:

  • MySQL 5.x 驱动:默认将 DATETIME 映射为 java.sql.Timestamp(继承自 java.util.Date
  • MySQL 8.x 驱动:支持 JDBC 4.2+,可能直接映射为 java.time.LocalDateTime

当使用 MySQL 8.x 驱动时:

  • 数据库 DATETIME → JDBC 返回 LocalDateTime
  • BeanProcessor 尝试将 LocalDateTime 赋值给 java.util.Date 类型属性
  • 由于无默认转换器,抛出类型不匹配异常

2、解决

1)方案一

使用驱动统一的 java.time 类型

1
2
3
4
5
public class Staff {// 使用 java.time 类型private LocalDateTime createTime; // getter/setter
}
2)方案二

第一:自定义 BeanProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package org.zing.dao;import org.apache.commons.dbutils.BeanProcessor;import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;/*** 自定义 BeanProcessor - 实现 LocalDateTime 转换 java.util.Date** @author zqx* @date 2025-02-25*/
public class CustomBeanProcessor extends BeanProcessor {@Overrideprotected Object processColumn(ResultSet resultSet, int index, Class<?> propType) throws SQLException {// 获取某字段的数据Object value = super.processColumn(resultSet, index, propType);// 处理 LocalDateTime → Date 的转换if (value instanceof LocalDateTime localDateTime && propType == Date.class) {return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());}// 其它类型的转换...return value;}
}

第二:通过 RowProcessor 注入自定义处理器

1
2
3
4
5
6
7
8
// 创建自定义 RowProcessor
BasicRowProcessor rowProcessor = new BasicRowProcessor(new CustomBeanProcessor());// 创建 BeanListHandler 时传入自定义处理器
BeanListHandler<Staff> handler = new BeanListHandler<>(Staff.class, rowProcessor);// 执行查询
List<Staff> list = runner.query("select * from staffs", handler);

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public List<Staff> selectByPage(int limit, int count) {String sql = "select id,name,age,phone,sta_pos as staPos,add_time as addTime,update_time as updateTime from staffs limit ?,?";List<Staff> list = null;try {// ResultSetHandler VS BeanListHandler// ResultSetHandler 结果集处理器,通过实现此接口来对结果集数据进行处理// BeanListHandler 是 ResultSetHandler 接口的其中一个实现类,返回实体对象的List集合Object[] params = {limit, count};// 创建自定义 RowProcessorBasicRowProcessor rowProcessor = new BasicRowProcessor(new CustomBeanProcessor());// 创建 BeanListHandler 时传入自定义处理器BeanListHandler<Staff> handler = new BeanListHandler<>(Staff.class, rowProcessor);// 执行查询list = qr.query(sql, handler, params);} catch (SQLException e) {throw new RuntimeException(e);}return list;
}
http://www.dtcms.com/wzjs/37947.html

相关文章:

  • 北京感染人数最新消息什么是优化师
  • 网站开发客户对话河北百度推广
  • 南京企业网站开发网站改进建议有哪些
  • 做网站可以在哪儿接活百度收录查询工具
  • 房地产网站建设公司推荐百度百家号官网
  • 电子商务基础知识优化网站排名技巧
  • 云南网站建设公司有哪些重庆百度快照优化
  • php做网站的重点境外电商有哪些平台
  • 绵阳做seo网站公司中国营销网站
  • 如何建立分销网站域名注册哪个网站好
  • 柳州专业网站建设加盟江门网站定制多少钱
  • 专业的o2o网站建设如何创建个人网站免费
  • wordpress主题highend关键词快速优化排名软件
  • 平面设计用什么软件最好外贸seo推广公司
  • 北京网站建设代理正规seo一般多少钱
  • 在那个网站做ppt可以赚钱网站域名备案信息查询
  • 如何查一个网站的备案信息快速排名工具免费
  • 商城网站建设清单seo推广需要多少钱
  • 网站打不开 ...爱网站查询
  • 网站搜索引擎优化方案seo网站培训优化怎么做
  • 毕业设计做网站好做吗网站推广基本方法是
  • php网站怎么做测试seo课程在哪培训好
  • 九江做网站的百度推广落地页
  • 微网站自助建设厉害的seo顾问
  • 小型企业网络搭建长沙seo排名收费
  • 购物网站建设要多少钱现在疫情怎么样了最新消息
  • 教育网站建设情况报告中央下令全国各地核酸检测
  • 提供完善政府网站建设b2b外链
  • 温州网站制作价格谷歌google官网
  • 手机ppt在哪个网站做沈阳网站建设