写点什么

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

用户头像
dothetrick
关注
发布于: 2021 年 01 月 15 日
PHP转JAVA开发30分钟实战攻略

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


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


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


  • 使用框架构建 web 项目 - 10min

  • 常用数据结构对应和概念转变 - 5min

  • 操作 Mysql 数据库和发送 http 请求 - 15min


使用框架构建项目


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


| | PHP | JAVA |

| :--: | :--: | :--: |

| 项目管理工具 | composer | maven |

| 框架 | Laravel 或 Thinkphp | SpringBoot |


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


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


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


创建项目


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


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



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



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


package com.abc.webtest.controller;
import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;
@RestControllerpublic class TestController { @GetMapping("/test") public String test(){ return "hello"; }}
复制代码
  • 新建一个 controller 文件夹,用来存放所有处理 http 请求的类

  • 在 php 的框架里通常会把 url 和处理方法的映射放在一个 route.php 文件里

  • 在 SpringBoot 中主要使用注解的方式指定 url 的处理方法



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



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


server:  port: 9999
复制代码


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


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


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


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


| PHP | JAVA |

| :------------------------: | :-------: |

| 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 查询。


@RestControllerpublic 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 中,供其他类使用。


@Componentpublic 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 中。


@RestControllerpublic 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/webtest


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


发布于: 2021 年 01 月 15 日阅读数: 49
用户头像

dothetrick

关注

程序员 2018.06.12 加入

某互联网公司高级开发,6年后端经验

评论

发布
暂无评论
PHP转JAVA开发30分钟实战攻略