亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
整體專案結(jié)構(gòu)" >整體專案結(jié)構(gòu)
##%%PRE_BLOCK_4%%" >##%%PRE_BLOCK_4%%
%%PRE_BLOCK_5%%另外一個(gè)基本上一樣,就是掃描路徑改成:%%PRE_BLOCK_6%%" >%%PRE_BLOCK_5%%另外一個(gè)基本上一樣,就是掃描路徑改成:%%PRE_BLOCK_6%%
#mapper.xml%%PRE_BLOCK_7%%" >#mapper.xml%%PRE_BLOCK_7%%
對(duì)應(yīng)mapper介面也非常簡(jiǎn)單,貼出一個(gè):%%PRE_BLOCK_8%%" >對(duì)應(yīng)mapper介面也非常簡(jiǎn)單,貼出一個(gè):%%PRE_BLOCK_8%%
首頁(yè) Java java教程 Spring Boot+MyBatis+Atomikos+MySQL(附源碼)

Spring Boot+MyBatis+Atomikos+MySQL(附源碼)

Aug 15, 2023 pm 04:12 PM
mysql spring boot mybatis

我們?cè)趯?shí)際專案中,盡量規(guī)避分散式交易。 但是,有些時(shí)候是真的需要做一些服務(wù)拆分從而會(huì)引出分散式事務(wù)問(wèn)題。

同時(shí),分散式事務(wù)也是面試中市場(chǎng)被問(wèn)到,可以拿著這個(gè)案例練練手,面試就可以說(shuō)上個(gè)123了。

這裡舉個(gè)業(yè)務(wù)栗子:用戶領(lǐng)取優(yōu)惠券,需要扣減用戶領(lǐng)取次數(shù),然後記錄一個(gè)用戶領(lǐng)取優(yōu)惠券記錄。

Spring Boot+MyBatis+Atomikos+MySQL(附源碼)
拆分前
Spring Boot+MyBatis+Atomikos+MySQL(附源碼)

#原本這裡可以使用訊息佇列方式,採(cǎi)用非同步化去新增使用者領(lǐng)取記錄。但是,這裡需求是就是需要用戶領(lǐng)完立刻就能查看到自己的領(lǐng)取記錄,那我們這裡就引入了Atomikos來(lái)實(shí)現(xiàn)分散式事務(wù)問(wèn)題。

分散式交易

#分散式交易是指跨越多個(gè)電腦或資料庫(kù)的事務(wù),這些電腦或資料庫(kù)之間可能存在網(wǎng)路延遲、故障或不一致的情況。分散式事務(wù)需要確保所有操作的原子性、一致性、隔離性和持久性,以確保資料的正確性和完整性。

分散式事務(wù)協(xié)定有哪些?

分散式事務(wù)協(xié)定主要有兩種:2PC(Two-Phase Commit)和3PC(Three-Phase Commit)。

2PC是目前最常用的分散式事務(wù)協(xié)議,其流程分為兩個(gè)階段:準(zhǔn)備階段和提交階段。在準(zhǔn)備階段,事務(wù)協(xié)調(diào)者向所有參與者發(fā)出準(zhǔn)備請(qǐng)求,參與者將本地事務(wù)執(zhí)行到prepare狀態(tài),並將prepare結(jié)果回傳給事務(wù)協(xié)調(diào)者。在提交階段,如果所有參與者都執(zhí)行成功,則事務(wù)協(xié)調(diào)者向所有參與者發(fā)出提交請(qǐng)求,參與者將本地事務(wù)提交,否則事務(wù)協(xié)調(diào)者向所有參與者發(fā)出回滾請(qǐng)求,參與者將本地事務(wù)回滾。

3PC是2PC的改良版,其在2PC的基礎(chǔ)上增加了一個(gè)準(zhǔn)備提交階段。在準(zhǔn)備提交階段,協(xié)調(diào)者向參與者詢問(wèn)是否可以提交,如果參與者返回同意,則在提交階段直接提交,否則在提交階段回滾。

分散式交易常見解決方案有哪些?

分散式事務(wù)解決方案有:

  • #基於訊息佇列的分散式事務(wù)方案(如RocketMQ的開源方案)
  • 基於分散式事務(wù)框架的分散式事務(wù)方案(如Seata、TCC-Transaction等框架)
  • 基於XA協(xié)定的分散式事務(wù)方案(如JTA等)
  • 基於可靠訊息最終一致性的分散式事務(wù)方案(如阿里巴巴的分散式事務(wù)中間件GTS)
  • 基於CAP原理的分散式事務(wù)方案(如CQRS架構(gòu)中的事件溯源模式)

什麼是JTA ?

JTA(Java Transaction API),是J2EE的程式介面規(guī)範(fàn),它是XA協(xié)定的JAVA實(shí)作。它主要定義了:

一個(gè)事務(wù)管理器的介面javax.transaction.TransactionManager,定義了有關(guān)事務(wù)的開始、提交、撤回等>操作。

一個(gè)符合XA規(guī)範(fàn)的資源定義介面javax.transaction.xa.XAResource,一個(gè)資源如果要支援JTA事務(wù),就需要讓它的資源實(shí)作該XAResource接口,並實(shí)作該接口定義的兩階段提交相關(guān)的接口。 如果我們有一個(gè)應(yīng)用,它使用JTA介面實(shí)現(xiàn)事務(wù),應(yīng)用在運(yùn)行的時(shí)候,就需要一個(gè)實(shí)作JTA的容器,一般情況下,這是一個(gè)J2EE容器,像JBoss,Websphere等應(yīng)用伺服器。

但是,也有一些獨(dú)立的框架實(shí)作了JTA,例如Atomikos, bitronix都提供了jar包方式的JTA實(shí)作框架。這樣我們就能夠在Tomcat或Jetty之類的伺服器上運(yùn)行使用JTA實(shí)作事務(wù)的應(yīng)用系統(tǒng)。

在上面的本地事務(wù)和外部事務(wù)的區(qū)別中說(shuō)到,JTA事務(wù)是外部事務(wù),可以用來(lái)實(shí)現(xiàn)對(duì)多個(gè)資源的事務(wù)性。它正是透過(guò)每個(gè)資源實(shí)現(xiàn)的XAResource來(lái)進(jìn)行兩階段提交的控制。有興趣的同學(xué)可以看看這個(gè)介面的方法,除了commit, rollback等方法以外,還有end(), forget(), isSameRM(), prepare()等等。光從這些介面就能夠想像JTA在實(shí)現(xiàn)兩階段事務(wù)的複雜性。

什麼是XA?

XA是由X/Open組織提出的分散式事務(wù)的架構(gòu)(或稱為協(xié)定)。 XA架構(gòu)主要定義了(全域)事務(wù)管理器(Transaction Manager)和(局部)資源管理器(Resource Manager)之間的介面。 XA介面是雙向的系統(tǒng)接口,在事務(wù)管理器(Transaction Manager)以及一個(gè)或多個(gè)資源管理器(Resource Manager)之間形成通訊橋樑。也就是說(shuō),在基於XA的一個(gè)事務(wù)中,我們可以針對(duì)多個(gè)資源進(jìn)行事務(wù)管理,例如一個(gè)系統(tǒng)存取多個(gè)資料庫(kù),或即存取資料庫(kù)、又存取像訊息中間件這樣的資源。這樣我們就能夠?qū)崿F(xiàn)在多個(gè)資料庫(kù)和訊息中間件直接實(shí)現(xiàn)全部提交、或全部取消的事務(wù)。 XA規(guī)範(fàn)不是java的規(guī)範(fàn),而是一種通用的規(guī)範(fàn), 目前各種資料庫(kù)、以及許多訊息中間件都支援XA規(guī)範(fàn)。

JTA是滿足XA規(guī)格的、用於Java開發(fā)的規(guī)格。所以,當(dāng)我們說(shuō),使用JTA實(shí)現(xiàn)分散式事務(wù)的時(shí)候,其實(shí)是說(shuō),使用JTA規(guī)範(fàn),實(shí)現(xiàn)系統(tǒng)內(nèi)多個(gè)資料庫(kù)、訊息中間件等資源的事務(wù)。

什麼是Atomikos

Atomikos是一個(gè)非常受歡迎的開源事務(wù)管理器,並且可以嵌入到你的Spring Boot應(yīng)用中。 Tomcat應(yīng)用程式伺服器沒有實(shí)作JTA規(guī)範(fàn),當(dāng)使用Tomcat作為應(yīng)用程式伺服器的時(shí)候,需要使用第三方的事務(wù)管理器類別來(lái)作為全域的事務(wù)管理器,而Atomikos框架就是這個(gè)作用,將事務(wù)管理整合到應(yīng)用程式中,而不依賴application server。

Spring Boot 整合Atomikos

說(shuō)一堆的理論沒什麼用,show me the code。

技術(shù)堆疊:Spring Boot MyBatis Atomikos MySQL

#

如果你依照本文程式碼,注意你的mysql版本。

先建好兩個(gè)資料庫(kù)(my-db_0和my-db_1),然後每個(gè)庫(kù)裡各建一張表。

資料庫(kù)my-db_0中:

CREATE TABLE `t_user_0` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int NOT NULL,
`gender` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

資料庫(kù)my-db_1中:

CREATE TABLE `t_user_1` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int NOT NULL,
`gender` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

這裡只是為了示範(fàn)分散式事務(wù),不用在意表的具體意義。

整體專案結(jié)構(gòu)

Spring Boot+MyBatis+Atomikos+MySQL(附源碼)
#專案整體結(jié)構(gòu)

maven配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tian</groupId>
    <artifactId>spring-boot-atomikos</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>

    <name>spring-boot-atomikos</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- mybatis依賴 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mysql依賴 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!--分布式事務(wù)-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jta-atomikos</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 要使生成的jar可運(yùn)行,需要加入此插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
            <resource>
                <!-- 編譯xml文件 -->
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

properties配置

server.port=9001
spring.application.name=atomikos-demo

spring.datasource.user0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.user0.url=jdbc:mysql://localhost:3306/my-db_0?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.user0.user=root
spring.datasource.user0.password=123456

spring.datasource.user1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.user1.url=jdbc:mysql://localhost:3306/my-db_1?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.user1.user=root
spring.datasource.user1.password=123456

mybatis.mapperLocations=classpath:/com/tian/mapper/*/*.xml
mybatis.typeAliasesPackage=com.tian.entity
mybatis.configuration.cache-enabled=true

#資料來(lái)源

##
/**
 * @author tianwc  公眾號(hào):java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年05月11日 19:38
 * 博客地址:<a href="http://woaijava.cc/">博客地址</a>
 * <p>
 * 配置好兩個(gè)數(shù)據(jù)源
 */
@Configuration
public class DataSourceConfig {

    // 將這個(gè)對(duì)象放入spring容器中(交給Spring管理)
    @Bean
    // 讀取 application.yml 中的配置參數(shù)映射成為一個(gè)對(duì)象
    @ConfigurationProperties(prefix = "spring.datasource.user0")
    public XADataSource getDataSource0() {
        // 創(chuàng)建XA連接池
        return new MysqlXADataSource();
    }

    /**
     * 創(chuàng)建Atomikos數(shù)據(jù)源
     * 注解@DependsOn("druidXADataSourcePre"),在名為druidXADataSourcePre的bean實(shí)例化后加載當(dāng)前bean
     */
    @Bean
    @DependsOn("getDataSource0")
    @Primary
    public DataSource dataSourcePre(@Qualifier("getDataSource0") XADataSource xaDataSource) {
        //這里的AtomikosDataSourceBean使用的是spring提供的
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(xaDataSource);
        atomikosDataSourceBean.setMaxPoolSize(20);
        return atomikosDataSourceBean;
    }


    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.user1")
    public XADataSource getDataSource1() {
        // 創(chuàng)建XA連接池
        return new MysqlXADataSource();
    }

    @Bean
    @DependsOn("getDataSource1")
    public DataSource dataSourceSit(@Qualifier("getDataSource1") XADataSource xaDataSource) {
        //這里的AtomikosDataSourceBean使用的是spring提供的
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(xaDataSource);
        return atomikosDataSourceBean;
    }
}

MyBatis掃描

@Configuration
@MapperScan(basePackages = {"com.tian.mapper.user0"}, sqlSessionTemplateRef = "preSqlSessionTemplate")
public class MybatisPreConfig {

    @Autowired
    @Qualifier("dataSourcePre")
    private DataSource dataSource;

    /**
     * 創(chuàng)建 SqlSessionFactory
     */
    @Bean
    @Primary
    public SqlSessionFactory preSqlSessionFactory() throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().
                getResources("classpath*:com/tian/mapper/user0/*.xml"));
        return bean.getObject();
    }

    /**
     * 通過(guò) SqlSessionFactory 來(lái)創(chuàng)建 SqlSessionTemplate
     */
    @Bean
    @Primary
    public SqlSessionTemplate preSqlSessionTemplate(@Qualifier("preSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        // SqlSessionTemplate是線程安全的,可以被多個(gè)DAO所共享使用
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
另外一個(gè)基本上一樣,就是掃描路徑改成:
("classpath*:com/tian/mapper/user1/*.xml")

#mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tian.mapper.user0.User0Mapper">

    <!-- -->
    <cache eviction="LRU" flushInterval="10000" size="1024"  />

    <resultMap id="BaseResultMap" type="com.tian.entity.User0">
        <id column="id" jdbcType="BIGINT" property="id" />
        <result column="user_name" jdbcType="VARCHAR" property="userName" />
        <result column="age" jdbcType="INTEGER" property="age" />
        <result column="gender" jdbcType="INTEGER" property="gender" />
    </resultMap>

    <sql id="Base_Column_List">
        id, user_name, age, gender
    </sql>
    <insert id="insert" parameterType="com.tian.entity.User0">
        insert into t_user_0 (id, user_name,age, gender)
        values (#{id,jdbcType=BIGINT}, #{userName,jdbcType=VARCHAR},#{age,jdbcType=INTEGER},#{gender,jdbcType=INTEGER})
    </insert>

</mapper>

另外一個(gè)基本上完全一樣,這裡就貼出來(lái)了。

對(duì)應(yīng)mapper介面也非常簡(jiǎn)單,貼出一個(gè):
public interface User0Mapper {

    int insert(User0 record);
}

#service

/**
 * @author tianwc  公眾號(hào):java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年05月11日 19:38
 * 博客地址:<a href="http://woaijava.cc/">博客地址</a>
 * <p>
 * 模擬三種場(chǎng)景:正常、制造異常、數(shù)據(jù)庫(kù)異常
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private User0Mapper user0Mapper;
    @Resource
    private User1Mapper user1Mapper;
    /**
     * 正常邏輯 同時(shí)對(duì)兩個(gè)數(shù)據(jù)庫(kù)進(jìn)行 插入數(shù)據(jù)
     */
    @Transactional
    @Override
    public int transaction1() throws Exception {
        User1 user1 = new User1();
        user1.setUserName("22222");
        user1.setAge(11);
        user1.setGender(0);
        user1Mapper.add(user1);
        System.out.println("---------------------------");
        // sit(數(shù)據(jù)源1)
        User0 user0 = new User0();
        user0.setUserName("111111");
        user0.setAge(11);
        user0.setGender(0);
        user0Mapper.insert(user0);
        return 1;
    }
    /**
     * 正常邏輯 同時(shí)對(duì)兩個(gè)數(shù)據(jù)庫(kù)進(jìn)行 插入數(shù)據(jù)
     * 數(shù)據(jù)插入完后  出現(xiàn)異常
     */
    @Transactional
    @Override
    public int transaction2() throws Exception {
        User1 user1 = new User1();
        user1.setUserName("22222");
        user1.setAge(11);
        user1.setGender(0);
        user1Mapper.add(user1);
        System.out.println("---------------------------");
        // sit(數(shù)據(jù)源1)
        User0 user0 = new User0();
        user0.setUserName("111111");
        user0.setAge(11);
        user0.setGender(0);
        user0Mapper.insert(user0);
        //認(rèn)為制造一個(gè)異常
        int a=1/0;
        return 1;
    }

    /**
     * 第一個(gè)數(shù)據(jù)插入成功  第二個(gè)數(shù)據(jù)插入失敗
     */
    @Transactional
    @Override
    public int transaction3() throws Exception {
        User1 user1 = new User1();
        user1.setUserName("22222");
        user1.setAge(11);
        user1.setGender(0);
        user1Mapper.add(user1);
        System.out.println("---------------------------");
        // sit(數(shù)據(jù)源1)
        User0 user0 = new User0();
       //故意搞長(zhǎng)點(diǎn),模擬插入失敗 讓前面的數(shù)據(jù)回滾 user0.setUserName("111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
        user0.setAge(11);
        user0.setGender(0);
        user0Mapper.insert(user0);
        return 1;
    }
}
## controller

<pre class='brush:php;toolbar:false;'>@RestController @RequestMapping(&quot;/user&quot;) public class UserController { @Resource private UserService userService; @PostMapping(&quot;/test1&quot;) public CommonResult test1() { int i = 0; try { i = userService.transaction1(); return CommonResult.success(i); } catch (Exception e) { e.printStackTrace(); } return CommonResult.success(i); } @PostMapping(&quot;/test2&quot;) public CommonResult test2() { int i = 0; try { i = userService.transaction2(); return CommonResult.success(i); } catch (Exception e) { e.printStackTrace(); } return CommonResult.success(i); } @PostMapping(&quot;/test3&quot;) public CommonResult test3() { int i = 0; try { i = userService.transaction3(); return CommonResult.success(i); } catch (Exception e) { e.printStackTrace(); } return CommonResult.success(i); } }</pre>

###專案啟動(dòng)類別##########
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

/**
 * @author tianwc  公眾號(hào):java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年05月11日 19:38
 * 博客地址:<a href="http://woaijava.cc/">博客地址</a>
 * <p>
 * 項(xiàng)目啟動(dòng)類
 */
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
//@ComponentScan(basePackages = {"com.tian"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
########測(cè)試########################################################## #####啟動(dòng)項(xiàng)目,分別測(cè)試以下三個(gè):#########http://localhost:9001/user/test1### ? 結(jié)果:兩個(gè)資料庫(kù)中,表格資料都新增一條#########http://localhost:9001/user/test2### ? ?結(jié)果:拋出除數(shù)無(wú)法為Zero的例外,兩個(gè)資料庫(kù)都沒有新增資料。 ###

http://localhost:9001/user/test3 ? ?結(jié)果:拋出資料欄位值太長(zhǎng)異常,兩個(gè)資料庫(kù)都沒有新增資料。

好了,到此我們已經(jīng)實(shí)作了分散式事務(wù)。

以上是Spring Boot+MyBatis+Atomikos+MySQL(附源碼)的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
如何用PHP開發(fā)問(wèn)答社區(qū)平臺(tái) PHP互動(dòng)社區(qū)變現(xiàn)模式詳解 如何用PHP開發(fā)問(wèn)答社區(qū)平臺(tái) PHP互動(dòng)社區(qū)變現(xiàn)模式詳解 Jul 23, 2025 pm 07:21 PM

1.PHP開發(fā)問(wèn)答社區(qū)首選Laravel MySQL Vue/React組合,因生態(tài)成熟、開發(fā)效率高;2.高性能需依賴緩存(Redis)、數(shù)據(jù)庫(kù)優(yōu)化、CDN和異步隊(duì)列;3.安全性必須做好輸入過(guò)濾、CSRF防護(hù)、HTTPS、密碼加密及權(quán)限控制;4.變現(xiàn)可選廣告、會(huì)員訂閱、打賞、傭金、知識(shí)付費(fèi)等模式,核心是匹配社區(qū)調(diào)性和用戶需求。

將MySQL部署自動(dòng)化為代碼 將MySQL部署自動(dòng)化為代碼 Jul 20, 2025 am 01:49 AM

要實(shí)現(xiàn)MySQL部署自動(dòng)化,關(guān)鍵在於選用Terraform定義資源、Ansible管理配置、Git進(jìn)行版本控制,並強(qiáng)化安全與權(quán)限管理。 1.使用Terraform定義MySQL實(shí)例,如AWSRDS的版本、類型、訪問(wèn)控制等資源屬性;2.通過(guò)AnsiblePlaybook實(shí)現(xiàn)數(shù)據(jù)庫(kù)用戶創(chuàng)建、權(quán)限設(shè)置等細(xì)節(jié)配置;3.所有配置文件納入Git管理,支持變更追蹤與協(xié)作開發(fā);4.避免硬編碼敏感信息,使用Vault或AnsibleVault管理密碼,並設(shè)置訪問(wèn)控制與最小權(quán)限原則。

如何在PHP環(huán)境中設(shè)置環(huán)境變量 PHP運(yùn)行環(huán)境變量添加說(shuō)明 如何在PHP環(huán)境中設(shè)置環(huán)境變量 PHP運(yùn)行環(huán)境變量添加說(shuō)明 Jul 25, 2025 pm 08:33 PM

PHP設(shè)置環(huán)境變量主要有三種方式:1.通過(guò)php.ini全局配置;2.通過(guò)Web服務(wù)器(如Apache的SetEnv或Nginx的fastcgi_param)傳遞;3.在PHP腳本中使用putenv()函數(shù)。其中,php.ini適用於全局且不常變的配置,Web服務(wù)器配置適用於需要隔離的場(chǎng)景,putenv()適用於臨時(shí)性的變量。持久化策略包括配置文件(如php.ini或Web服務(wù)器配置)、.env文件配合dotenv庫(kù)加載、CI/CD流程中動(dòng)態(tài)注入變量。安全管理敏感信息應(yīng)避免硬編碼,推薦使用.en

如何用PHP開發(fā)商品推薦模塊 PHP推薦算法與用戶行為分析 如何用PHP開發(fā)商品推薦模塊 PHP推薦算法與用戶行為分析 Jul 23, 2025 pm 07:00 PM

收集用戶行為數(shù)據(jù)需通過(guò)PHP記錄瀏覽、搜索、購(gòu)買等信息至數(shù)據(jù)庫(kù),並清洗分析以挖掘興趣偏好;2.推薦算法選擇應(yīng)根據(jù)數(shù)據(jù)特徵決定:基於內(nèi)容、協(xié)同過(guò)濾、規(guī)則或混合推薦;3.協(xié)同過(guò)濾在PHP中可實(shí)現(xiàn)為計(jì)算用戶餘弦相似度、選K近鄰、加權(quán)預(yù)測(cè)評(píng)分並推薦高分商品;4.性能評(píng)估用準(zhǔn)確率、召回率、F1值及CTR、轉(zhuǎn)化率並通過(guò)A/B測(cè)試驗(yàn)證效果;5.冷啟動(dòng)問(wèn)題可通過(guò)商品屬性、用戶註冊(cè)信息、熱門推薦和專家評(píng)價(jià)緩解;6.性能優(yōu)化手段包括緩存推薦結(jié)果、異步處理、分佈式計(jì)算與SQL查詢優(yōu)化,從而提升推薦效率與用戶體驗(yàn)。

使用SSL/TLS加密保護(hù)MySQL連接 使用SSL/TLS加密保護(hù)MySQL連接 Jul 21, 2025 am 02:08 AM

為什麼需要SSL/TLS加密MySQL連接?因?yàn)椴患用艿倪B接可能導(dǎo)致敏感數(shù)據(jù)被截取,啟用SSL/TLS可防止中間人攻擊並滿足合規(guī)要求;2.如何為MySQL配置SSL/TLS?需生成證書和私鑰,修改配置文件指定ssl-ca、ssl-cert和ssl-key路徑並重啟服務(wù);3.客戶端連接時(shí)如何強(qiáng)制使用SSL?通過(guò)創(chuàng)建用戶時(shí)指定REQUIRESSL或REQUIREX509實(shí)現(xiàn);4.SSL配置容易忽略的細(xì)節(jié)包括證書路徑權(quán)限、證書過(guò)期問(wèn)題以及客戶端配置需求。

MySQL撤銷用戶的特權(quán) MySQL撤銷用戶的特權(quán) Jul 16, 2025 am 03:56 AM

要使用REVOKE回收MySQL用戶權(quán)限,需按格式指定權(quán)限類型、數(shù)據(jù)庫(kù)和用戶。 1.回收全部權(quán)限用REVOKEALLPRIVILEGES,GRANTOPTIONFROM'用戶名'@'主機(jī)名';2.回收特定數(shù)據(jù)庫(kù)權(quán)限用REVOKEALLPRIVILEGESONmydb.FROM'用戶名'@'主機(jī)名';3.回收全局權(quán)限用REVOKE權(quán)限類型ON.*FROM'用戶名'@'主機(jī)名';注意執(zhí)行後建議刷新權(quán)限,權(quán)限範(fàn)圍需與授權(quán)時(shí)一致,且不能回收不存在的權(quán)限。

如何用PHP搭建在線客服機(jī)器人 PHP智能客服實(shí)現(xiàn)技術(shù) 如何用PHP搭建在線客服機(jī)器人 PHP智能客服實(shí)現(xiàn)技術(shù) Jul 25, 2025 pm 06:57 PM

PHP在智能客服中扮演連接器和大腦中樞角色,負(fù)責(zé)串聯(lián)前端輸入、數(shù)據(jù)庫(kù)存儲(chǔ)與外部AI服務(wù);2.實(shí)現(xiàn)時(shí)需構(gòu)建多層架構(gòu):前端接收用戶消息,PHP後端預(yù)處理並路由請(qǐng)求,先匹配本地知識(shí)庫(kù),未命中則調(diào)用外部AI服務(wù)如OpenAI或Dialogflow獲取智能回復(fù);3.會(huì)話管理由PHP寫入MySQL等數(shù)據(jù)庫(kù),保障上下文連續(xù)性;4.集成AI服務(wù)需用Guzzle發(fā)送HTTP請(qǐng)求,安全存儲(chǔ)APIKey,做好錯(cuò)誤處理與響應(yīng)解析;5.數(shù)據(jù)庫(kù)設(shè)計(jì)需包含會(huì)話、消息、知識(shí)庫(kù)、用戶表,合理建索引、保障安全與性能,支撐機(jī)器人記憶

如何用PHP開發(fā)AI智能表單系統(tǒng) PHP智能表單設(shè)計(jì)與分析 如何用PHP開發(fā)AI智能表單系統(tǒng) PHP智能表單設(shè)計(jì)與分析 Jul 25, 2025 pm 05:54 PM

選擇合適的PHP框架需根據(jù)項(xiàng)目需求綜合考慮:Laravel適合快速開發(fā),提供EloquentORM和Blade模板引擎,便於數(shù)據(jù)庫(kù)操作和動(dòng)態(tài)表單渲染;Symfony更靈活,適合複雜系統(tǒng);CodeIgniter輕量,適用於對(duì)性能要求較高的簡(jiǎn)單應(yīng)用。 2.確保AI模型準(zhǔn)確性需從高質(zhì)量數(shù)據(jù)訓(xùn)練、合理選擇評(píng)估指標(biāo)(如準(zhǔn)確率、召回率、F1值)、定期性能評(píng)估與模型調(diào)優(yōu)入手,並通過(guò)單元測(cè)試和集成測(cè)試保障代碼質(zhì)量,同時(shí)持續(xù)監(jiān)控輸入數(shù)據(jù)以防止數(shù)據(jù)漂移。 3.保護(hù)用戶隱私需採(cǎi)取多項(xiàng)措施:對(duì)敏感數(shù)據(jù)進(jìn)行加密存儲(chǔ)(如AES

See all articles