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

佛山市官网网站建设怎么样昆山网站建设书生商友

佛山市官网网站建设怎么样,昆山网站建设书生商友,营销培训课程2022,wordpress 轮播图自适应MyBatis了解 MyBatis 是什么#xff1f; MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架 MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集 MyBatis 可以使用简单的XML或注解用于配置和原始映射#xff0c;将接口和Java的 POJO#x…MyBatis了解 MyBatis 是什么 MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架 MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集 MyBatis 可以使用简单的XML或注解用于配置和原始映射将接口和Java的 POJOPlain Old Java Objects普通的Java对象映射成数据库中的记录 MyBatis 是一个半自动的ORMObject Relation Mapping框架 MyBatis 优点与 JDBCHibernate 和 JPA 相比 轻量级性能出色 SQL 和 Java 编码分开功能边界清晰。Java 代码专注业务、SQL 语句专注数据 开发效率稍逊于HIbernate但是完全能够接受 JDBC SQL 夹杂在 Java 代码中耦合度高导致硬编码内伤 维护不易且实际开发需求中 SQL 有变化频繁修改的情况多见 代码冗长开发效率低 Hibernate 和 JPA 操作简便开发效率高 程序中的复杂 SQL 需要绕过框架 内部自动生产的 SQL不容易做特殊优化 基于全映射的全自动框架大量字段的 POJO 进行部分映射时比较困难 反射操作太多导致数据库性能下降 搭建 MyBatis ①创建 maven 工程 打包方式jar 引入依赖 dependencies!-- Mybatis核心 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.7/version/dependency!-- junit测试 --dependencygroupIdjunit/groupIdversion4.12/versionscopetest/scope/dependency!-- MySQL驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.32/version/dependency /dependencies②创建MyBatis的核心配置文件 一般命名为 mybatis-config.xml 但仅仅只是建议并非强制要求。以后整合Spring时这个配置文件可以省略 核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息 核心配置文件存放的位置是 maven 工程的 src/main/resources 目录下 ?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration!--设置连接数据库的环境--environments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC/dataSource typePOOLEDproperty namedriver valuecom.mysql.cj.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/db1/property nameusername valueroot/property namepassword valueroot//dataSource/environment/environments!--引入映射文件--mapperspackage namemappers/UserMapper.xml//mappers /configuration③创建mapper接口 MyBatis中的mapper接口相当于以前的dao。但是区别在于mapper仅仅是接口我们不需要提供实现类。 public interface UserMapper {/*** 添加用户信息*/void insertUser(); }④创建MyBatis的映射文件 相关概念ORMObject Relationship Mapping对象关系映射。 对象Java的实体类对象 关系关系型数据库 映射二者之间的对应关系 Java与数据库中一些存在对应关系的概念 Java概念数据库概念类表属性字段/列对象记录/行 映射文件的命名规则 表所对应的 实体类的类名 Mapper.xml 例如表 t_user 映射的实体类为 User 所对应的映射文件为 UserMapper.xml 因此一个映射文件对应一个实体类对应一张表的操作 MyBatis 映射文件用于编写 SQL 访问以及操作表中的数据 MyBatis 映射文件存放的位置是 src/main/resources/mappers 目录下 注意MyBatis 中可以面向接口操作数据要保证两个一致 mapper 接口的全类名和映射文件的命名空间namespace保持一致 mapper 接口中方法的方法名和映射文件中编写 SQL 的标签的id属性保持一致 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.zrb.mapper.UserMapper!--int insertUser();--insert idinsertUserinsert into t_user values(null,admin,123456,23,男,12345qq.com)/insert /mapper⑤通过junit测试功能 Testpublic void test() throws IOException {//读取MyBatis的核心配置文件InputStream is Resources.getResourceAsStream(mybatis-config.xml);//创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder new SqlSessionFactoryBuilder();//通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory生产SqlSession对象SqlSessionFactory sqlSessionFactory sqlSessionFactoryBuilder.build(is);//创建SqlSession对象此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务//SqlSession sqlSession sqlSessionFactory.openSession();//创建SqlSession对象此时通过SqlSession对象所操作的sql都会自动提交SqlSession sqlSession sqlSessionFactory.openSession(true);//通过代理模式创建UserMapper接口的代理实现类对象UserMapper userMapper sqlSession.getMapper(UserMapper.class);//调用UserMapper接口中的方法就可以根据UserMapper的全类名匹配元素文件通过调用的方法名匹配映射文件中的SQL标签并执行标签中的SQL语句int result userMapper.insertUser();//sqlSession.commit();System.out.println(结果result);}SqlSession代表Java程序和数据库之间的会话。HttpSession是Java程序和浏览器之间的会话 SqlSessionFactory是生产 SqlSession 的工厂。 工厂模式如果创建某一个对象使用的过程基本固定那么我们就可以把创建这个对象的相关代码封装到一个工厂类中以后都使用这个工厂类来生产我们需要的对象。 ⑥加入log4j日志功能用于查看查询信息可不要 加入依赖 !-- log4j日志 -- dependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version /dependency加入log4j的配置文件 log4j的配置文件名为log4j.xml存放的位置是src/main/resources目录下 ?xml version1.0 encodingUTF-8 ? !DOCTYPE log4j:configuration SYSTEM log4j.dtd log4j:configuration xmlns:log4jhttp://jakarta.apache.org/log4j/appender nameSTDOUT classorg.apache.log4j.ConsoleAppenderparam nameEncoding valueUTF-8 /layout classorg.apache.log4j.PatternLayoutparam nameConversionPattern value%-5p %d{MM-dd HH:mm:ss,SSS}%m (%F:%L) \n //layout/appenderlogger namejava.sqllevel valuedebug //loggerlogger nameorg.apache.ibatislevel valueinfo //loggerrootlevel valuedebug /appender-ref refSTDOUT //root /log4j:configuration日志的级别 FATAL(致命)ERROR(错误)WARN(警告)INFO(信息)DEBUG(调试) 从左到右打印的内容越来越详细 核心配置文件详解 核心配置文件中的标签必须按照固定的顺序 properties?,settings?,typeAliases?,typeHandlers?, objectFactory?,objectWrapperFactory?,reflectorFactory?, plugins?,environments?,databaseIdProvider?,mappers? ?xml version1.0 encodingUTF-8 ? !DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtdconfiguration!--MyBatis核心配置文件中的标签必须要按照指定的顺序配置properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?--!--引入properties文件此后就可以在当前文件中使用${key}的方式访问value--properties resourcejdbc.properties /!--typeAliases设置类型别名即为某个具体的类型设置一个别名在MyBatis的范围中就可以使用别名表示一个具体的类型--typeAliases!--type设置需要起别名的类型alias设置某个类型的别名--!--typeAlias typecom.zrb.pojo.User aliasabc/typeAlias--!--若不设置alias当前的类型拥有默认的别名即类名且不区分大小写--!--typeAlias typecom.zrb.pojo.User/typeAlias--!--通过包设置类型别名指定包下所有的类型将全部拥有默认的别名即类名且不区分大小写--package namecom.zrb.pojo//typeAliases!--environments配置连接数据库的环境属性default设置默认使用的环境的id--environments defaultdevelopment!--environment设置一个具体的连接数据库的环境属性id设置环境的唯一标识不能重复--environment iddevelopment!--transactionManager设置事务管理器属性type设置事务管理的方式typeJDBC|MANAGEDJDBC表示使用JDBC中原生的事务管理方式MANAGED被管理例如Spring--transactionManager typeJDBC/!--dataSource设置数据源属性type设置数据源的类型typePOOLED|UNPOOLED|JNDIPOOLED表示使用数据库连接池UNPOOLED表示不使用数据库连接池JNDI表示使用上下文中的数据源--dataSource typePOOLEDproperty namedriver value${jdbc.driver}/property nameurl value${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}//dataSource/environmentenvironment idtesttransactionManager typeJDBC/dataSource typePOOLEDproperty namedriver valuecom.mysql.cj.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/db1/property nameusername valueroot/property namepassword value123456//dataSource/environment/environments!--引入mybatis的映射文件--mappers!--mapper resourcemappers/UserMapper.xml/--!--以包的方式引入映射文件但是必须满足两个条件1、mapper接口和映射文件所在的包必须一致2、mapper接口的名字和映射文件的名字必须一致--package namecom.zrb.mapper//mappers /configurationMyBatis获取参数值的两种方式 MyBatis获取参数值的两种方式${} 和 #{} ${} 的本质就是字符串拼接#{} 的本质就是占位符赋值 ${} 使用字符串拼接的方式拼接 sql 若为字符串类型或日期类型的字段进行赋值时需要手动加单引号但是 #{} 使用占位符赋值的方式拼接 sql 此时为字符串类型或日期类型的字段进行赋值时可以自动添加单引号 单个字面量类型的参数 若mapper接口中的方法参数为单个的字面量类型此时可以使用 ${}和 #{} 以任意的名称获取参数的值注意 ${} 需要手动加单引号 多个字面量类型的参数 若 mapper 接口中的方法参数为多个时 此时 MyBatis 会自动将这些参数放在一个 map 集合中以arg0,arg1...为键以参数为值以 param1,param2... 为键以参数为值因此只需要通过 ${} 和 #{} 访问 map 集合的键就可以获取相对应的值注意 ${} 需要手动加单引号 map 集合类型的参数 若 mapper 接口中的方法需要的参数为多个时此时可以手动创建 map 集合将这些数据放在 map 中只需要通过 ${} 和 #{} 访问 map 集合的键就可以获取相对应的值注意 ${} 需要手动加单引号 实体类类型的参数 若mapper接口中的方法参数为实体类对象时,此时可以使用 ${} 和 #{} 通过访问实体类对象中的属性名获取属性值注意 ${} 需要手动加单引号 使用Param标识参数 可以通过 Param 注解标识mapper接口中的方法参数 此时会将这些参数放在 map 集合中以 Param 注解的 value 属性值为键以参数为值以 param1,param2...为键以参数为值只需要通过 ${} 和 #{} 访问 map 集合的键就可以获取相对应的值注意 ${} 需要手动加单引号 特殊SQL的执行 ①模糊查询 三种方式 //1.用${}${}只进行字符串拼接直接写入字符串中 select * from t_user where username like %${like}% //2.用concat函数进行拼接 select * from t_user where username like concat(%,#{like},%) //3.用#{}#{}不能字节写字符串中否则会变成拼接到字符串 //并不会对其进行正确赋值可以用%#{}%前后的%用双引号括起 select * from t_user where username like %#{like}%②批量删除 批量删除时可以用 ${} delete from t_user where id in (${ids})③动态设置表名 动态查询表是可以用 ${} select * from ${tableName}④添加功能获取自增的主键 场景模拟 t_clazz(clazz_id,clazz_name) //班级表 t_student(student_id,student_name,clazz_id) //学生表 1、添加班级信息 2、获取新添加的班级的id 3、为班级分配学生即将某学的班级id修改为新添加的班级的id 简单事例获取主键自增表 t_user 的新增id /** * 添加用户信息 */ int insertUser(User user);# useGeneratedKeys设置使用自增的主键 # keyProperty因为增删改有统一的返回值是受影响的行数因此只能将获取的自增的主键放在传输的参数user对象的某个属性中 !--int insertUser(User user);-- insert idinsertUser useGeneratedKeystrue keyPropertyidinsert into t_user values(null,#{username},#{password},#{age},#{sex}) /insert自定义映射resultMap resultType和resultMap 查询的标签 select 必须设置属性 resultType 或 resultMap 用于设置实体类和数据库表的映射关系 resultType自动映射用于属性名和表中字段名一致的情况 resultMap自定义映射用于一对多或多对一或字段名和属性名不一致的情况 resultMap处理字段和属性的映射关系 若字段名和实体类中的属性名不一致则可以通过resultMap设置自定义映射 !--resultMap设置自定义映射属性id表示自定义映射的唯一标识type查询的数据要映射的实体类的类型子标签id设置主键的映射关系result设置普通字段的映射关系association设置多对一的映射关系collection设置一对多的映射关系属性property设置映射关系中实体类中的属性名column设置映射关系中表中的字段名 -- resultMap iduserMap typeUserid propertyid columnid/idresult propertyuserName columnuser_name/resultresult propertypassword columnpassword/resultresult propertyage columnage/resultresult propertysex columnsex/result /resultMap !--ListUser testMohu(Param(mohu) String mohu);-- select idtest resultMapuserMap!--select * from t_user where username like %${mohu}%--select id,user_name,password,age,sex from t_user where user_name like concat(%,#{mohu},%) /select若字段名和实体类中的属性名不一致但是字段名符合数据库的规则使用_实体类中的属性名符合Java的规则使用驼峰此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系 可以通过为字段起别名的方式保证和实体类中的属性名保持一致 可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase可以在查询表中数据时自动将_类型的字段名转换为驼峰 例如字段名user_name设置了mapUnderscoreToCamelCase此时字段名就会转换为userName 多对一映射处理 场景模拟 查询员工信息以及员工所对应的部门信息 级联方式处理映射关系 resultMap idempDeptMap typeEmpid columneid propertyeid/idresult columnename propertyename/resultresult columnage propertyage/resultresult columnsex propertysex/resultresult columndid propertydept.did/resultresult columndname propertydept.dname/result /resultMap !--Emp getEmpAndDeptByEid(Param(eid) int eid);-- select idgetEmpAndDeptByEid resultMapempDeptMapselect emp.*,dept.* from t_emp emp left join t_dept dept on emp.did dept.did where emp.eid #{eid} /select即这一步操作在员工表中定义了一个部门类型的成员变量通过数据库中查询的字段与部门类型的成员变量中的部门属性进行映射 使用association处理映射关系 resultMap idempDeptMap typeEmpid columneid propertyeid/idresult columnename propertyename/resultresult columnage propertyage/resultresult columnsex propertysex/result!-- association设置多对一的映射关系 --association propertydept javaTypeDeptid columndid propertydid/idresult columndname propertydname/result/association /resultMap !--Emp getEmpAndDeptByEid(Param(eid) int eid);-- select idgetEmpAndDeptByEid resultMapempDeptMapselect emp.*,dept.* from t_emp emp left join t_dept dept on emp.did dept.did where emp.eid #{eid} /select分步查询 ①查询员工信息 /** * 通过分步查询查询员工信息 * param eid * return */ Emp getEmpByStep(Param(eid) int eid);resultMap idempDeptStepMap typeEmpid columneid propertyeid/idresult columnename propertyename/resultresult columnage propertyage/resultresult columnsex propertysex/result!--select设置分步查询查询某个属性的值的sql的标识namespace.sqlIdcolumn将sql以及查询结果中的某个字段设置为分步查询的条件--association propertydeptselectcom.zrb.mapper.DeptMapper.getEmpDeptByStep columndid!-- 此处colum的作用为把当前查询出来的结果的某一字段作为下一步查询的条件使用 --/association /resultMap !--Emp getEmpByStep(Param(eid) int eid);-- select idgetEmpByStep resultMapempDeptStepMapselect * from t_emp where eid #{eid} /select②根据员工所对应的部门id查询部门信息 /** * 分步查询的第二步 根据员工所对应的did查询部门信息 * param did * return */ Dept getEmpDeptByStep(Param(did) int did);!--Dept getEmpDeptByStep(Param(did) int did);-- select idgetEmpDeptByStep resultTypeDeptselect * from t_dept where did #{did} /select一对多映射处理 collection /** * 根据部门id查新部门以及部门中的员工信息 * param did * return */ Dept getDeptEmpByDid(Param(did) int did);resultMap iddeptEmpMap typeDeptid propertydid columndid/idresult propertydname columndname/result!--ofType设置collection标签所处理的集合属性中存储数据的类型--collection propertyemps ofTypeEmpid propertyeid columneid/idresult propertyename columnename/resultresult propertyage columnage/resultresult propertysex columnsex/result/collection /resultMap !--Dept getDeptEmpByDid(Param(did) int did);-- select idgetDeptEmpByDid resultMapdeptEmpMapselect dept.*,emp.* from t_dept dept left join t_emp emp on dept.did emp.did where dept.did #{did} /select分步查询 ①查询部门信息 /** * 分步查询部门和部门中的员工 * param did * return */ Dept getDeptByStep(Param(did) int did);resultMap iddeptEmpStep typeDeptid propertydid columndid/idresult propertydname columndname/resultcollection propertyemps fetchTypeeagerselectcom.atguigu.MyBatis.mapper.EmpMapper.getEmpListByDid columndid/collection /resultMap !--Dept getDeptByStep(Param(did) int did);-- select idgetDeptByStep resultMapdeptEmpStepselect * from t_dept where did #{did} /select②根据部门id查询部门中的所有员工 /** * 根据部门id查询员工信息 * param did * return */ ListEmp getEmpListByDid(Param(did) int did);!--ListEmp getEmpListByDid(Param(did) int did);-- select idgetEmpListByDid resultTypeEmpselect * from t_emp where did #{did} /select分步查询的优点 可以实现延迟加载但是必须在核心配置文件中设置全局配置信息 lazyLoadingEnabled延迟加载的全局开关。当开启时所有关联对象都会延迟加载aggressiveLazyLoading当开启时任何方法的调用都会加载该对象的所有属性。否则每个属性会按需加载此时就可以实现按需加载获取的数据是什么就只会执行相应的sql。此时可通过 association 和 collection 中的 fetchType 属性设置当前的分步查询是否使用延迟加载 fetchType lazy (延迟加载)|eager(立即加载) 动态SQL Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。 if if 标签可通过 test 属性的表达式进行判断若表达式的结果为 true 则标签中的内容会执行反之标签中的内容不会执行 !--ListEmp getEmpListByCondition(Emp emp);-- select idgetEmpListByMoreTJ resultTypeEmpselect * from t_emp where 11if testename ! and ename ! nulland ename #{ename}/ifif testage ! and age ! nulland age #{age}/ifif testsex ! and sex ! nulland sex #{sex}/if /selectwhere where 和 if 一般结合使用 若 where 标签中的 if 条件都不满足则 where 标签没有任何功能即不会添加 where 关键字若 where 标签中的if条件满足则 where 标签会自动添加 where 关键字并将条件最前方多余的 and 去掉 注意where 标签不能去掉条件最后多余的 and。 trim trim用于去掉或添加标签中的内容 常用属性 prefix在trim标签中的内容的前面添加某些内容 prefixOverrides在trim标签中的内容的前面去掉某些内容 suffix在trim标签中的内容的后面添加某些内容 suffixOverrides在trim标签中的内容的后面去掉某些内容 select idgetEmpListByMoreTJ resultTypeEmpselect * from t_emptrim prefixwhere suffixOverridesandif testename ! and ename ! nullename #{ename} and/ifif testage ! and age ! nullage #{age} and/ifif testsex ! and sex ! nullsex #{sex}/if/trim /selectchoose、when、otherwise choose、when、 otherwise相当于if…else if…else !--ListEmp getEmpListByChoose(Emp emp);-- select idgetEmpListByChoose resultTypeEmpselect include refidempColumns/include from t_empwherechoosewhen testename ! and ename ! nullename #{ename}/whenwhen testage ! and age ! nullage #{age}/whenwhen testsex ! and sex ! nullsex #{sex}/whenwhen testemail ! and email ! nullemail #{email}/when/choose/where /selectforeach !-- 添加多条数据 -- !--int insertMoreEmp(ListEmp emps);-- insert idinsertMoreEmpinsert into t_emp valuesforeach collectionemps itememp separator,(null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)/foreach /insert !-- 删除多条数据 -- !--int deleteMoreByArray(int[] eids);-- delete iddeleteMoreByArraydelete from t_emp whereforeach collectioneids itemeid separatororeid #{eid}/foreach /delete !--int deleteMoreByArray(int[] eids);-- delete iddeleteMoreByArraydelete from t_emp where eid inforeach collectioneids itemeid separator, open( close)#{eid}/foreach /deleteSQL片段 sql片段可以记录一段公共sql片段在使用的地方通过include标签进行引入 sql idempColumnseid,ename,age,sex,did /sql select include refidempColumns/include from t_emp分页插件 分页插件的使用步骤 ①添加依赖 dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.2.0/version /dependency②配置分页插件 在MyBatis的核心配置文件中配置插件 plugins!--设置分页插件--plugin interceptorcom.github.pagehelper.PageInterceptor/plugin /plugins分页插件的使用 1在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能 pageNum当前页的页码 pageSize每页显示的条数 2在查询获取 list 集合之后使用PageInfoT pageInfo new PageInfo(ListT list, int navigatePages)获取分页相关数据 list分页之后的数据 navigatePages导航分页的页码数 3分页相关数据 PageInfo{ pageNum8, pageSize4, size2, startRow29, endRow30, total30, pages8, listPage{counttrue, pageNum8, pageSize4, startRow28, endRow32, total30, pages8, reasonablefalse, pageSizeZerofalse}, prePage7, nextPage0, isFirstPagefalse, isLastPagetrue, hasPreviousPagetrue, hasNextPagefalse, navigatePages5, navigateFirstPage4, navigateLastPage8, navigatepageNums[4, 5, 6, 7, 8] } pageNum当前页的页码 pageSize每页显示的条数 size当前页显示的真实条数 total总记录数 pages总页数 prePage上一页的页码 nextPage下一页的页码 isFirstPage/isLastPage是否为第一页/最后一页 hasPreviousPage/hasNextPage是否存在上一页/下一页 navigatePages导航分页的页码数 navigatepageNums导航分页的页码[1,2,3,4,5]
http://www.hkea.cn/news/14276877/

相关文章:

  • 中江建设银行网站企业网站备案流几天
  • 上海网站建设找摩彼做网站的的价位
  • 简单企业网站建设免费云主机试用一年
  • 购买手机网站推荐网站建设简单流程
  • 青岛高端网站设计公司wordpress 相同文章
  • 淘宝网站开发框架越秀网站建设方案
  • 福建网站建设网wordpress导航单页
  • 做个简单的网站多少钱企业网站建立的目的
  • 培训网站建设报价单网站app简单做
  • 专做母婴的网站长安网站建设网络推广
  • 与企业网站做接口做业务有哪些好的网站
  • 做网站网站犯法吗网站推广与优化哪里好
  • 购物网站建设基本流程树状图游戏推广怎么快速拉人
  • 网站没有索引量是什么意思网站后台不显示验证码
  • 国外设计灵感网站网站服务器类型查询
  • 网站建设费能算作广告费用吗frontpg做网站好吗
  • 北京网站建设招标苏州网站定制公司哪家好
  • 常德网站建设网站优化鹤壁网站制作
  • 做网站哪些网络公司好东莞常平做网站公司
  • 网站关键词优化外包服务学院网站建设自评
  • 深圳网站建设送域名网片钢筋
  • 没有网站可以做cpa吗网站建设用什么软件
  • 网页设计和网站开发有什么区别建设学校网站的作用
  • 塔城北京网站建设专业做电脑系统下载网站
  • 太原做网站制作天津市建设与管理网站
  • 个性化定制网站门户网站的营销特点
  • 钦州建站哪家好线上电商平台
  • 校园网站设计与实现新的网站设计制作
  • 普通网站和门户网站的区别网站制作视频教程新手必看
  • 广东同江医院网站建设网站搭建兼职