常用代码、特定函数、复杂概念、特定功能......在学习编程的过程中你会记录下哪些内容?快来分享你的笔记,一起切磋进步吧!
一、常用代码
在java编程中常用需要储备的就是工具类。包括封装的时间工具类。http工具类,加解密工具类,JSON工具类,翻页工具类,字符串处理工具类等等。
1、时间工具类
java
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateTimeUtils {
/**
* 获取当前时间,格式为:yyyy-MM-dd HH:mm:ss
* @return
*/
public static String getDateStr() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return df.format(new Date());
}
/**
* 获取当前时间,格式为:yyyy-MM-dd
* @return
*/
public static String getDayStr() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
return df.format(new Date());
}
/**
* 获取到月份,格式为:yyyyMM
* @return
*/
public static String getThisMonth() {
SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
return df.format(new Date());
}
/**
* 获取到月份,格式为:yyyyMMdd
* @return
*/
public static String getYyyyMMdd() {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
return df.format(new Date());
}
/**
* @description: 两个String类型,按照日期格式对比
* eg:
* dateOne:2015-12-26
* dateTwo:2015-12-26
* dateFormatType: yyyy-MM-dd
* 返回类型:-1:dateOne小于dateTwo, 0:dateOne=dateTwo ,1:dateOne大于dateTwo
* @param dateOne
* @param dateTwo
* @param dateFormatType:yyyy-MM-dd / yyyy-MM-dd HH:mm:ss /等
* @return -1,0,1,100
* @throws
*/
public static int compareTime(String dateOne, String dateTwo , String dateFormatType){
DateFormat df = new SimpleDateFormat(dateFormatType);
Calendar calendarStart = Calendar.getInstance();
Calendar calendarEnd = Calendar.getInstance();
try {
calendarStart.setTime(df.parse(dateOne));
calendarEnd.setTime(df.parse(dateTwo));
} catch (ParseException e) {
e.printStackTrace();
return 100;
}
int result = calendarStart.compareTo(calendarEnd);
if(result > 0){
result = 1;
}else if(result < 0){
result = -1;
}else{
result = 0 ;
}
return result ;
}
/**
* 获取当前时间,格式为: HH:mm:ss
* @return
*/
public static String getHHmmSS() {
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
return df.format(new Date());
}
public static void main(String[] args) throws ParseException {
System.out.println(DateTimeUtils.getHHmmSS());
}
//将时间转换为时间戳
public static String dateToStamp(String s) throws ParseException {
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(s);
long ts = date.getTime();
res = String.valueOf(ts);
return res;
}
/**
* 获取昨天日期"yyyy-MM-dd"
* @return
*/
public static String getYesterday() {
DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,-24);
return dateFormat.format(calendar.getTime());
}
}
2、http工具类
java
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Map;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
/**
* http请求
*/
@Slf4j
public class HttpUtils {
public static String doGet(String url) {
return doGet(url, null);
}
public static String doGet(String url, Map<String, String> map) {
String resultString = "";
RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
// 参数设置
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
if (CollectionUtil.isNotEmpty(map)) {
for (String key : map.keySet()) {
params.add(key, map.get(key));
}
}
try {
// 设置表单提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
params, headers);
// 执行HTTP请求
ResponseEntity<String> response = client.exchange(url, HttpMethod.GET, requestEntity, String.class);
resultString = response.getBody();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPost(String url, Map<String, String> map) {
String resultString = "";
ResponseEntity<String> response = null;
RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
// 参数设置
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
if (CollectionUtil.isNotEmpty(map)) {
for (String key : map.keySet()) {
params.add(key, map.get(key));
}
}
try {
// 请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
params, headers);
// 执行HTTP请求
response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
resultString = response.getBody();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return resultString;
}
public static String doPostJson(String url, String json) {
String resultString = "";
RestTemplate client = new RestTemplate();
ResponseEntity<String> response = null;
// 提交方式设置
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<String>(json, headers);
try {
// 执行HTTP请求
response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
resultString = response.getBody();
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
try {
} catch (Exception e) {
// TODO Auto-generated catch block
log.error(e.getMessage(), e);
}
}
return resultString;
}
/**
* 创建http请求头
* @param url
* @return
* @throws Exception
*/
public static URLConnection FactoryCreatURLConnection(String url) throws Exception {
URL realUrl;
URLConnection conn = null;
try {
// 打开和URL之间的连接
realUrl = new URL(url);
conn = realUrl.openConnection();
conn.setRequestProperty("accept", "text/plain;charset=utf-8");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return conn;
}
/**
* 判断连接是否可用
*
* @param url http请求地址
* @return
*/
public static boolean isRearchUrl(String url) {
return isRearchUrl(url, 3000);
}
/**
* 判断连接是否可用
*
* @param url http请求地址
* @return
*/
public static boolean isRearchUrl(String url, int timeout) {
if (StringUtils.isEmpty(url)) {
return false;
}
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
// 设置超时时间
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
if (connection.getResponseCode() >= HttpURLConnection.HTTP_OK
&& connection.getResponseCode() <= HttpURLConnection.HTTP_VERSION) {
return true;
}
} catch (Exception e) {
log.error(" HttpURLConnection exception happend!");
return false;
} finally {
if (connection != null) {
connection.disconnect();
}
}
return false;
}
/**
* 判断ip是否能ping通
*/
public static boolean checkIp(String ipAddr) {
try {
boolean status = false;
if (!StringUtils.isEmpty(ipAddr)) {
int timeOut = 3000; // 超时 3秒
status = InetAddress.getByName(ipAddr).isReachable(timeOut);
return status;
}
return status;
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
3、加解密工具类
java
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
/**
* Aes加解密
* @date 2022-4-07
*/
public class AesUtil {
private static final Logger logger = LogManager.getLogger("AESUtil");
private static final String CHARSET = "UTF-8";
public static String base64Encode(byte[] bytes) {
return Base64.encodeBase64String(bytes);
}
public static byte[] base64Decode(String base64Code) throws Exception {
return Base64.decodeBase64(base64Code.getBytes(CHARSET));
}
/**
* 加密
*
* @param content
* @param encryptKey
* @return
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
initEncryptCipher(encryptKey);
return encryptCipher.doFinal(content.getBytes(CHARSET));
}
/**
* 加密
*
* @param content
* @param encryptKey
* @return
* @throws Exception
*/
public static byte[] aesEncryptToBytes(byte[] content, String encryptKey) throws Exception {
initEncryptCipher(encryptKey);
return encryptCipher.doFinal(content);
}
/**
* 加密转字符
*
* @param content
* @param encryptKey
* @return
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
return base64Encode(aesEncryptToBytes(content, encryptKey));
}
/**
* 解密
*
* @param content
* @param decryptKey
* @return
* @throws Exception
*/
public static byte[] aesDecryptByBytes(String content, String decryptKey) throws Exception {
initDecryptCipher(decryptKey);
return decryptCipher.doFinal(content.getBytes(CHARSET));
}
/**
* 解密
*
* @param content
* @param decryptKey
* @return
* @throws Exception
*/
public static byte[] aesDecryptByBytes(byte[] content, String decryptKey) throws Exception {
initDecryptCipher(decryptKey);
return decryptCipher.doFinal(content);
}
public static String aesDecrypt(String content, String decryptKey) throws Exception {
return new String(aesDecryptByBytes(base64Decode(content), decryptKey));
}
private static Cipher encryptCipher = null;
private static Cipher decryptCipher = null;
public static void initEncryptCipher(String aesKey) throws Exception {
if (encryptCipher == null) {
//5.根据字节数组生成AES密钥
SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(aesKey.toCharArray()), "AES");
//6.根据指定算法AES自成密码器
encryptCipher = Cipher.getInstance("AES");
//7.初始化密码器
encryptCipher.init(Cipher.ENCRYPT_MODE, skeySpec);
}
}
public static void initDecryptCipher(String aesKey) throws Exception {
if (decryptCipher == null) {
//5.根据字节数组生成AES密钥
SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(aesKey.toCharArray()), "AES");
//6.根据指定算法AES自成密码器
decryptCipher = Cipher.getInstance("AES");
//7.初始化密码器
decryptCipher.init(Cipher.DECRYPT_MODE, skeySpec);
}
}
public static String hutoolEncrpt(String content,String key){
AES aes=new AES(Mode.ECB, Padding.ISO10126Padding, key.getBytes());
return aes.encryptBase64(content);
}
public static String hutoolDecrpt(String content,String key){
AES aes=new AES(Mode.ECB, Padding.ISO10126Padding, key.getBytes());
return aes.decryptStr(content);
}
public static void main(String[] args) throws Exception {
}
}
4、JSON工具类
java
import java.lang.reflect.Type;
import cn.hutool.json.JSONUtil;
public class JsonUtil {
/**
* JSON串转成对象
*
* @param jsonStr
* @param cls
* @return
*/
public static <T> T fromJson(String jsonStr, Class<T> cls) {
try {
if (null == jsonStr || jsonStr.trim().length() == 0) {
return null;
}
return JSONUtil.toBean(jsonStr, cls);
} catch (Exception e) {
return null;
}
}
/**
* JSON串转成对象
*
* @param jsonStr
* @param typeOfT
* @return
*/
public static Object fromJson(String jsonStr, Type typeOfT) {
if (null == jsonStr || jsonStr.trim().length() == 0) {
return null;
}
return JSONUtil.toBean(jsonStr, typeOfT, true);
}
/**
* 对象转JSON串
*
* @param t
* @return
*/
public static <T> String toJson(T obj) {
if (obj == null) {
return null;
}
return JSONUtil.toJsonStr(obj);
}
}
5、翻页工具类
java
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.io.Serializable;
import java.util.List;
/**
* 分页工具类
*/
public class PageUtils implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private int totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int currPage;
/**
* 列表数据
*/
private List<?> list;
/**
* 分页
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
}
/**
* 分页
*/
public PageUtils(IPage<?> page) {
this.list = page.getRecords();
this.totalCount = (int)page.getTotal();
this.pageSize = (int)page.getSize();
this.currPage = (int)page.getCurrent();
this.totalPage = (int)page.getPages();
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrPage() {
return currPage;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
}
二、特定函数
在java开发中使用最多的就是增删查改翻页查询。所以这几个是比不可少的特定函数。特别是在springboot框架的开发中。像这种具有共性的代码模块,我们可以使用逆向工程生成。
java
import java.util.List;
import java.util.Map;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.ctg.common.util.PageUtils;
import cn.ctg.common.response.ResponseData;
import cn.ctg.common.util.CtgUtils;
import lombok.extern.slf4j.Slf4j;
import cn.ctg.video.entity.MUser;
import cn.ctg.video.service.MUserService;
import cn.ctg.video.constant.MUserConstant;
/**
*
* @Description: 用户Controller
*/
@RestController
@RequestMapping("mUser")
@Slf4j
public class MUserController {
@Autowired
private MUserService mUserService;
@ApiOperation(value = "分页查询用户列表", notes = "分页查询用户列表")
@PostMapping("pageList")
public ResponseData<PageUtils> queryPage(@RequestBody Map<String, Object> param) {
PageUtils pageUtils = mUserService.queryPage(param);
return ResponseData.success(pageUtils);
}
/**
* 查询所有用户列表
* @param
* @return
*/
@ApiOperation(value = "查询所有用户列表", notes = "查询所有用户列表")
@PostMapping("searchAll")
public ResponseData<List<MUser>> searchAll() {
List<MUser> mUserList = mUserService.list();
if(!CtgUtils.isCollectionNull(mUserList)) {
return ResponseData.success(mUserList);
}else {
log.info(MUserConstant.NOT_EXIST);
return ResponseData.success(mUserList);
}
}
/**
* 保存用户
* @param mUser
* @return
*/
@ApiOperation(value = "保存用户", notes = "保存用户")
@PostMapping("save")
public ResponseData<String> save(@RequestBody MUser mUser) {
boolean res = mUserService.save(mUser);
if(res) {
return ResponseData.success(MUserConstant.SAVE_SUCCESS);
}else {
log.error(MUserConstant.SAVE_FAILED);
return ResponseData.error(MUserConstant.SAVE_FAILED);
}
}
/**
* 删除用户
* @param mUser
* @return
*/
@ApiOperation(value = "删除用户", notes = "删除用户")
@PostMapping("delete")
public ResponseData<String> delete(@RequestBody MUser mUser) {
boolean res = mUserService.removeById(mUser);
if(res) {
return ResponseData.success(MUserConstant.DELETE_SUCCESS);
}else {
log.error(MUserConstant.DELETE_FAILED);
return ResponseData.error(MUserConstant.DELETE_FAILED);
}
}
/**
* 根据主键ID更新用户
* @param mUser
* @return
*/
@ApiOperation(value = "根据主键ID更新用户", notes = "根据主键ID更新用户")
@PostMapping("update")
public ResponseData<Boolean> update(@RequestBody MUser mUser) {
boolean res = mUserService.updateById(mUser);
if(res) {
return ResponseData.success(true);
}else {
log.error(MUserConstant.UPDATE_FAILED);
return ResponseData.error(MUserConstant.UPDATE_FAILED);
}
}
/**
* 批量删除用户
* @param mUserList
* @return
*/
@ApiOperation(value = "批量删除用户", notes = "批量删除用户")
@PostMapping("deleteList")
public ResponseData<String> deleteList(@RequestBody List<MUser> mUserList) {
boolean res = mUserService.removeByIds(mUserList);
if(res) {
return ResponseData.success(MUserConstant.DELETE_SUCCESS);
}else {
log.error(MUserConstant.DELETE_FAILED);
return ResponseData.error(MUserConstant.DELETE_FAILED);
}
}
/**
* 根据主键ID查找用户
*/
@ApiOperation(value = "根据主键ID查找用户", notes = "根据主键ID查找用户")
@PostMapping("searchById")
public ResponseData<MUser> searchById (@RequestBody MUser mUser) {
MUser mUserRes = mUserService.getById(mUser.getId());
if (ObjectUtil.isNotEmpty(mUserRes)) {
return ResponseData.success(mUserRes);
}else {
log.error(MUserConstant.QUERY_FAILED);
return ResponseData.error(MUserConstant.QUERY_FAILED);
}
}
}
三、复杂概念
一些复杂概念主要涉及
1、IOC和AOP
什么是 IoCIoC (Inversion of control )控制反转/反转控制。
它是一种思想不是一个技术实现。描述的是:Java 开发领域对象的创建以及管理的问题。例如:现有类 A 依赖于类 B传统的开发方式 :往往是在类 A 中手动通过 new 关键字来 new 一个 B 的对象出来使用 IoC 思想的开发方式 :不通过 new 关键字来创建对象,而是通过 IoC 容器(Spring 框架) 来帮助我们实例化对象。我们需要哪个对象,直接从 IoC 容器里面过去即可。从以上两种开发方式的对比来看:我们 "丧失了一个权力" (创建、管理对象的权力),从而也得到了一个好处(不用再考虑对象的创建、管理等一系列的事情)
什么是 AOP
AOP:Aspect oriented programming 面向切面编程,AOP 是 OOP(面向对象编程)的一种延续。
2、过滤器,拦截器,事务,日志服务,定时器,任务调度等等
什么是过滤器与拦截器?
1.1过滤器(Filter)
java过滤器指的是在java中起到过滤的作用的一个方法。可以在一个请求到达servlet之前,将其截取进行逻辑判断,然后决定是否放行到请求的servlet;也可以在一个response到达客户端之前,截取结果进行逻辑判断,然后决定是否允许返回给客户端。
filter(过滤器) 有如下几个种类(功能):
- 用户授权的filter:filter负责判断用户是否有权限请求该页面。
- 给予过滤判断日志的filter:截取某个用户在本网站上的所有请求。
- 记录轨迹负责解码的filter:规定处理本次请求的解码方式。
需要注意的是,一个filter过滤器可以加在多个servlet控制器上,当然多个filter过滤器也是可以加在一个servlet控制器上的。
由此也是可以看出来,我们使用filter往往是对一些公共的操作进行处理。例如:判断用户权限,解码本次请求等。还比如,我们的web应用中某些页面是需要用户登录后才能访问的,以往我们都是在每个servlet页面加上判断控制,导致代码冗余。有了filter,我们可以定义一个实现了filter的过滤器,让需要判断是否登录的页面都加上这么一个过滤器,可以大大降低代码的冗余程度
1.2拦截器(Interceptor)
java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。
作用域:动态拦截Action调用的对象(也就是我们的controller层)
在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用,AOP可参考 Spring AOP速查笔记。 由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
过滤器与拦截器的区别
1.1 实现原理不同
- 过滤器的实现基于回调函数
- 拦截器基于Java的反射机制【动态代理】实现。
1.2 使用范围不同
- 过滤器是Servlet的规范,需要实现javax.servlet.Filter接口,Filter使用需要依赖于Tomcat等容器。
- 拦截器是Spring组件,定义在org.springframework.web.servlet包下,由Spring容器管理【又有更加丰富的生缪那个周期处理方法,细粒度,且能够使用Spring中的资源】,不依赖Tomcat等容器。
1.3 触发时机不同
- 过滤器:对请求在进入后Servlet之前或之后进行处理。
- 拦截器:对请求在handler【Controller】前后进行处理。
1.4 执行顺序不同
执行顺序 :Filter 处理中 -> Interceptor 前置 -> 我是controller -> Interceptor 处理中 -> Interceptor 处理后
当有两个过滤器或拦截器时:
过滤器:
每一次都将chain对象传入,达到最后接口回调的效果,类似函数的堆栈调用。
拦截器:
preHandle1 -> preHande2 -> 【Controller】 -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterComplention1
preHandle按照注册顺序,后两个与注册顺序相反。
- 一个拦截器的preHandle为false,则之后的所有拦截器都不会执行。
- 一个拦截器的preHandle为true,则这个拦截器的triggerAfterCompletion一定会执行。
- 只有所有的拦截器preHandler都为true,也就是正常执行,postHandle才会执行。
1.5 控制执行顺序方式不同
实际开发过程中,会出现多个过滤器或拦截器同时存在的情况,不过,有时我们希望某个过滤器或拦截器能优先执行,就涉及到它们的执行顺序。
过滤器用@Order注解控制执行顺序,通过@Order控制过滤器的级别,值越小级别越高越先执行。
3、与第三方的一些接口调用,比如支付,邮件,短信,验证码,加解密等等是必须掌握的功能。
四、特定功能
java开发系统中用户的登录注册是最基本的特定功能。
登录用户表的设计
sql
-- Drop table
-- DROP TABLE public.t_user;
CREATE TABLE public.t_user (
id varchar(32) NOT NULL,
user_name varchar(255) NOT NULL,
login_name varchar(255) NOT NULL,
password varchar(255) NOT NULL,
create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_login_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted int4 NOT NULL DEFAULT 0,
pwd_val_time timestamp NOT NULL,
belong_code varchar(8) NULL,
belong_name varchar(255) NULL,
data_type varchar(255) NULL,
phone varchar(255) NULL,
CONSTRAINT t_user_pkey PRIMARY KEY (id)
);