PHP转JAVA开发30分钟实战攻略

多态苔藓
• 阅读 3681

服务端开发中,有很多知识是相通的,例如mysql,redis,http协议等。

基于这些基础,在编程语言上的转变并不困难。

本文主要从下面几点出发,讲述如何快速从php开发转为java开发:

  • 使用框架构建web项目 - 10min
  • 常用数据结构对应和概念转变 - 5min
  • 操作Mysql数据库和发送http请求 - 15min

使用框架构建项目

先看下PHP和JAVA对应的项目工具和框架:

PHPJAVA
项目管理工具composermaven
框架Laravel或ThinkphpSpringBoot

java中,maven是项目管理工具,实现安装依赖,打包等功能,是一个项目的起点,通过pom.xml配置文件管理依赖。SpringBoot本质上就是一个maven的依赖包。

相比php的框架,SpringBoot原生提供的功能并不多,但是可以通过maven很方便的加载其他功能的依赖

常用的java开发IDE是idea,社区版是免费的,可以直接在官网下载,基本能满足开发需求。

创建项目

需要的准备工作,下载idea。在系统中安装maven和jdk,可以直接通过idea安装,也可以去官网下载安装。

可以使用官方网站:https://start.spring.io/ ,来创建SpringBoot项目,如下图,这里我们选择Spring Web依赖。

PHP转JAVA开发30分钟实战攻略

下载解压后,可以看到里面已经有了pom.xml文件,并加入了SpringBoot的依赖,使用idea加载文件夹:

PHP转JAVA开发30分钟实战攻略

项目引入后,可以看到目录结构已经建好,接下来实现一个web api处理http请求,如下:

package com.abc.webtest.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @GetMapping("/test")
    public String test(){
        return "hello";
    }
}
  • 新建一个controller文件夹,用来存放所有处理http请求的类
  • 在php的框架里通常会把url和处理方法的映射放在一个route.php文件里
  • 在SpringBoot中主要使用注解的方式指定url的处理方法

PHP转JAVA开发30分钟实战攻略

之后可以直接启动应用,默认的端口是:8080。启动后就可在浏览器中访问:http://localhost:8080/test,返回hello

PHP转JAVA开发30分钟实战攻略

  • 如果要修改启动的默认端口,可以在application.yml中添加如下配置。
server:
  port: 9999

application.yml是SpringBoot中用来管理配置的文件,大部分自动配置的组件的配置可以写到这里。例如上面的服务启动端口。

常用数据结构对应和概念转变

如果要问php中最常用的数据结构是什么?相信大多数答案都是array

相对的在java开发中常用的数据结构是ArrayListHashMap,它们可以看成是array的拆分,一种简单的对应关系为:

PHPJAVA
array('a','b','c')ArrayList
array(a'=>1,'b'=>2,'c'=>3)HashMap

了解对应关系有助于在开发中更好的使用对应的结构。

在开发中还有一些概念上的转变:

  • 变量定义

    • php是弱类型语言,定义变量时可以不指定类型,使用比较灵活,但也容易出问题。
    • java是强类型语言,每个变量都要指定类型,不能给变量赋值为别的类型。
  • 每次请求的变量遗留

    • 使用php-fpm方式提供服务时,每次请求结束时都会把创建的变量回收,包括静态变量。所以请求间不会有影响
    • SpringBoot提供服务时,是一直运行的,意味着上次请求创建或修改的变量可能会影响下一次请求,造成问题,这个需要特别注意。尤其是对静态变量的使用。

操作Mysql数据库

日常开发中,最常用的功能就是操作数据库和通过http请求调用接口了(微服务调用主要依赖服务框架,这里不涉及)。

代码中操作数据库,通常包括两大部分:

  • ORM持久层映射:负责代码和数据表的操作转换,把表映射为一个对象,通过对象来操作表

    • php中主要是各框架提供的,例如Laravel中的Eloquent Model
    • java中较受欢迎的是mybatis-plus,也是把每个表映射为一个实体类
  • 数据库连接层

    • php中是PDO + pdo_mysql扩展
    • java中可以使用druid + mysql-connector

下面就介绍下在java中使用mybatis-plus + druid + mysql-connector操作数据库中的一张表,主要分5步。

1.通过maven在pom.xml中加载这三个依赖

在使用SpringBoot框架时,会经常用到自动配置,在项目启动时自动创建需要的对象。

这里直接使用对应的starter包,可以在项目启动时,自动创建数据库连接池等对象。

      <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>
2.创建表的实体和Mapper

现在库中有一张表,表名是:main_user

CREATE TABLE `main_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `password` varchar(100) NOT NULL,
  `user_name` varchar(100) NOT NULL,
  `user_phone` varchar(40) NOT NULL,
  `score` int(11) DEFAULT '0',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

要操作这张表,首先需要创建一个类作为该表的映射,类名就是MainUser,类的成员就是表中的字段,每个字段的类型需要与数据库中的相对应,常用的类型可以很容看出来,其他字段可以百度一下JdbcType类型和Java类型的对应关系。

public class MainUser extends Model<MainUser> {
    private static final long serialVersionUID = 1L;
    @TableId(value = "user_id", type = IdType.AUTO)
    private Integer userId;
    private String password;
    private String userName;
    private String userPhone;
    private Integer score;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

然后创建一个Mapper用于操作这个类,就叫做MainUserMapper

因为这里使用了mybatis-plus,Mapper可以直接使用很多底层方法,可以只定义一个空接口。

import com.abc.webtest.db.entity.MainUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface MainUserMapper extends BaseMapper<MainUser> {
}
3.在SpringBoot中设置Mapper的包名

SpringBoot的IOC可以直接生成可用的接口实现对象,只要在启动时指定要扫描的Mapper所在的包名。

@SpringBootApplication
@MapperScan("com.abc.webtest.db.mapper") //这个就是mapper包,一个库中表的mapper都放在这里
public class WebtestApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebtestApplication.class, args);
    }
}
4.在application.yml中设置mysql的配置

将连接mysql需要的地址,用户名,密码写入application.yml中:

spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/test_db?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
      username: root
      password: 123456
5.在controller中操作表

这里简单展示下对表的操作。

在SpringBoot中,底层的IOC会负责类之间的引用关系,即在A中引用B,不需要手动创建对象,而是使用Resource等注解。

下面两个请求实现了对表的插入和按id查询。

@RestController
public class TestController {
    //这里会将要使用的对象加载到该类中
    @Resource
    MainUserMapper mainUserMapper;

    @GetMapping("/test")
    public String test() {
        return "hello";
    }

    //定义post请求,这里框架底层会直接将body里面的json数据,按key名赋值给参数中的对象
    @PostMapping("user/register") 
    public Boolean userRegister(@RequestBody MainUser mainUser) {
        mainUserMapper.insert(mainUser);
        return true;
    }

    @GetMapping("user/info")
    public MainUser userInfo(Integer userId) {
        MainUser mainUser = new MainUser();
        return mainUserMapper.selectById(userId);
    }
}

发送HTTP请求

在开发中,系统的外部资源除了数据库,最多的就是其他的服务了,这里介绍下java中访问http接口的方法。

在php中,访问http的底层基本都是用curl扩展的相关功能。

在java中,一个比较基础的包是httpclient,首先在pom.xml中引入这个包。

    <!-- httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.12</version>
        </dependency>
写一个HttpUtil类作Http的统一请求

这里使用@Componet注解,它的作用是告诉Spring框架将该类作为一个bean加载到IOC中,供其他类使用。

@Component
public class HttpUtil {
    CloseableHttpClient client = HttpClients.custom()
            .setDefaultRequestConfig(RequestConfig.custom()
                    .setConnectTimeout(500) //连接超时时间,单位毫秒,按实际情况调整
                    .build())
            .setDefaultSocketConfig(SocketConfig.custom()
                    .setSoTimeout(2 * 1000) //请求响应超时时间,单位毫秒,这里设为2秒,按实际情况调整
                    .build())
            .build();

    public String get(String url) throws IOException {
        HttpGet httpGet = new HttpGet(url);
        try (CloseableHttpResponse httpResponse = client.execute(httpGet)) {
            HttpEntity httpEntity = httpResponse.getEntity();
            return EntityUtils.toString(httpEntity, "UTF-8");
        }
    }

    public String post(String url, Map<String, String> params) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse httpResponse = null;
        try {
            //这里使用了Jackson作为json转换工具,在spring-web依赖中已经引入,可以直接使用
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(params);
            StringEntity stringEntity = new StringEntity(json, "UTF-8");
            httpPost.setEntity(stringEntity);
            httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
            httpResponse = client.execute(httpPost);
            return EntityUtils.toString(httpResponse.getEntity());
        } finally {
            if (httpResponse != null) {
                httpResponse.close();
            }
        }
    }
}
在controller中使用

这里创建两个简单的接口,使用GET和POST方法分别调用了两个免费的api。

同样使用Resource加载HttpUtil类的对象到controller中。

@RestController
public class TestController {
    @Resource
    HttpUtil httpUtil;

    @GetMapping("inaword")
    public String inAWord() throws IOException {
        return httpUtil.get("http://api.lkblog.net/ws/api.php");
    }

    @GetMapping("create/random")
    public String createRandom(String name, String phone) throws IOException {
        Map<String, String> params = new HashMap<>();
        params.put("name", name);
        params.put("job", phone);
        return httpUtil.post("https://reqres.in/api/users", params);
    }
}

通过上面的介绍,希望能帮助大家更快的上手java开发。

完整的pom.xml和application.xml

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.abc</groupId>
    <artifactId>webtest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>webtest</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>

        <!-- httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.12</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
application.yml
server:
  port: 9999

spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/test_db?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
      username: root
      password: 123456

文章中工程的源代码地址:https://gitee.com/dothetrick/...

以上内容属个人学习总结,如有不当之处,欢迎在评论中指正

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
4年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
4年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这