Java阶段二Day07
Java阶段二Day07
文章目录
- Java阶段二Day07
- V17
- UserController
- DispatcherServlet
- Controller
- RequestMapping
- V18
- DispatcherServlet
- HandleMapping
- V19
- BirdBootApplication
- 线程池
- 线程的执行过程
- 线程池API
- 数据库
- 数据库的基本概念
- 数据库管理系统中常见的概念
- SQL分类
- DDL语言-数据定义语言
- 对数据库的操作
- 对数据表的操作
- 教师总结
- 数据库基本概念
- 数据库DataBase
- 定义:
- 例
- 数据库管理系统(DBMS)
- 定义
- 常见的DBMS
- 在JAVA项目中与数据库的结合
- 数据库管理系统中常见的概念
- 库
- 表
- 例
- 库与表的关系
- 库与DBMS的关系
- 如何操作数据库
- 数据库的角色
- 数据库的交互
- 学习重点
- 数据库的连接方式
- 常用的客户端
- SQL语言
- SQL分类
- DDL语言-数据定义语言
V17
利用反射机制重构
DispatcherServlet
,使得将来添加新的业务时DispatcherServlet
不必再添加分支判断(不进行修改)实现:
- 新建包
com.webserver.annotation
- 在
annotation
包下添加两个注解
@Controller
:用于标注哪些类是处理业务的Controller
类@RequestMapping
:用于标注处理某个业务请求的业务方法- 将
com.webserver.controller
包下的所有Controller
类添加注解@Controller
并将里面用于处理某个业务的方法标注@RequestMapping
并指定该方法处理的请求DispatcherServlet
在处理请求时,先扫描controller
包下的所有Controller
类,并找到处理该请求的业务方法,使用反射调用
UserController
package com.birdboot.controller;import com.birdboot.annotations.Controller;
import com.birdboot.annotations.RequestMapping;
import com.birdboot.entity.User;
import com.birdboot.http.HttpServletRequest;
import com.birdboot.http.HttpServletResponse;import java.io.*;/*** 处理与用户相关的业务*/
@Controller
public class UserController {private static File userDir;//表示存放所有用户信息的目录:usersstatic {userDir = new File("./users");if(!userDir.exists()){userDir.mkdirs();}}@RequestMapping("/regUser")public void reg(HttpServletRequest request, HttpServletResponse response){System.out.println("开始处理用户注册");String username = request.getParameter("username");String password = request.getParameter("password");String nickname = request.getParameter("nickname");String ageStr = request.getParameter("age");System.out.println(username+","+password+","+nickname+","+ageStr);//必要的验证if(username==null||username.isEmpty()||password==null||password.isEmpty()||nickname==null||nickname.isEmpty()||ageStr==null||ageStr.isEmpty()||!ageStr.matches("[0-9]+")){response.sendRedirect("/reg_info_error.html");return;}int age = Integer.parseInt(ageStr);//将年龄转换为int值//2User user = new User(username,password,nickname,age);/*File的构造器File(File parent,String child)创建一个File对象表示child这个子项,而它是在parent这个File对象所表示的目录中*/File file = new File(userDir,username+".obj");if(file.exists()){//注册前发现以该用户名命名的obj文件已经存在,说明是重复用户response.sendRedirect("/have_user.html");return;}try (FileOutputStream fos = new FileOutputStream(file);ObjectOutputStream oos = new ObjectOutputStream(fos);){oos.writeObject(user);//保存用户信息完毕//3给用户回馈注册成功页面//要求浏览器重新访问下述地址对应的页面response.sendRedirect("/reg_success.html");} catch (IOException e) {e.printStackTrace();}}@RequestMapping("/loginUser")public void login(HttpServletRequest request,HttpServletResponse response){System.out.println("开始处理登录!!!!");//1获取登录信息String username = request.getParameter("username");String password = request.getParameter("password");//必要验证if(username==null||username.isEmpty()||password==null||password.isEmpty()){response.sendRedirect("/login_info_error.html");return;}//根据该登录用户的名字去定位users下该用户的注册信息File file = new File(userDir,username+".obj");//判断该文件是否存在,不存在则说明该用户没有注册过if(file.exists()){//将该用户曾经的注册信息读取出来用于比较密码try (FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis);){User user = (User)ois.readObject();//读取注册信息//比较本次登录的密码是否与注册时该用户输入的密码一致if(user.getPassword().equals(password)){//密码一致则登录成功response.sendRedirect("/login_success.html");return;}} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}//如果程序可以执行到这里,则说明要么是用户名没输入对,要么是密码没有输入对.都属于登录失败response.sendRedirect("/login_fail.html");}
}
DispatcherServlet
package com.birdboot.core;import com.birdboot.annotations.Controller;
import com.birdboot.annotations.RequestMapping;
import com.birdboot.controller.UserController;
import com.birdboot.http.HttpServletRequest;
import com.birdboot.http.HttpServletResponse;import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;/*** V8新增内容:* 该类是SpringMVC框架与Tomcat整合时的一个关键类* Tomcat处理业务原生的都是调用继承了HttpServlet的类来完成,此时需要进行很多配置* 以及使用时要作很多重复性劳动。* SpringMVC框架提供的该类也是继承了HttpServlet的,使用它来接收处理请求的工作。*/
public class DispatcherServlet {private static File baseDir;//类加载路径private static File staticDir;//类加载路径下的static目录static {try {//定位当前项目的类加载路径baseDir = new File( DispatcherServlet.class.getClassLoader().getResource(".").toURI());//定位类加载路径下的static目录staticDir = new File(baseDir, "static");} catch (URISyntaxException e) {e.printStackTrace();}}/*** service方法实际上是当我们继承了HttpServlet后必须重写的方法* 该方法要求接收两个参数:请求对象与响应对象。* Tomcat在处理请求时就是调用某个Servlet的service方法并将请求与响应对象传入* 来让其完成处理工作的。*/public void service(HttpServletRequest request, HttpServletResponse response) {//获取请求的抽象路径//不能在使用uri判断请求了,因为uri可能含参数,内容不固定。String path = request.getRequestURI();//path:"/regUser"System.out.println(path);//判断该请求是否为请求一个业务/*V17新增内容:当我们得到本次请求路径path的值后,我们首先要查看是否为请求业务:1:扫描controller包下的所有类2:查看哪些被注解@Controller标注的过的类(只有被该注解标注的类才认可为业务处理类)3:遍历这些类,并获取他们的所有方法,并查看哪些时业务方法只有被注解@RequestMapping标注的方法才是业务方法4:遍历业务方法时比对该方法上@RequestMapping中传递的参数值是否与本次请求路径path值一致?如果一致则说明本次请求就应当由该方法进行处理因此利用反射机制调用该方法进行处理。提示:反射调用后要记得return,避免执行后续处理静态资源的操作5:如果扫描了所有的Controller中所有的业务方法,均未找到与本次请求匹配的路径则说明本次请求并非处理业务,那么执行下面请求静态资源的操作*///定位controller目录 使用File访问文件系统时,路径中目录的层级分割是用"/"try {File dir = new File(baseDir,"com/birdboot/controller");//获取该目录下的所有.class文件File[] subs = dir.listFiles(f->f.getName().endsWith(".class"));for(File sub : subs){//遍历每一个.class文件String fileName = sub.getName();//获取文件名String className = fileName.substring(0,fileName.indexOf("."));//根据文件名获取类名//包名的层级分割使用"."Class cls = Class.forName("com.birdboot.controller."+className);//判断该类有没有注解@Controllerif(cls.isAnnotationPresent(Controller.class)){//扫描该类的所有方法Method[] methods = cls.getDeclaredMethods();//遍历每一个方法for(Method method : methods){//判断该方法是否有注解@RequestMappingif(method.isAnnotationPresent(RequestMapping.class)){//获取注解RequestMapping rm = method.getAnnotation(RequestMapping.class);//通过注解对象获取参数String value = rm.value();//对比本次请求是否与该方法注解参数一致?if(path.equals(value)){//一致则说明本次请求应当交由该方法处理//实例化该ControllerObject c = cls.newInstance();//调用该方法处理本次请求method.invoke(c,request,response);return;//处理后解除本次处理请求(避免执行下面处理静态资源的部分)}}}}}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}File file = new File(staticDir, path);if (file.isFile()) {//由于响应对象中状态代码和描述默认值为200,OK因此正确情况下不用再设置response.setContentFile(file);//设置响应头response.addHeader("Server", "BirdServer");} else {response.setStatusCode(404);response.setStatusReason("NotFound");file = new File(staticDir, "404.html");response.setContentFile(file);response.addHeader("Server", "BirdServer");}}
}
Controller
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}
RequestMapping
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {String value();
}
V18
重构代码
上一个版本那种DispatcherServlet
每次处理请求时都要扫描controller
包,这样性能低下,因此改为仅扫描一次实现:
- 在
com.webserver.core
包下新建类HandlerMapping
- 定义静态属性
Map mapping
key:请求路径;value:Method记录处理该请求的方法对象- 在静态块中初始化,完成原
DispatcherServlet
扫描controller
包的工作并初始化mapping
- 提供静态方法:
getMethod()
可根据请求路径获取处理该请求的方法- 在
DispatcherServlet
中处理业务时只需要根据请求获取对应的处理方法利用反射机制调用即可
DispatcherServlet
package com.birdboot.core;import com.birdboot.annotations.Controller;
import com.birdboot.annotations.RequestMapping;
import com.birdboot.controller.UserController;
import com.birdboot.http.HttpServletRequest;
import com.birdboot.http.HttpServletResponse;import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;/*** V8新增内容:* 该类是SpringMVC框架与Tomcat整合时的一个关键类* Tomcat处理业务原生的都是调用继承了HttpServlet的类来完成,此时需要进行很多配置* 以及使用时要作很多重复性劳动。* SpringMVC框架提供的该类也是继承了HttpServlet的,使用它来接收处理请求的工作。*/
public class DispatcherServlet {private static File baseDir;//类加载路径private static File staticDir;//类加载路径下的static目录static {try {//定位当前项目的类加载路径baseDir = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());//定位类加载路径下的static目录staticDir = new File(baseDir, "static");} catch (URISyntaxException e) {e.printStackTrace();}}/*** service方法实际上是当我们继承了HttpServlet后必须重写的方法* 该方法要求接收两个参数:请求对象与响应对象。* Tomcat在处理请求时就是调用某个Servlet的service方法并将请求与响应对象传入* 来让其完成处理工作的。*/public void service(HttpServletRequest request, HttpServletResponse response) {//获取请求的抽象路径//不能在使用uri判断请求了,因为uri可能含参数,内容不固定。String path = request.getRequestURI();//path:"/regUser"System.out.println(path);//判断该请求是否为请求一个业务Method method = HandlerMapping.getMethod(path);if(method!=null){//本次为请求业务//通过方法获取其所属类的类对象(某个Controller)try {Class cls = method.getDeclaringClass();Object obj =cls.newInstance();method.invoke(obj,request,response);} catch (Exception e) {//如果处理业务过程中报错,这是典型的因为服务端处理请求出现错误导致处理失败(500错误)response.setStatusCode(500);response.setStatusReason("Internal Server Error");}}else {File file = new File(staticDir, path);if (file.isFile()) {//由于响应对象中状态代码和描述默认值为200,OK因此正确情况下不用再设置response.setContentFile(file);//设置响应头response.addHeader("Server", "BirdServer");} else {response.setStatusCode(404);response.setStatusReason("NotFound");file = new File(staticDir, "404.html");response.setContentFile(file);response.addHeader("Server", "BirdServer");}}}
}
HandleMapping
package com.birdboot.core;import com.birdboot.annotations.Controller;
import com.birdboot.annotations.RequestMapping;import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;/*** SpringMVC框架使用这个类来维护所有Controller*/
public class HandlerMapping {private static File baseDir;//类加载路径/*请求与对应的处理方法的映射关系key:请求路径(与对应方法上@RequestMapping注解参数一致)value:处理该请求的方法*/private static Map<String, Method> mapping = new HashMap<>();static{try {//定位当前项目的类加载路径baseDir = new File(HandlerMapping.class.getClassLoader().getResource(".").toURI());initMapping();} catch (URISyntaxException | ClassNotFoundException e) {e.printStackTrace();}}/*** 初始化mapping*/private static void initMapping() throws ClassNotFoundException {File dir = new File(baseDir,"com/birdboot/controller");//获取该目录下的所有.class文件File[] subs = dir.listFiles(f->f.getName().endsWith(".class"));for(File sub : subs){//遍历每一个.class文件String fileName = sub.getName();//获取文件名String className = fileName.substring(0,fileName.indexOf("."));//根据文件名获取类名//包名的层级分割使用"."Class cls = Class.forName("com.birdboot.controller."+className);//判断该类有没有注解@Controllerif(cls.isAnnotationPresent(Controller.class)){//扫描该类的所有方法Method[] methods = cls.getDeclaredMethods();//遍历每一个方法for(Method method : methods){//判断该方法是否有注解@RequestMappingif(method.isAnnotationPresent(RequestMapping.class)){//获取注解RequestMapping rm = method.getAnnotation(RequestMapping.class);//通过注解对象获取参数String value = rm.value();//将该方法与其处理的请求路径以key,value形式存入mappingmapping.put(value,method);}}}}}/*** 根据请求路径获取某个Controller下的对应处理方法* @param path* @return*/public static Method getMethod(String path){return mapping.get(path);}public static void main(String[] args) {Method method = getMethod("/regUser");System.out.println(method);}
}
V19
使用线程池管理线程
在主启动类BirdBootApplication
中定义线程池,
并在接收客户端链接后将ClientHandler
交给线程池处理
BirdBootApplication
package com.birdboot.core;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** 主启动类*/
public class BirdBootApplication {private ServerSocket serverSocket;private ExecutorService threadPool;public BirdBootApplication(){try {System.out.println("正在启动服务端...");serverSocket = new ServerSocket(8088);threadPool = Executors.newFixedThreadPool(50);System.out.println("服务端启动完毕!");} catch (IOException e) {e.printStackTrace();}}public void start(){try {while(true) {System.out.println("等待客户端链接...");Socket socket = serverSocket.accept();System.out.println("一个客户端链接了!");//启动一个线程处理该客户端交互ClientHandler handler = new ClientHandler(socket);threadPool.execute(handler);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {BirdBootApplication application = new BirdBootApplication();application.start();}
}
线程池
- 复用线程
- 线程的数量控制
线程的执行过程
- 线程任务:Runnable
- 创建线程:new Thread()
- 启动:start()
- 并发执行中:Running
- 任务执行完毕:Dead
- 线程销毁:gc
线程池API
Executors
:创建线程池的工厂类,用于创建线程池对象ExecutorService
:线程池接口,规定线程池相关功能方法
创建线程池:ExecutorService pool = Executors.newFixedThreadPool(容量)
创建并指派任务:
- 创建任务:实现
Runnable
接口重写run()
方法 - 指派任务:调用线程池方法
pool.execute(任务)
线程池的关闭:
shutdown()
:不再接收新的任务,将现有任务执行完毕结束线程池中所以线程shutdownNow()
:不再接收新任务,中断线程池所有线程
数据库
数据库的基本概念
-
数据库DataBase:保存一组数据的仓库就是数据库
-
数据库管理系统(DBMS):一套可以独立运行的软件,用于维护磁盘上的数据,维护性好,性能好,可扩展性强
常见的DBMS:
- MySQL
- MariaDB
- Oracle
- DB2
- SQLServer
数据库管理系统中常见的概念
-
库:是表的集合,一个库中可以存放若干张表。通常库是服务于项目的。
-
表:是数据的集合,具有一组相同属性的数据存放在同一张表中。
- 行:存放数据
- 列:存放字段
-
数据库的角色:数据库是一个独立运行的软件,并且是以服务端的形式体现的,我们要操作数据库则需要以客户端的角度与服务端建立连接并进行相关的操作
-
数据库的交互:连接数据库后,向其发送
SQL
语句(Structured Query Language 结构化查询语言),数据库会理解该SQL
语句的含义并进行对应操作SQL语句的标准:SQL92标准,所有DBMS都支持SQL92标准,该标准就是操作数据库的“普通话”,但不是所有的数据库操作都在SQL92标准中,不在该标准中的操作,不同的数据库提供的语法可能完全不同,此时这类
SQL
称为“方言” -
常用的客户端
- 命令行
- 图形化界面
- JDBC
- 集成开发环境(IDE)
SQL分类
- DDL:数据定义语言,是操作数据库对象的语言。数据库对象(库,表,视图,索引,序列)
- DML:数据操作语言,是操作表中数据的语言。对表中数据操作的语言(增INSERT,删DELETE,改UPDATE)
- DQL:数据查询语言,是查询表中数据的语言。SELECT语句(学习的重点和难点)
- DCL:数据控制语言,管理数据库的语言(权限分配等,DBA关心的)
- TCL:事务控制语言,控制事务操作
DDL语言-数据定义语言
对数据库的操作
-
新建一个数据库:
CREATE DATABASE 数据库名 [charset = 字符集] # 指定字符集 CREATE DATABASE mydb1 CHARSET = UTF8; CREATE DATABASE mydb2 CHARSET = GBK;
-
查看已创建数据库:
SHOW DATABASES;
-
查看创建数据库时的信息:
SHOW CREATE DATABASE 数据库名
-
删除数据库:
DROP DATABASE 数据库名
-
切换数据库:
USE 数据库名
对数据表的操作
-
创建数据库表
CREATE TABLE 表名(字段名1 类型[(长度)][DEFALUT 默认值][约束],字段名2 类型[(长度)][DEFALUT 默认值][约束], ) [charset = 字符集]
-
查看表结构:
DESC 表名
-
查看表创建时的信息:
SHOW CREATE TABLE 表名
-
查看当前数据库中创建的所有表:
SHOW TABLES
-
修改表名:
RENAME TABLE 原表名 TO 新表名
-
删除表:
DROP TABLE 表名
-
修改表结构,在表末尾追加新字段:
ALTER TABLE 表名 ADD 字段名 类型[(长度) 默认值 约束]
-
修改表结构,在表最开始添加新字段:
ALTER TABLE 表名 ADD 字段名 类型 [(长度) 默认值 约束] FIRST
-
修改表结构,在表中间插入新字段:
ALTER TABLE 表名 ADD 字段名 类型[(长度) 默认值 约束] AFTER 表中现有字段名
-
修改表结构,在表中删除字段:
ALTER TABLE 表名 DROP 字段名
-
修改表结构,在表中修改现有字段:
ALTER TABLE 表名 CHANGE 原字段名 新字段名 类型 [(长度) 默认值 约束]
修改表结构的注意事项
- 修改表结构最好在表中没有数据的情况下进行
- 当表中含有数据时,
- 尽量不修改表中某字段类型,否则可能因为现有数据不满足新修改的类型导致修改失败
- 尽量不缩短字段长度
- 若为字段新添加约束,该字段现有的数据不能违反该约束
教师总结
数据库基本概念
数据库DataBase
定义:
保存一组数据的仓库就是数据库
例
BirdBoot项目中,我们为了保存一组用户信息,创建了一个目录users。里面用若干个文件保存每一个用户信息
此时users目录就可以称为是一个数据库
只不过对于这些数据的维护操作,要么手动,要么通过自己编码来维护。
手动操作效率低
编码来维护:维护成本高,可扩展性差
数据库管理系统(DBMS)
定义
一套独立可运行的软件,用于维护磁盘上的数据。维护性好,性能好,可扩展性强。
常见的DBMS
- MySQL
- MariaDB
- Oracle
- DB2
- SQLServer
在JAVA项目中与数据库的结合
数据库管理系统中常见的概念
库
是表的集合,一个库中可以存放若干张表。通常库是服务于项目的。
表
是数据的集合,具有一组相同属性的数据存放在同一张表中。
行:称为是记录,表中每一条数据
列:称为是字段,每一条记录的属性
例
BirdBoot项目中,涉及到的数据有用户信息,文章信息。用户信息就可以设计一张用户表保存。文章信息可以设计一张文章表保存
库与表的关系
库与DBMS的关系
如何操作数据库
数据库的角色
数据库是一个独立运行的软件,并且是以服务端的形式体现的,我们要操作数据库则需要以客户端的角度与服务端建立连接并进行相关的操作
数据库的交互
我们连接上数据库后,向其发送SQL语句,数据库理解该SQL语句的含义并执行相关操作并回馈结果.
SQL语句的标准:SQL92标准。
所有的DBMS都支持SQL92标准,该标准就是操作数据库的"普通话"。
不是所有的数据库操作都在SQL92标准中,不在该标准中的操作不同的数据库提供的语法可能完全不同,此时这类SQL称为是"方言"
学习重点
学会SQL语句
SQL:全称Structured Query Language
数据库的连接方式
常用的客户端
- 命令行
- 图形化界面
- JDBC
- 集成开发环境(IDE)
SQL语言
Structured Query Language,结构化查询语言
操作数据库的语言
SQL语句不区分大小写,但是好的书写习惯:关键字大写,非关键字小写
SQL分类
-
DDL:数据定义语言,是操作数据库对象的语言。数据库对象(库,表,视图,索引,序列)
-
DML:数据操作语言,是操作表中数据的语言。对表中数据操作的语言(增INSERT,删DELETE,改UPDATE)
-
DQL:数据查询语言,是查询表中数据的语言。SELECT语句(学习的重点和难点)
-
DCL:数据控制语言,管理数据库的语言(权限分配等,DBA关心的)
-
TCL:事务控制语言,事务控制语言。
DDL语言-数据定义语言
对数据库对象进行操作的语言, 涉及到的关键字CREATE,ALTER,DROP
对数据库的操作
新建一个数据库
语法
CREATE DATABASE 数据库名 [charset=字符集]
例
新建一个数据库:mydb
CREATE DATABASE mydb;
注:SQL语句不区分大小写,但是好的书写习惯:关键字大写,非关键字小写
指定字符集
创建数据库mydb1,指定字符集为UTF-8
CREATE DATABASE mydb1 CHARSET=UTF8;创建数据库mydb2,指定字符集为GBK
CREATE DATABASE mydb2 CHARSET=GBK;
查看已创建的数据库
语法
SHOW DATABASES;
查看创建数据库时的信息
语法
SHOW CREATE DATABASE 数据库名
例
SHOW CREATE DATABASE mydb
删除数据库
语法
DROP DATABASE 数据库名
例
DROP DATABASE mydb
切换数据库
语法
USE 数据库名
例
USE mydb1; //切换数据库到mydb1
USE mydb2; //切换数据库到mydb2
练习
题干
1. 创建 db1和db2 数据库 字符集分别为utf8和gbk
2. 查询所有数据库检查是否创建成功
3. 检查两个数据库的字符集是否正确(查看创建时的SQL)
4. 先使用db2 再使用 db1
5. 删除两个数据库
答案
1. 创建 db1和db2 数据库 字符集分别为utf8和gbkCREATE DATABASE db1 CHARSET=UTF8CREATE DATABASE db2 CHARSET=GBK
2. 查询所有数据库检查是否创建成功SHOW DATABASES
3. 检查两个数据库的字符集是否正确(查看创建时的SQL)SHOW CREATE DATABASE db1SHOW CREATE DATABASE db2
4. 先使用db2 再使用 db1USE db2USE db1
5. 删除两个数据库DROP DATABASE db1DROP DATABASE db2
表操作
创建表
语法
CREATE TABLE 表名(字段名名1 类型[(长度)] [DEFALUT 默认值] [约束],字段名名2 类型,...
)[CHARSET=字符集]
例
准备一个数据库mydb并使用
CREATE DATABASE mydb; 创建数据库mydb
USE mydb; 切换到mydb,那么后面创建表都是创建到这个库中创建一张表user,保存用户信息(用户名,密码,昵称,年龄)
CREATE TABLE user(id INT, 类型是方言,不同数据库不同,mysql中整数为INT,oraclet为Numberusername VARCHAR(32), 字符串类型是VARCHAR,长度为字节量,如果是UTF-8编码32字节可以存password VARCHAR(32), 10个汉字。nickname VARCHAR(32),age INT(3) 对于整数而言,长度表示保存的数字位数。
)
查看表结构
语法
DESC 表名
例
查看user表的结构
DESC user
查看表创建时的信息
语法
SHOW CREATE TABLE 表名
例
SHOW CREATE TABLE user
查看当前数据库中创建的所有表
语法
SHOW TABLES
修改表名
语法
RENAME TABLE 原表名 TO 新表名
例
将user表改名为userinfo
RENAME TABLE user TO userinfo
删除表
语法
DROP TABLE 表名
例
删除表userinfo
DROP TABLE userinfo
练习
题干
1.创建数据库mydb3 字符集gbk 并使用
2.创建t_hero英雄表, 有名字和年龄字段
3.修改表名为hero
4.查看表hero的信息
5.查询表hero结构
6.删除表hero
7.删除数据库mydb3
答案
1.创建数据库mydb3 字符集gbk 并使用CREATE DATABASE mydb3 CHARSET=GBKUSE mydb32.创建t_hero英雄表, 有名字和年龄字段CREATE TABLE t_hero(username VARCHAR(32),age INT(3) )3.修改表名为heroRENAME TABLE t_hero TO hero4.查看表hero的信息SHOW CREATE TABLE hero5.查询表hero结构DESC hero6.删除表heroDROP TABLE hero7.删除数据库mydb3DROP DATABASE mydb3
修改表结构
准备一张表
CREATE TABLE hero(name VARCHAR(32),age INT(3)
)
添加一个字段
在表末尾追加新字段
语法
ALTER TABLE 表名 ADD 字段名 类型[(长度) 默认值 约束]
例
向表hero的末尾添加一个新字段gender,它的类型是字符串,长度占10个字节
ALTER TABLE hero ADD gender VARCHAR(10)
在表最开始添加字段
语法
ALTER TABLE 表名 ADD 字段名 类型 FIRST
例
在hero表最开始添加id字段,类型为int
ALTER TABLE hero ADD id INT FIRST
在表中插入新的字段
语法
在表中现有的字段后面添加新字段
ALTER TABLE 表名 ADD 字段名 类型 AFTER 表中现有字段名
例
在name字段后面添加密码pwd字段
ALTER TABLE hero ADD pwd VARCHAR(32) AFTER name
删除字段
语法
ALTER TABLE 表名 DROP 字段名
例
将hero中的pwd字段删除
ALTER TABLE hero DROP pwd
修改表字段
语法
ALTER TABLE 表名 CHANGE 原字段名 新字段名 类型[长度 默认值 约束]
例
修改hero表中的年龄字段长度为5
ALTER TABLE hero CHANGE age age INT(5)
修改hero表中的年龄字段为字符串,长度为20字节
ALTER TABLE hero CHANGE age age VARCHAR(20)
修改hero表中的gender字段,改名为nickname 类型为字符串,长度30字节
ALTER TABLE hero CHANGE gender nickname VARCHAR(30)
修改表结构的注意事项
- 修改表结构最好是在表中没有数据的情况下进行
- 当表中含有数据时
- 尽量不修改表中某字段的类型,否则可能因为现有数据不满足新修改的类型导致修改失败
- 尽量不缩短字段长度
- 若为字段新添加约束,该字段现有的数据不能违反该约束
综合练习
题干
1.创建数据库mydb4 字符集utf8并使用
2.创建teacher表 有名字(name)字段
3.添加表字段: 最后添加age 最前面添加id(int型) , age前面添加salary工资(int型)
4.删除age字段
5.修改表名为t
6.删除表t
7.删除数据库mydb4
答案
#创建数据库mydb4字符集utf8并使用
CREATE DATABASE mydb4 CHARSET = utf8;
# 创建teacher表有名字(name)字段
CREATE TABLE teacher(name VARCHAR(255) NOT NULL
);
#添加表字段:最后添加age最前面添加id(int型),age前面添加salary工资(int型)
ALTER TABLE teacher ADD age CHAR(1);
ALTER TABLE teacher ADD id INT(32) FIRST;
ALTER TABLE teacher ADD salary INT(32) AFTER id;
# 删除age字段
ALTER TABLE teacher DROP age;
# 修改表名为t
ALTER TABLE teacher RENAME TO t;
# 或
RENAME TABLE teacher TO t;
# 删除表t
DROP TABLE t;
#删除数据库mydb4
DROP DATABASE mydb4;
相关文章:

Java阶段二Day07
Java阶段二Day07 文章目录 Java阶段二Day07V17UserControllerDispatcherServletControllerRequestMapping V18DispatcherServletHandleMapping V19BirdBootApplication 线程池线程的执行过程线程池API 数据库数据库的基本概念数据库管理系统中常见的概念 SQL分类DDL语言-数据定…...

React Native iOS打包详细步骤
一、在自己项目的iOS文件夹下新建一个文件夹取名bundle 二、将打包命令写到项目package.json文件里,终端执行 npm run bundle-ios 先添加如下(注意:这里写的路径"./ios/bundle"就是上面bundle创建的文件夹):…...
I/O复用函数,poll和epoll的用法与select、poll、epoll的区别
1.poll的接口介绍 poll系统调用和select类似,也是在指定时间内轮询一定数量的文件描述符,已测试其中是否有就绪者。poll的原型如下: # include <poll.h> int poll(struct pollfd*fds,nfds_t nfds,int timeout); poll系统调用成功返回就…...

大数据周会-本周学习内容总结011
开会时间:2023.04.23 15:00 线下会议 目录 01【spark】 02【es同步mysql】 03【下周任务】 01【spark】 尚硅谷大数据技术Spark教程-笔记01【Spark(概述、快速上手、运行环境、运行架构)】尚硅谷大数据技术Spark教程-笔记02【SparkCore&am…...
常见的NoSQL数据库介绍
目录 一、NoSQL概述 二、为什么用NoSQL 三、NoSQL特点 四、NoSQL的分类 五、NoSQL适用场景 六、NoSQL不适用场景 一、NoSQL概述 NoSQL(NoSQL Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。 NoSQL 不依赖业务逻辑方式存储…...

记录安装Nodejs和HBuilderX搭建、部署微信小程序开发环境(一)
文章目录 1 前言2 注册小程序账号3 安装微信开发者工具4 安装Nodejs和HBuilderX4.1 windows用户安装Nodejs4.2 macos/linux用户安装Nodejs4.3 安装HBuilder X 5 创建项目5.1 新建一个项目5.2 进行基本配置 6 HBuilderX同步微信开发者工具6.1 打开服务端口6.2 调用微信开发者工具…...
(一)pyahocorasick和marisa_trie,字符串快速查找的python包,自然语言处理,命名实体识别可用的高效包...
Pyahocorasick Pyahocorasick是一个基于AC自动机算法的字符串匹配工具。它可以用于快速查找多个短字符串在一个长字符串中的所有出现位置。Pyahocorasick可以在构建状态机时使用多线程,从而大大加快构建速度。 安装Pyahocorasick Pyahocorasick可以使用pip命令进行安…...

基于Java+SpringBoot+vue+element驾校管理系统设计和实现
基于JavaSpringBootvueelement驾校管理系统设计和实现 博主介绍:5年java开发经验,专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 …...
Unity中值类型和引用类型及使用时的注意事项
什么是值类型,什么是引用类型,Unity中值类型有哪些,引用类型有哪些,使用时需要注意些什么? 一、值类型和引用类型的概念 A. 值类型 值类型是指变量直接存储其值的数据类型,变量的值被保存在栈中࿰…...

PM510V16 3BSE008358R1嵌入式卡件用于励磁系统多用于工业发电
PM510V16 3BSE008358R1嵌入式卡件用于励磁系统多用于工业发电 物联网与工业自动化控制系统的联系 当今,物联网可谓是在各大媒体出镜率最高、而且与“智能”联系密切的名词之一。从“管理、控制、智能”的角度来看,其实物联网与工业自动化是一脉相承的…...

AI 这是要杀疯啦!
ChatGPT 是基于 GPT 系列大模型开发出来的一个对话场景的 Demo,它已经让我们见识到了大模型的威力。 但有些开发者的胃口不满足于此,已经开始尝试“突破” AI 的边界了,本文推荐 5 个人工智能的开源项目。其中前两个项目,让人细思…...
【精品示例】超实用Python爬虫入门实例——做一个优质舔狗
引言 最近发现了一个有意思的网站,里面充斥了大量的舔狗箴言。作为一个爬虫发烧友怎么能错过此等机会,咱们直接就是上才艺! 类的编写 本次爬虫使用了多协程的方案进行,保证了爬虫的速度。在这里我们新建一个爬虫类,…...

TCP流量控制与拥塞控制
什么是流量控制 一条TCP连接的每一侧主机都为该连接设置了接收缓存。当该TCP连接接收到正确的、有序的报文段,就会将数据放入接收缓存。相关联的应用会从缓存中读取数据。 如果发送者发送数据过快、过多,而接收方的应用程序从缓冲区读取的速度较慢&…...

Java_异常
Java_异常 1.什么是异常 生活中的异常:感冒发烧、电脑蓝屏、手机死机等。 程序中的异常:磁盘空间不足、网络连接中断、被加载的资源不存在等。 程序异常解决办法:针对程序中非正常情况,Java语言引入了异常࿰…...

自动化工具 接口自动化测试引擎
一、前言: 1、解决痛点:接口自动化测试用例需要人去开发、去维护。 2、实现第一性原理:根据定义的测试策略自动生成接口测试用例。 二、引擎优势: 1、提升人效:降低传统方式中接口测试开发与维护的工作量。 2、覆盖更…...
十三、详解Kubernetes的存储管理器
Kubernetes是一个开源的容器编排系统,它可以自动化地管理容器的部署、扩展和运维。在Kubernetes中,存储管理器是一个重要的组件,它负责管理容器的存储资源,包括持久化存储和临时存储。 Kubernetes的存储管理器主要有以下几个功能: 提供持久化存储:Kubernetes的存储管理器…...
java版 工程管理系统源码之提高工程项目管理软件的效率
高效的工程项目管理软件不仅能够提高效率还应可以帮你节省成本提升利润 在工程行业中,管理不畅以及不良的项目执行,往往会导致项目延期、成本上升、回款拖后,最终导致项目整体盈利下降。企企管理云业财一体化的项目管理系统,确保…...

VMware 安装 MS-DOS7.10 并配置网络
VMware 安装 MS-DOS7.10 并设置软盘共享 1. 新建虚拟机2. 开机2.1. 这几个地方都可以开机2.2. 手速慢,进不了BIOS的朋友可以点这里 安装 MS-DOS7.101. 先选 1 安装 MS-DOS7.10 回车2. 欢迎页面,客气一下而已,继续 Next3. 继续王婆卖瓜4. 这步…...

嵌入式51单片机04-矩阵按键系列
文章目录 矩阵按键一、矩阵按键基础知识二、矩阵按键系列代码1. 矩阵按键操作(显示数字)(1)仿真电路图(2)源代码(3)实验结果 2. 矩阵按键操作(控制数码管)&am…...

某安全对抗行走APP逆向分析
1.定位url 抓包: https://api5.xxxx.com/xxx-rest-service/message/fun_getnearby 看一下参数: opentime:时间戳 reqdata:base64编码 sign 未知,需要解密 # -*- coding: utf-8 -*- # @Author : Codeooo # @Time : 2022-10-14import frida, sysm199a = "&qu…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...