垂直搜索引擎完整實現

来源:http://www.cnblogs.com/1996swg/archive/2017/08/17/7383678.html
-Advertisement-
Play Games

本篇博客是在上一篇《Lucene搜索引擎+HDFS+MR完成垂直搜索》的基礎上,在數據收集之後的JSP/Servlet方面,換為SpringMVC框架來實現。 藉助SpringMVC技術完成資料庫、HDFS、頁面的交互,以達到實現垂直搜索引擎。 本篇博客的思想:一是深入數據收集、分析、關鍵詞搜索呈現 ...


本篇博客是在上一篇《Lucene搜索引擎+HDFS+MR完成垂直搜索》的基礎上,在數據收集之後的JSP/Servlet方面,換為SpringMVC框架來實現。

藉助SpringMVC技術完成資料庫、HDFS、頁面的交互,以達到實現垂直搜索引擎

本篇博客的思想:一是深入數據收集、分析、關鍵詞搜索呈現的流程實現;

        一是藉此實踐學習SpringMVC框架的技術。

首先簡單闡述實現垂直搜索引擎的流程:1‘網路爬蟲的數據存取到HDFS和資料庫中;

                   2’MR對數據進行分析規約;

                  3‘SpringMVC實現關鍵詞搜索並呈現到網頁(此處為本篇重點闡述)

----->

目錄:

1、SpringMVC闡述

2、創建web項目(添加Spring框架支持)

3、配置applicationContext.xml★★

4、配置web.xml文件★★

5、添加log4j.properties文件至src根目錄

6、實現DAO操作類 

7、修改頁面源碼

8、編寫控制器來自動接收參數,以及進行數據操作★★

9、過濾器解決亂碼問題

10、結果顯示

11、總結

------>

 

1、  SpringMVC闡述

SpringMVC是Spring的一個子框架,主要是用來處理MVC設計模式中的View和Control。

MVC:

Model:模型層,也就是資料庫操作層。DAO部分代碼

View:展示層,也就是頁面顯示部分。Servlet部分

Controller:控制層,也就是業務邏輯層。JSP部分

 

使用SpringMVC以後,這三部分代碼都會有改變,由Spring來進行調整。

企業用的最多的是SpringMVC + MyBatis。

這裡我們就只使用SpringMVC + JDBC來完成

 

Spring 在這三層可以有不同的作用:

Model層中Spring可以幫助進行數據源連接池的配置,還可以簡化JDBC的操作代碼,同時還能幫助完成自動的打開和關閉資料庫連接。

View層中,Spring可以幫助我們簡化表單提交的參數代碼,也可以自動接收Control中返回的數據信息。

Control層中,Spring可以幫助我們自動接收頁面提交的參數。

 

Spring的核心在於配置文件,所有的類的信息基本都要加入到配置文件中或使用Annotation來進行標註。

 

2、創建web項目(添加Spring框架支持)

【項目整體呈現】

 

創建一個新的web項目,導入上一篇項目所需的jar包,以及拷貝vo類(DAO介面類)和utils類(關鍵詞查詢類)所在的包

先為項目加入Spring的框架支持

在項目上點右鍵,選擇MyEclipse,然後找到install Spring … 的選項。

按照固定的步驟加入支持,最後一步時,一定要註意選擇好需要的支持庫,這裡必須用到的是Persistence和Web

 

 

3、配置applicationContext.xml

這個文件Spring的配置文件,主要是將各種POJO,JAVA,action配置到XML轉交給beanfactory管理,降低耦合度。


主要的配置組件:
<bean id="射影class的名字" class="寫的JAVA類"/>


然後就是這些<bean>之間的依賴關係,比如:
<bean id="mySerive" class="org.haha.MyServiceImpl"/>
<bean id="loginAction" class="org.haha.LoginAction" scope="prototype">
<!--依賴註入業務邏輯組件-->
<property name="ms" ref="myService" />
</bean>


以上代碼的意思會在loginAction的代碼里引用MyServiceImpl類,但是只需要用ms代替就可以
例如:
 public String execute() throws Exception{
    ms.sayhello();
}
正常情況應該 new MyServiceImpl,但是通過XML配置之後就直接用以上代碼就可以實現
new 的效果。

 

以下是該項目的配置文件呈現:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans
 3     xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xmlns:p="http://www.springframework.org/schema/p"
 6     
 7     xmlns:context="http://www.springframework.org/schema/context"
 8     xmlns:mvc="http://www.springframework.org/schema/mvc"
 9     
10     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
11             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
12             http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
13 
14     <!-- 加入SpringMVC的庫支持 -->
15     <mvc:annotation-driven></mvc:annotation-driven>
16     <!-- 加入Context支持 -->
17     <context:annotation-config></context:annotation-config>
18     <!-- 配置使用Annotation的包範圍 -->
19     <context:component-scan base-package="org.liky.sina.dao.impl,org.liky.sina.action"></context:component-scan>
20     
21     <!-- 配置資料庫連接池 -->
22     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
23         <property name="driverClassName" value="org.gjt.mm.mysql.Driver"></property>
24         <property name="url" value="jdbc:mysql://localhost:3306/sina_news"></property>
25         <property name="username" value="root"></property>
26         <property name="password" value="admin"></property>
27     </bean>
28     
29     <!-- 配置一個模板類 -->
30     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
31         <property name="dataSource">
32             <ref bean="dataSource"/>
33         </property>
34     </bean>
35     
36     <!-- 配置自動管理連接的一個事務操作支持 -->
37     <bean id="transactionManager"    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
38         <property name="dataSource">
39             <ref bean="dataSource"/>
40         </property>
41     </bean>
42     
43     
44     <bean    id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
45         <property name="transactionManager">
46             <ref bean="transactionManager"/>
47         </property>    
48     
49     <!-- 配置事務處理方式      *表示service中的所有方法都要進行事務處理。PROPAGATION_REQUIRED表示事務處理方式,有以下三種選擇:
50         PROPAGATION_REQUIRED:正常事務處理
51         PROPAGATION_REQUIRED_NEWS:每個操作單獨進行一個事務處理
52         PROPAGATION_REQUIRED_NEVER:不使用事務,出錯後後面的不進行添加
53      -->
54      
55      <property name="transactionAttributes">
56          <props>
57              <prop key="*">PROPAGATION_REQUIRED</prop>
58          </props>
59      </property>
60     
61     </bean>
62     
63     <!-- 配置事務管理器的作用範圍 -->
64     <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
65         <property name="interceptorNames">
66             <list>
67                 <value>transactionInterceptor</value>
68             </list>
69         </property>
70         <property name="beanNames">
71             <list>
72               <value>*DAOImpl</value>
73             </list>
74         </property>
75     </bean>
76     
77     
78         
79 </beans>

 

4、配置web.xml文件

  這個文件是需要在裡面讓伺服器啟動時,可以自動載入spring的配置文件。

  代碼呈現:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 5     id="WebApp_ID" version="3.0">
 6     <display-name>SinaNewsSpringMVC</display-name>
 7     <welcome-file-list>
 8         <welcome-file>index.html</welcome-file>
 9     </welcome-file-list>
10     <listener>
11         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
12     </listener>
13     <context-param>
14         <param-name>contextConfigLocation</param-name>
15         <param-value>classpath:applicationContext.xml</param-value>
16     </context-param>
17 
18     <!-- 手工配置載入SpringMVC的支持庫和跳轉路徑 -->
19     <servlet>
20         <servlet-name>springmvc</servlet-name>
21         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
22 
23         <init-param>
24             <param-name>contextConfigLocation</param-name>
25             <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
26         </init-param>
27         <load-on-startup>1</load-on-startup>
28     </servlet>
29     <servlet-mapping>
30         <servlet-name>springmvc</servlet-name>
31         <url-pattern>*.do</url-pattern>
32     </servlet-mapping>
33 
34     <!-- 添加過濾器 -->
35     <filter>
36         <filter-name>encoding</filter-name>
37         <filter-class>org.liky.sina.filter.EncodingFilter</filter-class>        
38     </filter>
39     <filter-mapping>
40         <filter-name>encoding</filter-name>
41         <url-pattern>/*</url-pattern>
42     </filter-mapping>
43 </web-app>

 

 5、添加log4j.properties文件至src根目錄

Log4j,Apache的一個開源項目,作用:

     可以控制日誌信息輸送的目的地是控制台、文件、GUI組件、甚至是套介面服務器、NT的事件記錄器、UNIXSyslog守護進程等;

       可以控制每一條日誌的輸出格式;

        通過定義每一條日誌信息的級別,我們能夠更加細緻地控制日志的生成過程。

     此外,這些可以通過一個配置文件來靈活地進行配置,而不需要修改應用的代碼。

 1 ### direct log messages to stdout ###
 2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 3 log4j.appender.stdout.Target=System.out
 4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 6 
 7 ### direct messages to file hibernate.log ###
 8 #log4j.appender.file=org.apache.log4j.FileAppender
 9 #log4j.appender.file.File=hibernate.log
10 #log4j.appender.file.layout=org.apache.log4j.PatternLayout
11 #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
12 
13 ### set log levels - for more verbose logging change 'info' to 'debug' ###
14 
15 log4j.rootLogger=warn, stdout
16 
17 log4j.logger.org.hibernate=info
18 #log4j.logger.org.hibernate=debug
19 
20 ### log HQL query parser activity
21 #log4j.logger.org.hibernate.hql.ast.AST=debug
22 
23 ### log just the SQL
24 #log4j.logger.org.hibernate.SQL=debug
25 
26 ### log JDBC bind parameters ###
27 log4j.logger.org.hibernate.type=info
28 #log4j.logger.org.hibernate.type=debug
29 
30 ### log schema export/update ###
31 log4j.logger.org.hibernate.tool.hbm2ddl=debug
32 
33 ### log HQL parse trees
34 #log4j.logger.org.hibernate.hql=debug
35 
36 ### log cache activity ###
37 #log4j.logger.org.hibernate.cache=debug
38 
39 ### log transaction activity
40 #log4j.logger.org.hibernate.transaction=debug
41 
42 ### log JDBC resource acquisition
43 #log4j.logger.org.hibernate.jdbc=debug
44 
45 ### enable the following line if you want to track down connection ###
46 ### leakages when using DriverManagerConnectionProvider ###
47 #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

 

 

6、實現DAO操作類 

之後啟動伺服器進行測試,如果啟動後沒有報錯,那就表示環境配置成功,可以正常使用。

下麵就開始編寫DAO操作。

對於DAO介面是沒有變化的,所以可以直接拷貝過來

這裡不需要再編寫工廠類,因為Spring可以自動幫助創建對象。

實現類需要交給Spring來進行管理和控制,並且簡化jdbc代碼操作

代碼如下:

 1 package org.liky.sina.dao.impl;
 2 
 3 import java.sql.ResultSet;
 4 import java.sql.SQLException;
 5 import java.util.List;
 6 
 7 import org.liky.sina.dao.INewsDAO;
 8 import org.liky.sina.vo.News;
 9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.jdbc.core.JdbcTemplate;
11 import org.springframework.jdbc.core.RowMapper;
12 import org.springframework.jdbc.core.support.JdbcDaoSupport;
13 import org.springframework.stereotype.Component;
14 
15 @Component
16 public class NewsDAOImpl extends JdbcDaoSupport implements INewsDAO,RowMapper<News> {
17 
18     @Autowired
19     public NewsDAOImpl(JdbcTemplate jdbcTemplate) {
20         super.setJdbcTemplate(jdbcTemplate);
21     }
22 
23 
24     public void doCreate(News news) throws Exception {
25         String sql="insert into news (id,title,description,url) values (?,?,?,?)";
26         
27         super.getJdbcTemplate().update(sql, news.getId(),news.getTitle(),news.getDescription(),news.getUrl());
28     }
29 
30     public News findById(int id) throws Exception {
31         String sql="select id,title,description,url from news where id=?";
32         News news=super.getJdbcTemplate().queryForObject(sql,new Object[]{id},this);    
33         
34         return news;
35     }
36 
37     public List<News> findByIds(Integer[] ids, int start, int pageSize)
38             throws Exception {
39         StringBuilder sql = new StringBuilder(
40                 "SELECT id,title,description,url FROM new_news WHERE id IN (");
41         if (ids != null && ids.length > 0) {
42             for (int id : ids) {
43                 sql.append(id);
44                 sql.append(",");
45             }
46             // 第一個 ? 表示開始的記錄數,第二個 ? 表示每頁顯示的記錄數。
47             String resultSQL = sql.substring(0, sql.length() - 1)
48                     + ") LIMIT ?,?";
49             List<News> allNews = super.getJdbcTemplate().query(resultSQL,
50                     new Object[] { start, pageSize }, this);
51             return allNews;
52         }
53         return null;
54     }
55     
56     
57     public int getAllCount(Integer[] ids)throws Exception{
58         StringBuilder sql=new StringBuilder("select count(id) from new_news where id in (");
59         
60         if(ids!=null&&ids.length>0){
61             for(int id:ids){
62                 sql.append(id);
63                 sql.append(",");
64             }
65             // 第一個 ? 表示開始的記錄數,第二個 ? 表示每頁顯示的記錄數。
66                 String resultSQL = sql.substring(0, sql.length() - 1) + ")";
67                 int count = super.getJdbcTemplate().queryForInt(resultSQL);                            
68                 return count;            
69         }        
70         return 0;
71     }
72     
73     public News mapRow(ResultSet rs, int arg1) throws SQLException {
74         News news=new News();
75         news.setId(rs.getInt(1));
76         news.setTitle(rs.getString(2));
77         news.setDescription(rs.getString(3));
78         news.setUrl(rs.getString(4));
79         return news;
80 
81     }
82 
83 }

 

7、修改頁面源碼

表單部分進行一些簡單的調整,加入了form標簽相關的配置。主要在action的值改為了search.do

【1】index.jsp修改

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%
 3 String path = request.getContextPath();
 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
 5 %>
 6 
 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 8 <html>
 9   <head>
10     <base href="<%=basePath%>">
11     <title>新浪新聞熱詞搜索</title>
12   </head>
13   
14   <body>
15     <center>
16         <form action="search.do" method="post">
17         請輸入查詢關鍵字:
18         <input type="text" name="keyword">
19         <input type="submit" value="查詢">       
20         </form>
21     </center> 
22   </body>
23 </html>

【2】result.jsp修改

 1 <%@page import="org.liky.sina.vo.News"%>
 2 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 3 <%
 4     String path = request.getContextPath();
 5     String basePath = request.getScheme() + "://"
 6             + request.getServerName() + ":" + request.getServerPort()
 7             + path + "/";
 8 %>
 9 
10 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
11 <html>
12 <head>
13 <base href="<%=basePath%>">
14 
15 <title>新浪新聞搜索</title>
16 </head>
17 
18 <body>
19     <center>
20         <%
21             List<News> allNews = (List<News>)request.getAttribute("allNews");
22         %>
23         <table width="80%">
24             <%
25                 for (News n : allNews) {
26             
27             %>
28                 <tr>
29                     <td>
30                         <a href="<%=n.getUrl() %>" target="_blank"><%=n.getTitle() %></a> <br>
31                         <%=n.getDescription() %>
32                         <hr/>
33                     </td>
34                 </tr>
35             <%
36                 }
37                 
38             %>
39         </table>
40         
41         <%
42             int cp = (Integer)request.getAttribute("currentPage");
43             int allPages = (Integer)request.getAttribute("allPages");
44         %>
45         <form id="split_page_form" action="search.do" method="post">
46             <input type="hidden"  name="currentPage" id="cp" value="<%=cp %>" />
47             <input type="button" <%=cp == 1?"disabled":"" %> value="首頁" onclick="changeCp(1);">
48             <input type="button" <%=cp == 1?"disabled":"" %> value="上一頁" onclick="changeCp(<%=cp - 1 %>);">
49             <input type="button" <%=cp == allPages?"disabled":"" %> value="下一頁" onclick="changeCp(<%=cp + 1 %>);">
50             <input type="button" <%=cp == allPages?"disabled":"" %> value="尾頁" onclick="changeCp(<%=allPages %>);">
51             第 <%=cp %>  頁 / 共 <%=allPages %>52             <br>
53             請輸入查詢關鍵字:<input type="text" name="keyword" value="<%=request.getParameter("keyword")%>">
54             <input type="submit" value="查詢">
55         </form>
56         <script type="text/javascript">
57             function changeCp(newcp) {
58                 // 改變當前頁數
59                 document.getElementById("cp").value = newcp;
60                 // 提交表單
61                 document.getElementById("split_page_form").submit();
62             }
63         </script>
64         
65     </center>
66 </body>
67 </html>

 

8、編寫控制器來自動接收參數,以及進行數據操作

之後需要編寫SpringMVC的控制器來自動接收參數,併進行數據操作。

代碼呈現:

 1 package org.liky.sina.action;
 2 
 3 import java.util.List;
 4 
 5 import javax.annotation.Resource;
 6 
 7 import org.liky.sina.dao.INewsDAO;
 8 import org.liky.sina.utils.HDFSUtils;
 9 import org.liky.sina.vo.News;
10 import org.springframework.stereotype.Controller;
11 import org.springframework.web.bind.annotation.RequestMapping;
12 import org.springframework.web.bind.annotation.RequestParam;
13 import org.springframework.web.servlet.ModelAndView;
14 
15 
16 @Controller
17 public class NewsAction {
18     private INewsDAO newsdao;
19     
20     @RequestMapping(value="/search.do")
21     public ModelAndView search(@RequestParam String keyword,@RequestParam(defaultValue="1") int currentPage){
22         ModelAndView mv= new ModelAndView();
23         //一頁顯示10條數據
24         int pageSize=10;
25         
26         try{
27             Integer[] ids=HDFSUtils.getIdsByKeyword(keyword);
28             //根據這些id查詢相應的結果
29             List<News> allNews=newsdao.findByIds(ids, (currentPage-1), pageSize);
30             
31             int count=newsdao.getAllCount(ids);
32             //計算一個關鍵詞讀取的數據顯示總頁數
33             int allPages=count/pageSize;
34             if(count%pageSize!=0){
35                 allPages++;
36             }
37             
38             //結果傳遞迴頁面顯示
39             mv.addObject("allNews",allNews);
40             mv.addObject("allPages", allPages);
41             mv.addObject("currentPage", currentPage);
42             
43             //切換到頁面上
44             mv.setViewName("/result.jsp");                                    
45         }catch(Exception e){
46             e.printStackTrace();
47         }
48         
49         return mv;
50     }
51     
52     @Resource(name="newsDAOImpl")
53     public void setNewsdao(INewsDAO newsdao){
54         this.newsdao=newsdao;
55         
56     }
57 }

 

 

9、過濾器解決亂碼問題

測試時會有亂碼出現,因此還要編寫一個過濾器來處理亂碼。

如果是MyEclipse的亂碼問題,只需修改:

 

 【1】過濾器代碼呈現:

 1 package org.liky.sina.filter;
 2 /**
 3  * 過濾器,解決網頁亂碼的問題
 4  */
 5 import java.io.IOException;
 6 
 7 import javax.servlet.Filter;
 8 import javax.servlet.FilterChain;
 9 import javax.servlet.FilterConfig;
10 import javax.servlet.ServletException;
11 import javax.servlet.ServletRequest;
12 import javax.servlet.ServletResponse;
13 
14 public class EncodingFilter implements Filter {
15 
16     @Override
17     public void destroy() {
18     }
19 
20     @Override
21     public void doFilter(ServletRequest arg0, ServletResponse arg1,
22             FilterChain arg2) throws IOException, ServletException {
23         //修改編碼格式為UTF-8
24         arg0.setCharacterEncoding("UTF-8");
25         arg2.doFilter(arg0, arg1);
26     }
27 
28     @Override
29     public void init(FilterConfig arg0) throws ServletException {
30         // TODO Auto-generated method stub
31 
32     }
33 
34 }

 

 

【2】在web.xml中配置這個過濾器:

1 <filter>
2         <filter-name>encoding</filter-name>
3         <filter-class>org.liky.sina.filter.EncodingFilter</filter-class>
4     </filter>
5     <filter-mapping>
6         <filter-name>encoding</filter-name>
7         <url-pattern>/*</url-pattern>
8     </filter-mapping>

 

 

10、結果顯示

關於其他的代碼在參考《Lucene搜索引擎+HDFS+MR完成垂直搜索》。

運行結果如下:

 控制台顯示:

 

瀏覽器index.jsp顯示:

 

搜索結果   result.jsp  顯示,尾部實現了分頁功能,並且還可以進行搜索:

 

 

11、總結

    首先上一篇結尾存在的亂碼問題在此處第九部分,給出了過濾器的方法,將編碼格式改為UTF-8,已經解決了。

  關於垂直搜索引擎,是針對某一個行業的專業搜索引擎(本次項目是對新浪新聞的數據收集,爬取深度為5),是搜索引擎的細分和延伸,是對網頁庫中的某類專門的信息進行一次整合,定向分欄位抽取出需要的數據進行處理後再以某種形式返回給用戶。

  本篇用SpringMVC框架的技術完成數據的垂直搜索,相比來說,結構更加清晰,難點在於兩個配置文件的修改,以及在代碼中使用配置文件

  思路流程:

    1、  DAO操作類根據首頁搜索框關鍵詞的輸入,獲取HDFS的id,以便從資料庫提取一組信息;

    2、  配置文件實現了資料庫的連接,並簡化了DAO的流程實現;

    3、  SpringMVC的控制器自動接收參數,併進行數據操作;

    4、  JSP文件接收控制器傳遞的數據,呈現在結果頁面。

 

  

 

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 概述 bootstrap開發標簽頁時,標簽頁顯示正常,但點擊時候對應內容區域沒有變化。 具體癥狀與解決方案 1.標簽頁UI出現,但點擊無反應,標簽頁UI並未隨點擊進行切換 先檢查bootstrap.css,jQuery.js和bootstrap.js是否有正確引入,並保證引入順序jQuery在前,b ...
  • 一、JavaScript基礎 1、JavaScript用法: HTML 中的腳本必須位於 <script> 與 </script> 標簽之間。 腳本可被放置在 HTML 頁面的 <body> 和 <head> 部分中。 HTML引入外部js文件方法示例: <!DOCTYPE html> <html> ...
  • 俗話說不打無準備之仗,這次真是有點懵逼了,建議大家去面試的時候,尤其是去小型互聯網公司的時候,如果你想比其他人有競爭力,那麼你要研究一下當前他的公司正在開發產品,他們的業務類型是什麼樣的,比如他們公司正在開發xxxApp,你可以花費兩天時間,做一個xxxApp的demo,等去面試的時候,你就可以有底 ...
  • React Native使用props來實現頁面間數據傳遞和通信。在React Native中,有兩種方式可以存儲和傳遞數據:props(屬性)以及state(狀態) ...
  • 簡書地址:http://www.jianshu.com/p/1c288440754d demo地址:https://github.com/Brances/ZMProject ...
  • 對UIbutton的簡單使用(基本上足夠了),話不多說,直接看 UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom]; /* UIButtonTypeCustom = 0, //自定義風格 UIButtonTypeSyst ...
  • 一,代碼。 二,輸出。 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //2015-09-16格式 NSDate ...
  • 1 MySQL學習路線 基礎階段:MySQL資料庫的基本操作(增刪改查),以及一些高級操作(視圖、觸發器、函數、存儲過程等)。 優化階段:如何提高資料庫的效率,如索引,分表等。 部署階段:如何搭建真實的環境系統,如伺服器集群,負載均衡等。 2 資料庫的基礎 2.1 什麼是資料庫? 資料庫:datab ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...