Java框架之Spring(五)

来源:https://www.cnblogs.com/1693977889zz/archive/2017/12/31/8158840.html
-Advertisement-
Play Games

本文主要介紹Spring中, 1 Spring JDBC 2 使用註解方式管理事務的傳播行為 3 採用XML 方式配置事務 4 SH 整合 5 SSH 整合 一、Spring JDBC 1) 導包 , 使用myeclipse2014, 添加與持久化相關的包 2) 引入名稱空間等 3) 配置數據源 4 ...


本文主要介紹Spring中,

1 Spring JDBC

2 使用註解方式管理事務的傳播行為

3 採用XML 方式配置事務

4 SH 整合

5 SSH 整合

一、Spring JDBC

1) 導包 , 使用myeclipse2014, 添加與持久化相關的包

2) 引入名稱空間等

3) 配置數據源

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!-- 單實例bean -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shop?useUnicode=true&amp;characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>      
<property name="initialSize" value="10"/>   <!-- 連接池啟動時的初始值 -->        
<property name="maxActive" valu3) e="300"/>    <!-- 連接池的最大值 -->
<property name="maxIdle" value="5"/> <!-- 最大空閑值.當經過一個高峰時間後,連接池可以慢慢將已經用不到的連接慢慢釋放一部分,一直減少到maxIdle為止 -->
<property name="minIdle" value="3"/> <!-- 最小空閑值.當空閑的連接數少於閥值時,連接池就會預申請去一些連接,以免洪峰來時來不及申請 -->
</bean>

4) dao層

@Repository("userDaoImpl")
public class UserDaoImpl {
       private JdbcTemplate jdbcTemplate; //用於進行資料庫操作的模板,線程安全的
                    
       @Resource
       public void setDataSource(DataSource dataSource){
                   this.jdbcTemplate=new JdbcTemplate(dataSource);
                    }
                    
       //添加
       public int addUser(UserInfo user){
                        String sql="insert into userInfo (userName,password,note) values(?,?,?)" ;
                        Object[] paramList={user.getUserName(),user.getPassword(),user.getNote()};        
                        
       //也可以不用定義數組,直接這樣寫 :return  jdbcTemplate.update(sql, user.getUserId(),user.getUserName(),user.getPassword(),user.getNote());
                        return  jdbcTemplate.update(sql, paramList);
                    }
                    
       //刪除
       public int delUser(int id){
       String sql="delete from userInfo where id=?";
       Object[] paramList={id};
                        return jdbcTemplate.update(sql, paramList);        
                    }
                    
       //修改
       public int update(UserInfo user){
                        String sql="update userInfo set userName=?,password=?, note=? where id=?";
                        Object[] paramList={user.getUserName(),user.getPassword(),user.getNote(),user.getId()};    
                        return jdbcTemplate.update(sql, paramList);        
                    }
                    
       //查詢
       public UserInfo getUserById(int id){
                        String sql="select * from userInfo where id=?"; //註意:如果查詢結果多於一條,將報異常
                        Object[] paramList={id};
                        Object user=jdbcTemplate.queryForObject(sql, paramList, new BeanPropertyRowMapper(UserInfo.class));
                        return (UserInfo)user;    
                    }
                    
       //查詢出列表
       public List<UserInfo>getUserList(){
                        String sql="select * from userInfo";
                        return (List<UserInfo>)jdbcTemplate.query(sql,new BeanPropertyRowMapper(UserInfo.class));
                    }
                    
       //查詢出單個Int值
       public int getUserCount(){
                        String sql="select count(*) from userInfo";
                        return jdbcTemplate.queryForInt(sql);        
                    }
                    
       //只查詢一個欄位
       public String getUserName(int id){
                        String sql="select userName from userInfo where id= "+id;
                        return (String)jdbcTemplate.queryForObject(sql, String.class); //因為要查詢的欄位是String型的,所以在這裡用 String.class
                    }
                    
       //返回map 
       public Map getUserMapData(int id){
                        String sql="select * from  userInfo where id="+id;
                        return jdbcTemplate.queryForMap(sql);    
                    }
                    
       //添加一個用戶,返回其ID
       public void addUser2(final UserInfo user){ //註意,這裡必須用 final
                        jdbcTemplate.execute(new ConnectionCallback<Object>() { //org.springframework.jdbc.core.包下的 ConnectionCallback
                            @Override                                                        
                            public Object doInConnection(Connection conn) throws SQLException,DataAccessException {
                            
                                String sql="insert into userInfo (userName,password,note) values(?,?,?)" ;
                                PreparedStatement stm=conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
                                stm.setString(2, user.getUserName());
                                stm.setString(3, user.getPassword());
                                stm.setString(4, user.getNote());
                                
                                stm.executeUpdate();
                                ResultSet rs=stm.getGeneratedKeys();
                                
                                if(rs.next()){
                                    System.out.println("新添加的用戶的主鍵是:"+rs.getInt(1));
                                }            
                                return null;
                            }
                        });        
                    }
                
        //拿到自增主鍵的另一個方法,來自幫助文檔
        public void ttt(){
                        KeyHolder keyHolder = new GeneratedKeyHolder();
                        jdbcTemplate.update(
                            new PreparedStatementCreator() {
                                public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                                    PreparedStatement ps = connection.prepareStatement("insert into my_test (name) values(?)", new String[] {"id"});
                                    ps.setString(1, "張三");
                                    return ps;
                                }
                            },
                            keyHolder);
                        keyHolder.getKey();  //這就是拿到的自增主鍵
                    }
                    
                }

 5) 測試用例

public class UserDaoImplTest {
                private static  ClassPathXmlApplicationContext ctx;
                private static UserDaoImpl  dao;
                
                @BeforeClass
                public static void setUpBeforeClass() throws Exception {
                    ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
                    dao=(UserDaoImpl)ctx.getBean("userDaoImpl");
                }
            
                @Before
                public void setUp() throws Exception {
                }
            
                @Test
                public void testAddUser() {
                    UserInfo user=new UserInfo();
                    user.setUserName("趙明明");
                    user.setPassword("忘了");
                    user.setNote("又想起來了");    
                
                    dao.addUser(user);
                    
                    System.out.println("-----------嘻嘻---------------");
            
                }
            
                @Test
                public void testDelUser() {
                    int result=dao.delUser(196611);
                    System.out.println(result);
                }
            
                @Test
                public void testUpdate() {
                    UserInfo user=new UserInfo();
                    user.setId(196610);
                    user.setUserName("費無極");
                    user.setPassword("大費費");
                    user.setNote("中小型費費");        
                
                    int result=dao.update(user);
                    System.out.println(result);
                }
            
                @Test
                public void testGetUserById() {
                    UserInfo user=dao.getUserById(196609);
                    System.out.println(user.getNote());
                }
                
            
                @Test
                public void testGetUserList() {
                    List<UserInfo>userList=dao.getUserList();
                    for(UserInfo u:userList){
                        System.out.println(u.getUserName());        
                    }
                }
            
                @Test
                public void testGetUserCount() {
                    int result=dao.getUserCount();
                    System.out.println(result);
                }
            
                @Test
                public void testGetUserName() {
                    String userName=dao.getUserName(491553);
                    System.out.println(userName);
                }
            
                @Test
                public void testGetUserMapData() {
                    Map userMap=dao.getUserMapData(2);
                    
                    Set<Map.Entry>entrySet=userMap.entrySet();
                    Iterator <Map.Entry>it=entrySet.iterator();
                    while(it.hasNext()){
                        Map.Entry item=it.next();
                        System.out.println(item.getKey()+"---"+item.getValue());
                    }
                }
            
                @Test
                public void testAddUser2() {
                    UserInfo user=new UserInfo();
                    user.setUserName("奧八馬");
                    user.setPassword("小狒狒");
                    user.setNote("超級小狒狒");            
                    dao.addUser2(user);
                }
            
                @Test
                public void testTtt() {
                    
                }

二、使用註解方式管理事務的傳播行為

//刪除
public int delUser(int id){
                String sql="delete from userInfo where id=?";
                Object[] paramList={id};
                int result= jdbcTemplate.update(sql, paramList);    
                
                int a=90/0;  //如果程式在這裡出現異常,會不會回滾,預設情況下,不回滾
                return result;
            }

在spring中開啟事務管理

1)要加入相應的名稱空間

xmlns:tx="http://www.springframework.org/schema/tx"
                ...
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd

2) 配置事務管理器

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource" ref="dataSource" />
</bean>
                
<!-- 使用註解的方式管理事務(不使用註解,不用加這句) -->
<tx:annotation-driven transaction-manager="txManager"/>

3) 在要進行事務管理的類上,用註解聲明

@Transactional @Repository("userDaoImpl")
public class UserDaoImpl {
       public int delUser(int id){
                         String sql="delete from userInfo where id=?";
                         Object[] paramList={id};
                         int result= jdbcTemplate.update(sql, paramList);    
                                        
                         int a=90/0;  //如果程式在這裡出現異常,會不會回滾,由於聲明瞭事務,所以會回滾
                         return result;
                                    }
                                    
                                    ...
                          }
                          
//對這個方法進行細粒度的控制 
@Transactional(noRollbackFor=RuntimeException.class) 
public void delAllUser(){
                         String sql="delete from userInfo ";
                         jdbcTemplate.execute(sql);
                         throw new RuntimeException(發生了運行時異常);
                         
                        }

這段代碼要刪除所有用戶,但運行時拋出了異常,所以事務會回滾,數據不會被刪除,可以更改這種行為,在方法前加上註解。

@Transactional(noRollbackFor=RuntimeException.class)  表示出了異常也不回滾。

有的方法比如查詢方法,不需要事務,可以在該方法上指定。

@Transactional(propagation=Propagation.NOT_SUPPORTED)  //加上以後,這個方法就不再支持事務了
public List<UserInfo>getUserList(){
                            String sql="select * from userInfo";
                            return (List<UserInfo>)jdbcTemplate.query(sql,new BeanPropertyRowMapper(UserInfo.class));
                        }

事務的傳播行為

----REQUIRED:業務方法需要在一個事務中運行。如果方法運行時,已經處在一個事務中,那麼加入到該事務,否則為自己創建一個新的事務。

----NOT_SUPPORTED:聲明方法不需要事務。如果方法沒有關聯到一個事務,容器不會為它開啟事務。如果方法在一個事務中被調用,該事務會被掛起,在方法調用結束後,原先的事務便會恢復執行。

----REQUIRESNEW:(requiresnew) 屬性表明不管是否存在事務,業務方法總會為自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務會被掛起,新的事務會被創建,直到方法執行結束,新事務才算結束,原先的事務才會恢復執行。

----MANDATORY (mandatory,強制的,命令的,受委托的):該屬性指定業務方法只能在一個已經存在的事務中執行,業務方法不能發起自己的事務。 如果業務方法在沒有事務的環境下調用,容器就會拋出例外。

----SUPPORTS:這一事務屬性表明,如果業務方法在某個事務範圍內被調用,則方法成為該事務的一部分。如果業務方法在事務範圍外被調用,則方法在沒有事務的環境下執行。

----Never:指定業務方法絕對不能在事務範圍內執行。如果業務方法在某個事務中執行,容器會拋出例外,只有業務方法沒有關聯到任何事務,才能正常執行。

----NESTED:nested (窩,嵌套)如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務, 則按REQUIRED屬性執行.它使用了一個單獨的事務, 這個事務擁有多個可以回滾的保存點。

內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效。

REQUIRED 是預設的 ,比如

//這裡什麼都不寫,相當於寫上 @Transactional(propagation=Propagation.REQUIRED)
public int delUser(int id){
                          String sql="delete from userInfo where id=?";
                          Object[] paramList={id};
                          int result= jdbcTemplate.update(sql, paramList);    
                                
                          int a=90/0;  //如果程式在這裡出現異常,會不會回滾
                          return result;
            
public void testTx(UserInfo user){
                          jdbcTemplate.update("delete from userInfo where id=1");
                          addUser(user);
                          jdbcTemplate.update("delete from userInfo where id=2");
                          //int x=0/0;
                          }

說明:

對於這個例子來說,沒有指明事務的傳播行為,所以這是預設的 @Transactional(propagation=Propagation.REQUIRED)。

對於 addUser 來說,如果如果方法運行時,已經處在一個事務中,則它將加入這個事務。所以,上面的操作,將會成為一個整體。

三、採用XML 方式配置事務

<aop:config>
<aop:pointcut id="myTxPointCut" expression="execution(* cat.dao.UserDaoImpl_other.*(..))" />
<aop:advisor advice-ref="txAdvisor"  pointcut-ref="myTxPointCut" />
</aop:config>
                
<tx:advice id="txAdvisor" transaction-manager="txManager" >
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>

用XML配置的方式,就不用再寫

<tx:annotation-driven transaction-manager="txManager"/>
                 @Repository("userDaoImpl_other")
                public class UserDaoImpl_other {
                    ....
                    public void testTx(UserInfo user){
                        jdbcTemplate.update("delete from userInfo where id=5");
                        addUser(user);
                        jdbcTemplate.update("delete from userInfo where id=6");
                        
                        int x=0/0;
                    }
    
                    
                public static void main(String[] args) {
                    ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
                    UserDaoImpl_other dao=(UserDaoImpl_other)ctx.getBean("userDaoImpl_other");
                    
                    UserInfo user=new UserInfo();
                    user.setUserName("9999999999999");
                    user.setPassword("小狒狒");
                    user.setNote("超級小狒狒");    

                    dao.testTx(user);
                    
                }
    
            }

四、SH 整合

1) 導入名稱空間

<beans xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xmlns:context="http://www.springframework.org/schema/context"
                    xmlns:tx="http://www.springframework.org/schema/tx"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

2) 打開掃描

<context:component-scan base-package="cat" />

3) 配置 DataSource  //hibernate用的

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
       <property name="url" value="jdbc:mysql://localhost:3306/production?useUnicode=true&amp;characterEncoding=UTF-8"/>
       <property name="username" value="root"/>
       <property name="password" value="root"/>
       <property name="initialSize" value="10"/> 連接池啟動時的初始值 
       <property name="maxActive" value="500"/> 連接池的最大值 
       <property name="maxIdle" value="2"/> 最大空閑值.當經過一個高峰時間後,連接池可以慢慢將已經用不到的連接慢慢釋放一部分,一直減少到maxIdle為止
       <property name="minIdle" value="3"/> 最小空閑值.當空閑的連接數少於閥值時,連接池就會預申請去一些連接,以免洪峰來時來不及申請
</bean>

4) 配置SessionFactory //hibernate用的

/*
   sessionFactory 建議做成單例
   LocalSessionFactoryBean  除了可建一個 sessionFactory 對象出來,把它做成單例,還專門用於集成
   Hibernate ,用於做一些額外的工作,比如接管hibernate的事務
*/
<bean id="sessionFactory"  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >  
<property name="dataSource">
<ref bean="dataSource" />
</property>
                        
<property name="mappingResources">
          <list>
               <value>cat/beans/UserInfo.hbm.xml</value>
          </list>
</property>
                        
<property name="hibernateProperties">
          <value>
                  hibernate.dialect=org.hibernate.dialect.MySQLDialect
                  hibernate.hbm2ddl.auto=update
                  hibernate.show_sql=true
                  hibernate.format_sql=true
                        
//配置二級緩存用的
// hibernate.cache.use_second_level_cache=true
// hibernate.cache.use_query_cache=false //是否使用查詢緩存 因為它的效率比較差,所以不用
// hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider //指定的緩存產品 要導入 lib\optional\ejcacje -1-1-3/jar
          </value>
</property>
</bean>

5) 配置事務管理器 txManager

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
            
<tx:annotation-driven transaction-manager="txManager"/>  如果要用註解方式管理事務,要加這個配置

五、SSH 整合

再和 struts2 進行整合

1) 在web.xml 中 對Spring容器進行初始化

//指定spring 的配置文件,預設從web根目錄尋找配置文件,可以通過string 提供的classpath:首碼指定從類路徑下尋找 
<context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:beans.xml</param-value>  如果配置多個配置文件,可以用逗號隔開
</context-param>
// 對spring 容器進行實例化  ,實例化後,這個實例會放在applicateion 範圍-->
         <listener>
         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
         </listener>

2) 在web.xml中添加struts2應用

 <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>杠*</url-pattern>
</filter-mapping>

3) 在類路徑下添加 sruts.xml 文件

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
          "http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.objectFactory" value="spring" />  //聲明要用spring來創建 action 類
                    
          <package name="p_user" namespace="" extends="struts-default">
                   <action name="userAction_name" class="userAction">
                                <result name="success">/main.jsp</result>
                   </action>  
          </package>    
</struts>  

4) Action 類

@Controller
public class UserAction {
@Resource(name="userDaoImpl")
                        private IUserDao dao;
                        public String execute(){
                            UserInfo user=new UserInfo();
                            user.setUserName("SSH整合成功");
                            dao.addUser(user);
                            return "success";
                        }
                    }

5)介面

public interface IUserDao {
                    void addUser(UserInfo user) ;
                    
                    void delUser(int id) ;
                    
                    UserInfo getUserById(int id);
                    
                    List<UserInfo>getUserList();
                    
                    void updateUser(UserInfo user);
                    
                    void deleteUser(UserInfo user);
                }

6)實現類

@Transactional @Repository
                    public class UserDaoImpl implements IUserDao{
                        @Resource //這個註解預設是按名稱註入
                        private SessionFactory sessionFactory;
                    
                        public void addUser(UserInfo user) {
                            //Session s=sessionFactory.openSession();
                            //它得到的是spring容器管理的session
                            Session s=sessionFactory.getCurrentSession();
                            s.save(user);
                        }
                    
                        public void delUser(int id) {
                            Session s=sessionFactory.getCurrentSession();
                            UserInfo user=(UserInfo)s.get(UserInfo.class, id); 
                            s.delete(user);  //先查一下,再刪除
                        }
                    
                        @Transactional(propagation=Propagation.NOT_SUPPORTED)
                        public UserInfo getUserById(int id) {
                            Session s=sessionFactory.getCurrentSession();
                            return (UserInfo)s.get(UserInfo.class, id);
                        }
                    
                        @Transactional(propagation=Propagation.NOT_SUPPORTED)
                        public List<UserInfo> getUserList() {
                            Session s=sessionFactory.getCurrentSession();
                            return s.createQuery("from UserInfo").list();
                        }
                    
                        public void updateUser(UserInfo user) {
                            Session s=sessionFactory.getCurrentSession();
                            s.saveOrUpdate(user);
                        }
                    
                        public void deleteUser(UserInfo user) {
                            Session s=sessionFactory.getCurrentSession();
                            s.delete(user); 
                        }
                    
                    }

附 如何知道一個類在哪個jar包中

ctl + shift + t

附 關於被Spring 管理的 dao 使用介面訪問的問題

Spring的文檔中這麼寫的:Spring AOP部分使用JDK動態代理或者CGLIB來為目標對象創建代理,如果被代理的目標對象實現了至少一個介面,則會使用JDK動態代理。所有該目標類型實現的介面都將被代理。若該目標對象沒有實現任何介面,則創建一個CGLIB代理。使用beanNameAutoProxyCreator來進行事務代理的話,他的proxyTargetClass這個屬性設置為false(預設是false),即使用JDK動態代理,如果你的service類沒有實現介面的話,就會報類型轉換錯誤。

解決辦法有:

1、給service類添加一個介面iService,讓service類實現它,則創建代理類時使用JDK動態代理就不會出現問題

2、設置beanNameAutoProxyCreator的proxyTargetClass屬性為true,意思是強制使用CGLIB代理,前提是你已經將CGLIB包加入到項目中。

其實,就是 在配置文件中配置:

<aop:aspectj-autoproxy proxy-target-class="true"/>

但要註意:

需要導入 cglib-nodep-2.2.jar (它可以從myeclipse 自動生成的 Spring 項目中獲得),還要導入 aspectj 相關的幾個jar包。


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

-Advertisement-
Play Games
更多相關文章
  • ##importlogginglogging.debug('debug message')logging.info('info message')logging.warning('warning message') # WARNING:root:warning messagelogging.erro ...
  • 註意迭代器和可迭代對象不同#迭代器:1、有iter方法,2、有next方法li=[1,2,3,4,5]d=iter(li) # 等於li.__iter__()print(d) # <list_iteratorobjectat0x00000174316CC3C8>可以通過next方法取出元素。for循 ...
  • 要讀取鍵盤輸入的數據,需要使用輸入流,可以是位元組輸入流,也可以是位元組輸入流轉換後的字元輸入流。 關於鍵盤輸入,有幾點註意的是:(1).鍵盤輸入流為System.in,其返回的是InputStream類型,即位元組流。(2).位元組流讀取鍵盤的輸入時,需要考慮回車符(\r:13)、換行符(\n:10)。( ...
  • 再有兩天就進入2018了,想想還是要準備一下明年的工作方向。回想當初開始學習函數式編程時的主要目的是想設計一套標準API給那些習慣了OOP方式開發商業應用軟體的程式員們,使他們能用一種接近傳統資料庫軟體編程的方式來實現多線程,並行運算,分散式的數據處理應用程式,前提是這種編程方式不需要對函數式編程語 ...
  • 一、Spring簡介 Spring MVC是當前最優秀的 MVC 框架,自從Spring 2.5 版本發佈後,由於支持註解配置,易用性有了大幅度的提高。Spring 3.0 更加完善,實現了對 Struts 2 的超越。現在越來越多的開發團隊選擇了Spring MVC。 1)Spring3 MVC使 ...
  • 除之前的Spring相關包,還有structs2包外,還需要Hibernate的相關包 首先,Spring整合其他持久化層框架的JAR包 spring-orm-4.2.4.RELEASE.jar (整合Hibernate的) 這個JAR包在Spring框架中包含 Hibernate 需要的JAR包 ...
  • 為什麼需要泛型? 試想你需要一個簡單的容器類,或者說句柄類,比如要存放一個蘋果的籃子,那你可以這樣簡單的實現: 這樣一個簡單的籃子就實現了,但問題是它只能存放蘋果,之後又出現了另外的一大堆水果類,那你就不得不為這些水果類分別實現容器: 然後你發現你其實在做大量的重覆勞動。所以你幻想你的語言編譯器要是 ...
  • 1 兩種文本編輯器:Sublime Text 、 Notepad++ 執行python文件,在命令行中,切換到該Python文件所在的目錄下,然後輸入 Python ###.py命令就可以了。 2 Python的交互模式和直接運行.py文件有什麼區別呢? 直接輸入python進入交互模式,相當於啟動 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...