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…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...