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

济南网站制作多少钱dedecms小说网站模板下载

济南网站制作多少钱,dedecms小说网站模板下载,医院网站建设政策,wordpress可折叠菜单这是我的JDBC第三次学习了#xff0c;在学习的过程中#xff0c;老是会忘掉一些知识#xff0c;不记下笔记实在不行啊#xff01; 使用JDBC调用存储过程 (1)关于如何使用Navicat(11.1.13) for MySQL如何创建存储过程。我在另一篇文章写过#xff0c;在此不赘述了。 使用Na…   这是我的JDBC第三次学习了在学习的过程中老是会忘掉一些知识不记下笔记实在不行啊    使用JDBC调用存储过程    (1)关于如何使用Navicat(11.1.13) for MySQL如何创建存储过程。我在另一篇文章写过在此不赘述了。    使用Navicat(11.1.13) for MySQL如何创建存储过程存储过程的主要代码如下 BEGININSERT INTO user (name, birthday, money) values (pname, birthday, money);SELECT LAST_INSERT_ID() into pid; END    注意 in表示输入参数。out表示输出参数。last_insert_id()是mysql所特有的一个函数可以查询出最后一次插入到数据库的那条数据的id。    (2)使用JDBC调用存储过程(即返回当前这条记录插入后形成的id)代码如下 static void ps() throws SQLException {Connection conn null;CallableStatement cs null;ResultSet rs null;try {conn JdbcUtils.getConnection();/** call是固定写法addUser()是我们在数据库中定义的存储过程的名字* ()后面指定参数 如果没有任何参数addUser后的括号也要写上。* 所以类似于函数 */String sql {call addUser(?,?,?,?)};cs conn.prepareCall(sql);cs.registerOutParameter(4, Types.INTEGER);//注册输出参数/** 设置输入参数*/cs.setString(1, pa name);cs.setDate(2, new java.sql.Date(System.currentTimeMillis()));cs.setFloat(3, 100f);cs.executeUpdate();int id cs.getInt(4);//不注册输出参数是不能这样拿出来的System.out.println(idid);} finally {JdbcUtils.free(rs, cs, conn);}}    返回当前这条记录插入后形成的id还有如下你方法 static int create() throws SQLException {Connection conn null;PreparedStatement ps null;ResultSet rs null;try {//2.建立连接conn JdbcUtils.getConnection();//3.创建语句String sql insert into user (name,birthday,money) values (name1 gk,1987-01-01,400);/** 自动产生主键用参数Statement.RETURN_GENERATED_KEYS拿出产生的主键* mysql参数Statement.RETURN_GENERATED_KEYS加不加都可以拿出来* 但是这和不同的数据库产品以及相应的驱动有关所以最好写上*/ps conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);ps.executeUpdate();/** getGeneratedKeys()这个方法为什么不是返回int类型而是要返回一个ResultSet类型呢* 因为一、主键不一定是int类型* 二、联合(复合)主键 有可能是一张表中的几个字段合起来构成一个id这样就不能返回一个int类型了* 如果是联合主键返回的是多列的内容我们可以遍历ResultSet得到联合主键列的值。 * 所以返回ResultSet*/rs ps.getGeneratedKeys();int id 0;if(rs.next()) {id rs.getInt(1);}return id;} finally {JdbcUtils.free(rs, ps, conn);}}      使用JDBC的批处理功能     批处理可以大幅度提升大量增、删、改的速度。 public class BatchTest {//main方法调用测试批量插入与普通的insert所消耗的时间比 public static void main(String[] args) throws SQLException {long start System.currentTimeMillis();for(int i 0; i 100; i) {create(i);}long end System.currentTimeMillis();System.out.println(create:(end-start));start System.currentTimeMillis();createBatch();end System.currentTimeMillis();System.out.println(createBatch:(end-start));}//普通方法插入数据static void create(int i) throws SQLException {Connection conn null;PreparedStatement ps null;ResultSet rs null;try {//2.建立连接conn JdbcUtils.getConnection();//3.创建语句String sql insert into user (name,birthday,money) values (?,?,?);ps conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);ps.setString(1, batch namei);ps.setDate(2, new java.sql.Date(System.currentTimeMillis()));ps.setFloat(3, 100fi);ps.executeUpdate();} finally {JdbcUtils.free(rs, ps, conn);}}//批量插入数据static void createBatch() throws SQLException {Connection conn null;PreparedStatement ps null;ResultSet rs null;try {//2.建立连接conn JdbcUtils.getConnection();//3.创建语句String sql insert into user (name,birthday,money) values (?,?,?);ps conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);/** 每循环一次都会形成一条新的sql语句被打包直到循环完成然后进行批量的处理* 那么可不可以无限量的增加呢其实会产生内存溢出的情况到底循环多少次进行打包才合适这个值要经过测试*/for(int i 0; i 100; i) {ps.setString(1, batch namei);ps.setDate(2, new java.sql.Date(System.currentTimeMillis()));ps.setFloat(3, 100fi);/** 并不是使用批处理就会提高效率* 把sql语句打成一个包* 包不能太大(并不是越大越好)会内存溢出*/ps.addBatch();}int[] is ps.executeBatch();} finally {JdbcUtils.free(rs, ps, conn);}}}        可滚动结果集与分页技术  static void scroll() throws SQLException {Connection conn null;Statement st null;ResultSet rs null;try {conn JdbcUtils.getConnection();/** 在创建一个Statement的时候指定可滚动的结果集的类型* TYPE_SCROLL_SENSITIVE滚动的过程中对数据库是敏感的* (按我的理解就是查询数据的时候如果又新增、删除、更新那么能感觉得到)* CONCUR_READ_ONLY字面意思是同意只读*/st conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);/** 在mysql中通过limit关键字实现分页* 每种数据库产品的关键字不同例如Oracle使用rownumsqlServer用top* 现在有几十种关系型数据库如果数据库不支持这种关键字进行分页的时候可以用滚动的结果集来实现分页* 但是性能比较低 *///sql select id,name,birthday,money from user limit 150, 10;//mysql支持分页rs st.executeQuery(select id,name,birthday,money from user);//5.处理结果while(rs.next()) {System.out.println(rs.getObject(id)\trs.getObject(name)\trs.getObject(birthday)\trs.getObject(money));}System.out.println(-------------------------------------);/** 绝对定位可以直接定位到rs所有返回结果中指定的一条记录上 * 例定位到第150行*/rs.absolute(150);int i 0;/** 可以通过i来控制循环次数实现分页效果* 但是要数据库产品或者驱动支持此功能 */while(rs.next() i 10) {i;System.out.println(rs.getObject(id)\trs.getObject(name)\trs.getObject(birthday)\trs.getObject(money));}} finally {JdbcUtils.free(rs, st, conn);}}        可更新和对更新敏感的结果集  static void read() throws SQLException, InterruptedException {Connection conn null;Statement st null;ResultSet rs null;try {//2.建立连接conn JdbcUtils.getConnection();//3.创建语句/** 设置滚动结果集的类型为ResultSet.TYPE_SCROLL_SENSITIVE就是能感知到数据库的变化 * CONCUR_UPDATABLE字面意思是同意更新*/st conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);//4.执行语句rs st.executeQuery(select id,name,birthday,money from user where id 5);//5.处理结果/** 验证TYPE_SCROLL_SENSITIVE* 下面让rs每循环一次rs睡眠10秒钟然后再这个过程中我们用mysql客户端修改数据库中的数据 * 我们看看它读出来的是修改前的数据还是修改后的。我们在上面设置的可滚动的结果集的类型 * 是ResultSet.TYPE_SCROLL_SENSITIVE也就是能感知数据库的变化那如果在rs没有读出数据库里的* 那条数据之前我们在mysql的客户端将原先的数据修改掉这里读出来的数据应该是修改后的数据但是在* 测试的时候读出的数据却依然是修改之前的这应该和数据库的驱动有关系 * 但是如果是能感知数据库的变化那么数据库的性能也是降低了你执行executeQuery()方法后它已经将数据查询完成* 打包后给你发送过来了如果察觉到数据库的变化那么它要在输出之前再查询一遍数据库这种需求用的比较少作为了解即可 */while(rs.next()) {int id rs.getInt(id);System.out.println(show id ...);Thread.sleep(10000);System.out.println(id\trs.getObject(name)\trs.getObject(birthday)\trs.getObject(money));/** 查询的时候可以更新(可更新的结果集)* 可更新的结果集我们并不建议这样做因为上面的sql语句是查询操作 * 但是下面还隐藏着更新操作对于程序的可读性不好这种需求也比较少 * 了解即可*/String name rs.getString(name);if(lisi.equals(name)) {rs.updateFloat(money, 300f);rs.updateRow();//修改完成后要修改一行 }}} finally {JdbcUtils.free(rs, st, conn);}}       数据库的元数据信息     通过DatabaseMetaData可以获得数据库相关的信息如数据库版本、数据库名、数据库厂商信息、是否支持事务、是否支持某种事务隔离级别是否支持滚动结果集等。对于我们编写程序来说不常用但是在框架的编写中经常会用到例如hibernate它要屏蔽不同数据库之间的区别那么它就要知道当前是什么数据库然后做出相应的判断处理在使用hibernate的时候有一项是配置数据库的方言其实就是指定你使用的是什么数据库产品。如果你不进行指定hibernate会自动的尝试着去检测当前数据库产品的类型其实就是根据DatabaseMetaData来检测的。    示例代码 public class DBMO {public static void main(String[] args) throws SQLException {Connection conn JdbcUtils.getConnection();//得到数据库的元信息 DatabaseMetaData dbmd conn.getMetaData();//取出当前使用数据库的名称 System.out.println(db name dbmd.getDatabaseProductName());//看看当前数据库支不支持事务 System.out.println(tx dbmd.supportsTransactions());conn.close();}}      参数的元数据信息  public class ParameterMetaTest {public static void main(String[] args) throws SQLException {Object[] params new Object[] {lisi, new java.sql.Date(System.currentTimeMillis()), 100f};read(select * from user where name ? and birthday ? and money ?, params);}static void read(String sql, Object[] params) throws SQLException {Connection conn null;PreparedStatement ps null;ResultSet rs null;try {conn JdbcUtils.getConnection();ps conn.prepareStatement(sql);//得到参数信息的元数据 /*第一种方式给sql语句中的占位符赋值但是要约定sql语句中占位符的所表示的类型和个数和参数数组中是一致的 ParameterMetaData pmd ps.getParameterMetaData();int count pmd.getParameterCount();for(int i 1; i count; i) {System.out.print(pmd.getParameterClassName(i) \t);System.out.print(pmd.getParameterType(i) \t);System.out.println(pmd.getParameterTypeName(i));//CtrlT打开其基础体系ps.setObject(i, params[i-1]);}*//** 第二种方式给sql语句中的占位符赋值*/for(int i 1; i params.length; i) {ps.setObject(i, params[i-1]);}rs ps.executeQuery();while(rs.next()) {System.out.println(rs.getInt(id)\trs.getString(name)\trs.getDate(birthday)\trs.getFloat(money));}} finally {JdbcUtils.free(rs, ps, conn);}} }    小知识快捷键CtrlT——打开其整个继承体系。    有可能产生的异常 java.sql.SQLException: Parameter metadata not available for the given statement解决的方法不难就是在连接数据库时的URL后面加上可以返回的元数据类型    例如出异常时我的URL是这样写的 url jdbc:mysql://localhost:3306/jdbc;正确写法应该是 url jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadatatrue;出现异常的原因因为mysql驱动默认generateSimpleParameterMetadatafalse只有设置为truemetadata类型会将每一个参数反射为Varchar类型。(时间才过去几天就有点不是很清楚了)        将结果集元数据封装为Map       现在我们有一种需求将ResultSet结果集中的数据封装成Mapmap的key是数据库中字段的值value就是在字段中的值。    通过ResultSetMetaData可以获得结果有几列、各列名、各列别名、各列类型等。    可以将ResultSet放入Map(key:列名 value:列值)。    用反射ResultSetMetaData将查询结果读入对象中简单的O/RMapping。 让SQL语句中列别名和要读入的对象属性名一样通过ResultSetMetaData获得结果列数和列别名通过反射将对象的所有setXxx方法找到将3中找到的方法setXxx和2中找到的列别名进行匹配即方法中的Xxx与列别名相等由上一步找到的方法和列别名对应关系进行赋值 Method.invoke(obj, rs.getObject(columnAliasName));       示例代码如下 public class ResultSetMetaDataTest {public static void main(String[] args) throws SQLException {ListMapString, Object data read(select id, name as n from user where id 5);System.out.println(data);}static ListMapString, Object read(String sql) throws SQLException {Connection conn null;PreparedStatement ps null;ResultSet rs null;try {conn JdbcUtils.getConnection();ps conn.prepareStatement(sql);rs ps.executeQuery();//得到ResultSet的元数据 ResultSetMetaData rsmd rs.getMetaData();//得到ResultSet元数据的列数 int count rsmd.getColumnCount();String[] colNames new String[count];for(int i 1; i count; i) {System.out.print(rsmd.getColumnClassName(i)\t);//得到参数的类名例java.lang.String System.out.print(rsmd.getColumnName(i)\t);//取列的实际名字System.out.println(rsmd.getColumnLabel(i));//取列的别名colNames[i-1] rsmd.getColumnLabel(i);}ListMapString, Object datas new ArrayListMapString, Object();while(rs.next()) {MapString, Object data new HashMapString, Object();for(int i 0; i colNames.length; i) {data.put(colNames[i], rs.getObject(colNames[i]));}datas.add(data);}return datas;} finally {JdbcUtils.free(rs, ps, conn);}} }        编写一个基本的连接池来实现连接的复用   大家都知道Arraylist的底层使用数组实现的而LinkedList使用链表实现的所以对于Arraylist读取速度比较快而对于LinkedList修改和添加比较快所以我们这个连接池因为要频繁的操作集合所以用LinkedList来实现。 public class MyDataSource {private static String url jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadatatrue;private static String user root;private static String password yezi;/** 对集合中的元素进行频繁的取出* 用LinkedList*/LinkedListConnection connectionsPool new LinkedListConnection();//向我们的LinkedList集合中加入10个链接作为我们的连接池 public MyDataSource() {try {for(int i 0; i 10; i) {//将Connection放到链表的最后面 this.connectionsPool.addLast(this.createConnection());}} catch(SQLException e) {throw new ExceptionInInitializerError(e);}}//得到一个链接(先进先出算法)public Connection getConnection() throws SQLException {return this.connectionsPool.removeFirst();}//创建链接private Connection createConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}/** 关闭一个链接这个关闭不是真正意义上的关闭* 而是又把它放回到连接池中实现了Connection的复用 */public void free(Connection conn) {this.connectionsPool.addLast(conn);} }    对基本连接池进行一些工程细节上的优化    在上面实现的连接池中我们只是默认创建了10个连接但是如果这个时候有10个线程同时都来拿连接那连接池里就没有连接了在有线程过来拿的时候就会报错了现在我们进行一些优化。 public class MyDataSource {private static String url jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadatatrue;private static String user root;private static String password yezi;//规定默认创建的连接数 private static int initCount 5;//规定最大可以创建的连接数 private static int maxCount 10;//统计当前共创建了多少个连接 private int currentCount 0;/** 对集合中的元素进行频繁的取出* 用LinkedList*/LinkedListConnection connectionsPool new LinkedListConnection();public MyDataSource() {try {for(int i 0; i initCount; i) {this.connectionsPool.addLast(this.createConnection());//每创建一个链接currentCount this.currentCount;}} catch(SQLException e) {throw new ExceptionInInitializerError(e);}}public Connection getConnection() throws SQLException {/** 因为Connection不是线程安全的* 所以我必须保证每个线程拿到的链接不是同一个所以要进行同步当两个线程同时来拿的时候 * 另外一个线程必须等待 */synchronized (connectionsPool) {//①连接池中还有连接取出if(this.connectionsPool.size() 0)return this.connectionsPool.removeFirst();//②连接池中已没有连接并且当前创建的链接数没有到最大值那就继续创建链接 if(this.currentCount maxCount) {this.currentCount;return this.createConnection();}//③大于连接池中的最大数抛出异常throw new SQLException(已没有连接);}}public void free(Connection conn) {this.connectionsPool.addLast(conn);}private Connection createConnection() throws SQLException {return DriverManager.getConnection(url, user, password);} }        通过代理模式来保持用户关闭连接的习惯    在上面的示例中我们在关闭链接的时候调用的是free方法来把这个连接又放回到了池中但是按照开发人员的使用习惯应该是调用colse()方法来关闭一个链接但是如果调用close方法关闭那这个连接就真的关闭了也就是说我们这个方法设计的不符合开发人员的使用习惯。下面我用代理模式(关于代理模式我在另一篇文章中写过)的方法来解决这个问题     定义一个类实现Connection接口Connectio接口中有很多的方法这些方法我们都无法自己完成我们交给通过构造方法传递进来的真正的Connection的对象来完成我们只是修改它的close方法在用户得到链接的时候我们返回给用户这个类的对象那么当用户调用close方法关闭链接的时候我们就可以在这个close方法中将用户要关闭的那个链接再次的放到连接池中这样链接就不会真正的关闭了。 public class MyConnetion implements Connection {private Connection realConnection;private MyDataSource2 dataSource;/** 限制其(连接)最大使用次数*/private int maxUseCount 5;/** 记录(连接)当前使用次数*/private int currentUseCount 0;/** 由于访问修饰符是default* 所以只能在包cn.itcast.jdbc.datasource中使用MyConnetion*/MyConnetion(Connection connection, MyDataSource2 dataSource) {this.realConnection connection;this.dataSource dataSource;}//清除警告Overridepublic void clearWarnings() throws SQLException {this.realConnection.clearWarnings();}Overridepublic Statement createStatement() throws SQLException {return this.realConnection.createStatement();}Overridepublic void commit() throws SQLException {this.realConnection.commit();}Overridepublic void close() throws SQLException {this.currentUseCount;/** 规定同一个链接只能使用maxUseCount次* 超过这个次数就把真正的链接关闭连接池中就要少一个链接* 这个时候再拿链接拿到的就是新创建得一个新的链接对象了。 */if(this.currentUseCount this.maxUseCount)this.dataSource.connectionsPool.addLast(this);else {this.realConnection.close();this.dataSource.currentCount--;}}//Connectio接口中实在是有太多的方法在此就不写了我们主要关注close()方法}    为了更清楚地表达思想我们可以慢慢来优化代码(不好的代码) public class MyDataSource2 {private static String url jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadatatrue;private static String user root;private static String password yezi;private static int initCount 1;private static int maxCount 1;int currentCount 0;LinkedListMyConnetion connectionsPool new LinkedListMyConnetion();public MyDataSource2() {try {for(int i 0; i initCount; i) {this.connectionsPool.addLast(this.createConnection());this.currentCount;}} catch(SQLException e) {throw new ExceptionInInitializerError(e);}}public Connection getConnection() throws SQLException {synchronized (connectionsPool) {if(this.connectionsPool.size() 0)return this.connectionsPool.removeFirst();if(this.currentCount maxCount) {this.currentCount;return this.createConnection();}throw new SQLException(已没有连接);}}public void free(Connection conn) {if(conn instanceof MyConnetion) {this.connectionsPool.addLast((MyConnetion)conn);}}private MyConnetion createConnection() throws SQLException {Connection realConn DriverManager.getConnection(url, user, password);MyConnetion myConnetion new MyConnetion(realConn, this);return myConnetion;}}    因为针对接口编程是面向对象的第一原则所以我们优化代码为 public class MyDataSource2 implements DataSource {//实现了DataSource接口之后就是一个标准的数据源了我们的程序只和数据源打交道后面会讲DBCP实现private static String url jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadatatrue;private static String user root;private static String password yezi;private static int initCount 1;private static int maxCount 1;int currentCount 0;/** 针对接口编程——面向对象的第一原则*/LinkedListConnection connectionsPool new LinkedListConnection();public MyDataSource2() {try {for(int i 0; i initCount; i) {this.connectionsPool.addLast(this.createConnection());this.currentCount;}} catch(SQLException e) {throw new ExceptionInInitializerError(e);}}public Connection getConnection() throws SQLException {synchronized (connectionsPool) {if(this.connectionsPool.size() 0)return this.connectionsPool.removeFirst();if(this.currentCount maxCount) {this.currentCount;return this.createConnection();}throw new SQLException(已没有连接);}}public void free(Connection conn) {this.connectionsPool.addLast(conn);}private Connection createConnection() throws SQLException {/** 这是一个真实的connection*/Connection realConn DriverManager.getConnection(url, user, password);MyConnetion myConnetion new MyConnetion(realConn, this);return myConnetion;//返回一个代理对象}  //实现DataSource接口中一系列方法较多不写}        Java的动态代理及使用该技术完善连接代理     在上面的示例中我们为了产生一个代理对象实现了Connection接口的所有的方法但是我们只需要修改它的close方法别的方法我们都需要交给真正的Connection对象去处理比较麻烦我们用动态代理(?)来实现它。 class MyConnectionHandler implements InvocationHandler {private Connection realConnection;private Connection warpedConnection;private MyDataSource2 dataSource;/** 限制其最大使用次数*/private int maxUseCount 5;/** 记录当前使用次数*/private int currentUserCount 0;MyConnectionHandler(MyDataSource2 dataSource) {this.dataSource dataSource;}Connection bind(Connection realConn) {this.realConnection realConn;/** Proxy类就像程序员一样可写代码* Proxy写一个类此类实现了Connection接口* 对connection接口的方法调用转化给调用处理器MyConnectionHandler* * 动态产生warped(包裹的)Connection。*/this.warpedConnection (Connection)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {Connection.class}, this);return warpedConnection;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if(close.equals(method.getName())) {this.currentUserCount;if(this.currentUserCount this.maxUseCount)this.dataSource.connectionsPool.addLast(this.warpedConnection);else {this.realConnection.close();this.dataSource.currentCount--;}}/** 调用方法的时候如果是close方法就执行我们的逻辑(上面的代码)* 对于其他的所有的方法全部交给真实Connection对象本身自己去处理 * 调用realConnection实例的method方法*/ return method.invoke(this.realConnection, args);} }    当写完上面的代理类后我们还是需要修改MyDataSource2类的createConnection()方法来调用我们的代理类将它需要的参数传递给它并把生成的代理类返回(注意MyDataSource2类中只须修改createConnection())部分代码如下 private Connection createConnection() throws SQLException {/** 这是一个真实的connection*/Connection realConn DriverManager.getConnection(url, user, password);MyConnectionHandler proxy new MyConnectionHandler(this);return proxy.bind(realConn);}      标准DataSource接口及数据源的总结介绍     理解数据源的优势与特点  DataSource用来取代DriverManager来获取Connection通过DataSource获得Connection速度很快通过DataSource获得的Connection都是已经被包裹过的不是驱动原来的连接他的close方法已经被修改一般DataSource内部会用一个连接池来缓存Connection这样可以大幅度提高数据库的访问速度连接池可以理解成一个能够存放Connection的Collection我们的程序只和DataSource打交道不会直接访问连接池。   转载于:https://www.cnblogs.com/yerenyuan/p/5328115.html
http://www.zqtcl.cn/news/903536/

相关文章:

  • 国外mod大型网站财税公司
  • 一个很好的个人网站开发做一个简单网页多少钱
  • 东莞在哪里学网站建设网站建设团队与分工
  • 网站功能插件昆明网站建设技术研发中心
  • 网站开发培训中心 市桥移动端ui
  • 高碑店地区网站建设上海排名十大装潢公司
  • 无锡自助建站网站还是新能源专业好
  • pc 手机网站 微站如何建设与维护网站
  • 大学生兼职网站开发毕设论文杭州网络排名优化
  • 做教育机器网站网站建设的步骤图
  • 桔子建站是什么平台郑州公司注册网上核名
  • 网站开发技能有哪些网站建设艾金手指科杰
  • 网站建设挂什么费用网站建设学那些课
  • 网站定位与功能分析在互联网公司做网站
  • 安阳网站建设兼职做网站推广有哪些公司
  • 网站制作的一般过程怎么用手机搭建网站
  • 备案 网站名称 怎么改深圳建网站公司
  • html 企业网站模板网站策划书免费
  • 网站建设销售ppt拖拽建站系统源码
  • 网站托管费用多少网站的开发流程
  • 周到的商城网站建设北京品牌网站
  • 网站开发费用属于什么科目网站建设考试多选题
  • c asp做网站wordpress4.5.2文章采集
  • 百度网站建设电话建立网站站建设可以吗
  • 网站后台代码在哪修改网站如何做下一页
  • 网站开发职业要求百度推广代理商与总公司的区别
  • 西安网站建设中心网页 网 址网站区别
  • 技术支持东莞网站建设机械seo岗位是什么意思
  • 做商城网站需要备案什么域名硬件开发工具有哪些
  • 网络网站制作技巧wordpress全文