# mysql
```markdown
DDL库的增删查改
创建自己的数据库
----create database 库名
举例:create database javaEE
----判断再去创建:create database if not exists 库名
举例:create database if not exists javaEE
删除库
----drop database 库名
举例:drop database javaEE
----判断是否存在再删 drop database if exists
举例:drop database if exists javaEE
查询创建数据库的默认字符集格式
----show create database javaEE
-- DDL之表的增删查改
创建表的前提:进入库中
use javaEE
Database changed
--查询这个库中的所有元素
show tables;
Empty set(0.00 sec)为空
创建表的语法
create table 表名(
字段名称1 字段类型1
字段名称2 字段类型2
...
);
字段类型 :mysql
varchar(字符个数)-----代表String 字符串
int 整数类型 默认的字符个数int(11):当前真实age年龄的长度(所占的实际字符数)整数默认int
举例
age int
int(指定字符个数):int(4)
举例
age int(4)----0007
date:日期
datetime:日期+时间
timestamp:时间戳(即时时间)
插入某个指定的时间:当前的那个日期+时间
doblle(3,2):这个字段值是3位数,小数后保留两位
举例:3.25
double: 999.0
```
# 创建一个表
```
创建一个人类表
create table person(
id int
name varchar(20),
gender varchar(5),
address varchar(50);
email varchar(50)
);
Query OK, 0 rows affected (0.04 sec)-----显示成功
```
# 查询表
```
查询表的结构
desc 表名
desc person;
```
# 修改表的名称
```
修改表的名称
alter table 表名 change 旧字段的名称 新字段的名称 数据类型
alter table person change gender sex varchar(5);
```
# 修改字段类型
```
修改字段类型
alter table 表名 modify 字段名称 新的字段类型
alter table person modify address varchar(100);
查询 desc person
```
# 添加新的列
```
添加一个新的列
alter table 表名 add 新的字段名称 类型
alter table person add socre double(3.1);
desc person;
```
# 修改表
```
修改表:将某一个字段删除
alter table 表名 drop 字段名称
alter table person drop email
desc person
```
# 复制一张新的表
```
复制一张新的表和之前的表相同
create table 新的的表名 like 以前的表名
create table student like person;
```
# 修改表的名称
```
修改表的名称
alter table 以前表名 rename to 新的表名
alter table person rename to teacher;
```
# 删除表
```
删除表
drop table 表名;
drop table teacher;
```
# 数据库的DML语句
# 插入语句
```markdown
给表中插入数据 insert into 语句
语法一:一次性插入全部的字段值 insert into 表名 values(字段名称1的值,字段名称2的值....);
insert into student values(1,'张三','男','西安市','1980-05-04;);
insert into student values(2,'李四','男','西安市','1985-05-24;);
语法二:插入部分字段
insert into 表名(字段名称1,字段名称2...) values(值1,值2,值3...);
insert into student(id,name,sex,address) values (3,'赵云','男','王者峡谷');
语句三:一次性插入多条语句
insert into 表名 values(值1,值2...),(值1,值2...)...;
insert into stuednt values(4,'马三炮','男','斗罗大陆','1840-05-23'),
insert into stuednt values(5,'唐三','男','斗罗大陆','1880-06-23'),
insert into stuednt values(6,'小舞','女','斗罗大陆',1540-04-23);
注意事项:插入字段值的时候,必须和当前字段的先后顺序一一对应
```
# 修改语句
```markdown
修改表的语句--update
修改的时候需要使用where 条件语句
update 表名 set 字段名称 = 值 where 其他字段
修改赵云的出生日期
update student set birthday = '1980-06-23' where id =3;
```
# 修改多个字段
```
修改多个字段
update student set anme = '赵无极' ,sex = 'nan',where id = 4;
```
# 批量修改
```markdown
批量修改(不建议使用)
update 表名 set 字段名称 = 值;
update student set address = '西安市雁塔区';
```
# 删除语句
```markdown
删除语句
delete from 表名 where 带条件删除
delete from student where id = 6;
如果不带条件删除的是全表记录
delete from 表名
delete from student;
另一种删除,删除的是全表的记录
truncate table 表名
truncate table student;
```
# truncate table 表名 ;它和 delete from 表名 ; 两者有什么区别
```markdown
delete from 表名 ;仅仅只是删除表的记录,
不会删除这个表的结构,那么针对自增长约束的字段不影响
后者TRUNCATE TABLE 表名 ;删除了表,
它重新创建一张一模一样的空表,(表的结构存在)
前一些自增长的主键约束(数据库约束)者这个语法它会将影响
```
# 创建一张新的表,并id编号,带一个自增长主键约束
```markdown
create table student(
id int primary key auto_increment,---id 自增长主键(唯一且非空)
name varchar(20),
sex varchar(5),
address varcher(50),
birthday date
);
insert into student(name,sex,address,birthday) values
('文章','男','西安市','1981-02-27'),
('王宝强','男','西安市雁塔区','1995-10-30'),
('张佳宁','女','北京市','1990-10-30'),
('李云迪','男','北京市朝阳区','1981-10-30');
最基本的查询的语句:查询全表:
开发中,不能写*,将全部字段名称写上
select * from student;
```
# 查询语句
```markdown
查询语法:DQL语句 (数据库查询语句是最多的!)
select 全部字段名称 from student ;
如果自己测试查询可以使用 * 去代替所有(通配符号)
查询语句:查询指定字段
select
id,
NAME,
age,
address
from
student ;
-- 查询语句:查询指定字段的时候指定别名 字段名称后面 as 别名名称 (as可以省略)
selecr
id AS '编号',
NAME AS '姓名',
age AS '年龄',
sex AS '性别',
address AS '地址',
math AS '数学成绩',
english '英语成绩' -- as 省略了
from
student;
-- 一般查询时候,表的名称一旦很长,给表起别名;访问字段使用表的别名.字段名称 (多表查询使用多)
select
s.`id` '编号',
s.`name` '姓名',
s.`age` '年龄',
s.`address` '地址'
from
student s; -- 给表起了个别名 s (as省略可以不写)
-- 查询地址这个字段
select
address '地址'
from
student ;
-- 查询字段的时候去重
select
DISTINCT(address) -- 数据库的DISTINCT(字段名称),可以实现字段去重
from student ;
-- 查询所有的学生的数学成绩和英语成绩的总分
select
id '学号',
NAME '姓名',
(math+english) '总分'
from
student ;
-- 两个数据类型一致:int,求和 举例:英语和数学字段;
-- 如果有一个字段的值位null(空值),没有意义,数学+NULL = NULL
-- 数据库的函数 ifnull(字段名称,预期值) ;
select
id '学号',
NAME '姓名',
math+IFNULL(english,0) '总分'
from
student ;
select * from student ;
```
public static void main(String[] args) throws ParseException,ClassNotFoundException,Exeption{ //方法声明上 :可能性
//给定日期文本字符串
String dateStr = "2021-11-1" ;
//dateStr---->Date格式: 解析
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
//解析
Date date = sdf.parse(dateStr) ; //这个方法本身就抛出异常 throws ParseException
//使用date即可
System.out.println("-----------------------------------------") ;
method() ;
}
//throw:通过方法体中逻辑语句进行处理
public static void method(){
int i = 10 ;
int b = 0 ;
if(b!=0){
System.out.println(i/b) ;
}else{
throw new ArithmeticException() ;
}
}
//throws和throw的区别
1)使用位置不同
throws:跟在方法上,而且可以跟多个异常类名,中间逗号隔开
throw:方法体的语句中
2)处理方式不同
throws:它的处理交给调用者处理,谁调用这个带throws的方法,谁就需要进行处理
throw:它的处理交给方法体中逻辑语句处理;
3)是否出现的可能性
throws:可能出现问题
throw:表示执行某段代码一定会出现这个异常
4)后面是否跟的是对象
throws:后面跟的异常类名
throw:后面的异常对象 new XXXExeption() ;
DQL语句的其他查询, 高级查询
wher条件后跟的表达式(关系运算符/逻辑运算符 ||(or) &&(and) between....and )
比较运算符 > ,<, <=,>=,=; != 等价于 <> ;
逻辑运算符 && 等价于and ,between || 等价于or
某个字段在是某个集合中的一个的时候:字段名称 in(值1,值2,值3...)
查询为null的信息
is null
查询部位null的信息
is not null
模糊查询
模糊查询 关键字 like
select 字段列表 from 表名 where 字段名称 like '包含%%符号和下划线_'
%:代表任意的字符 姓名 姓李的人 '%李%'
_:代表的是单个字符 姓名为两字符的'__' -------两个下划线
聚合函数
count (字段名称)查询总记录的 max(字段名称):求最大值 min(字段名称):求最小值 sum(字段名称):针对某个字段列表进行求和 avg(字段名称):针对某个字段列求平均分分组查询
分组查询:group by
分组查询的时候可以查询分组的字段
按照性别分组查询
select gender from 表名 group by
注意:group by后面不能使用聚合函数
筛选(过滤)having
一般结合group by使用;
举例:
按照性别分组,查询他们的数学的平均分以及总人数
1):数学成绩不大于70分的人不参与分组
2):筛选出总人数大于2的一组
SELECt
sex '性别',
AVG(math) '数学平均分',
COUNT(id) '总人数'
FROM
student
WHERe
math > 70 -- 条件
GROUP BY
sex -- 分组
-- 筛选出总人数大于2的一组
HAVINg
COUNT(id) > 2 ;
having和group的区别
having后面可以使用聚合函数,而group by 的后面不能使用聚合函数查;
如果存在where 语句,group by,having,先where条件,然后分组group by ,
然后筛选having;
分页查询
分页查询(重点)limit (mysql和oracle有方言差异这个语法上)
select 字段列表 from 表名 limit 起始行数(起始索引),每页显示的条数;
起始行数(起始索引):从零开始计算= (当前页码减一)*每页显示的条数
数据库的约束
约束:约束用户操作表时候的行为,防止无意义的数据在表中存在 默认约束 default 非空约束 not null 唯一约束 unique 主键约束 primary key (非空且唯一) 自增长约束 auto_incrment 外键约束 foreign key 外键约束基础,可以进行级联操作 通过修改表的语句添加外键约束 constraint-----声明 外键名称(自己指定) foreign key-----(从表的字段)作用在外键上 references----关联与主表的主键 通过sql语句:修改表语句将外键约束删除 alter table 表名 drop foreign key 外键的名称添加外键约束的同时,添加级联删除和级联修改
alter table 表名 add ConSTRAINT dept_emp_fk -- 声明 跟的外键名称 FOREIGN KEY (dept_id) -- 作用在外键上 REFERENCES dept(id) -- 关联与主表的主键id ON DELETE CASCADE ON UPDATE CASCADE数据库备份
数据库的备份:需要将数据库进行存储(计算机磁盘上或者是硬盘)
方式1:命令行的方式
方式2:图形界面化的方式:简单/直观/易于上手
进入dos控制台:mysqldump -uroot -p密码 数据库 > 磁盘地址...
数据库的还原
方式1:命令行方式 mysql8---进入mysql自动控制台或者dos登录mysql 先将数据库删除掉,重新创建一个新的库,使用这个use 库名 souce 将备份的地址 (自动将原先备份的库中的表数据全部执行) 方式2:图形界面化 在sqlYog或者navicat里面都可以用,直接将库选中, 删除,删除之后, 在创建的新库右键---选择 import---> Execute Sql scripts:执行sql脚本 选择备份的地址,直接执行sql文件!Properties属性集合类的特有遍历方式以及src下面的xx.properties如何读取
//创建属性集合列表,他继与Hsahtable表与表之间的关系键和值String Properites prope = new Properites(); //读取src下的文件 InputStream inputStream =类名.class.getClassLoader().getResouerStream("xx.properties") //获取配置文件中的key---对应的value Set keySet = prop.stringPropertyNames() ; for(String key :keySet){ //通过键获取值 String value = prop.getProperty(key) ; //key---value获取 } //将配置文件添加到属性集合中 prop.load(inputStream);
一对多(常见)
分类表和商品表
多对多的关系
采用中间表完成 举例:学生表和课程表
一对一的关系
是一种特例, 举例:有一个人对应一个身份证
数据库的三大范式
1NF
第一范式:数据库表中的每一列是不可再拆分的原子数据项(是一个独立的列)
2NF
第二范式:满足第一范式的基础上,每一张表的非主键字段必须完全依赖与主键字段,不能产生部分依赖
3NF
第三范式:满足第二范式的基础上(非主键字段必须完全依赖主键字段)非主键字段不能产生传递依赖
主键------非主键字段----非主键字段
多表查询
分类:
内连接查询
隐式内连接 条件:where
显示连接 条件: inner join(inner可省略)表名2 on 连接条件
多表查询,连接条件不是很多的情况下:
尽量采用隐式内连接使用where(sql优化的一种)
外连接查询
左外连接:
左外连接(推荐):将表名1中所有的数据全部查询以及他们的交集的数(满足连接条件数据)据查询出来
右外连接
将右表中所有的数据全部查询以及他们的交集的数(满足连接条件数据)据查询出来!
子查询
单行单列
利用where条件后面的可以携带比较运算符<=,>=,<,>,赋值运算符 =
多行多列
查询时利用or或者in语句
复杂查询
按照需求给定的已知的条件查询,查出的结果------当做一张虚表继续和当前表进行联合查询
举例:
select
字段名称
from
(select
字段名称
from
emp
where
判断条件)
LEFT OUTER JOIN
列表
ON
条件
创建视图
create view 视图表 as select 语句;
格式:
create view
mnyview(表名)----------一张虚表
as
select
字段名称
from
表名
where
判断条件
查询,修改和删除视图
查询视图
select * from myciew;
修改视图
alter view 视图名字(虚拟表名称) as select语句 条件查询 with check option(检查语法校验)
删除视图
drop view myview;
修改或者添加/删除的时候,可能会造成基本的数据被更改,
但是并不是所有的执行都可以操作!
不能更改视图的原因
情况一
当使用聚合函数的时候
情况二:
视图中不能使用系统或者用户变量
mysql中的用户变量----@变量名
全局变量----@@变量名
情况三:
临时表中不能创建视图
创建临时表
create temporary table 表名(字段名称);
查看临时表:
select * from 临时表名;
数据库的事务
概念:
在执行某个业务功能中,当这个业务功能它同时执行多个sql语句,将这个多个sql语句的执行过程看成一个整体,要么同时执行成功,要么同时执行失败!
格式
开启业务 -- start transaction
业务功能 -- 同时执行多条sql语句,一条语句失败,就整体失败
回滚--rollback 默认回滚到起始点-------如果出问题直接回滚
永久储存---commit
事务的特点
ACID:传统型事务 原子性:事务是一个不可拆分的,是一个整体 一致性:事务在操作业务数据的前后,总量保持不变 隔离性:事务和事务之间----也就是一个业务和一个业务之间的独立的,不能互相影响 持久性:对数据的修改,一旦提交commit,对数据的操作是永久性的,即时关机-或者服务器宕机,下次开机还是存在的事物的隔离级别
select @@transaction_isolation;
--mysql的默认的事物级别:repeatable rand:可以重复读
read uncommitted;读未提交 安全性最差,执行效率高 脏读会出现(最危险最严重的)
read committed ;读已提交 安全性相对第一种安全,防止脏读,但是出现不可重复读
repeatable read;可重复读 mysql默认级别,能够防止脏读,不可重复读
serializable ;串行话 安全性最高的
设置隔离级别
set global transaction isolation level 级别的名称
反射
Jvm在加载类的时候,引导类的加载器-----校验Java代码的语法,如果语法存在问题,编译报错,没有问题---执行代码
宗旨:
要获取类的或者接口的字节码文件对象
获取构造器对象Constructor,创建类对象
获取成员变量所在的对象Field,给成员变量赋值
获取成员方法所在的对象Method,调用成员方法并去使用它
如何通过反射获取构造方法的类对象
//类的无参构造:公共的
Class cla = Class.froname("类的全限定名称");
//直接在创建类对象:方式一
Object classObject = cla.newInstance();
//方式二:
Constructor con = cla.getConstructor();
//创建当前类实例
Object obj = con.newInstance();
//带参构造方法:Private,有三个参数 String,int,String
Class cal = Class.forName("类的全限定名称");
//获取构造器
Constructor con2 = cla.getDeclaredConstructor(String.class,int.class,String.class) ;
//取消Java语言访问检查
con2.steAsscessiable(true);
//创建类的实例
Object obj23 = con2.newInstance("张三丰",86,"男");
如何通过反射获取成员变量的类对象Field,给变量赋值
//成员变量:public修饰的
Class cla = Class.froname("类的全限定名称");
//获取这个无参构造方法的类对象:Constructor
Constructor con = cla.getConstructor();
//创建当前类实例
Object obj = con.newInstance();
//获取成员变量所在的Field对象
Field myField = cla.getField("成员变量名称");
myField.set(obj,"hello");
System.out.println(obj)
如何通过反射获取成员方法的类对象Method,调用方法
//成员变量:public修饰的
Class cla = Class.forName("类的全限定名称");
//获取这个无参构造方法的类对象:Constructor
Constructor con = cla.getConstructor();
//创建当前实例
Object obj = con.newInstance();
//字节码文件----成员方法Method类对象
//public String show(String str,int i){
//return str+i;
//}
Method m = cla.getMethod("show",String.class.int.class);
//底层调用Object invoke方法(Object obj,Object...value)
Object stringObj = m.invoke(ibj,"hello",10);
//输出
System.out.println(stringObj)
Java代码经历的上阶段
SORUCE:源码阶段
CLASS:编译---类的加载阶段
RUNTIME:运行阶段
获取字节码文件的三种方式
第一种:
Object类的getClass()方法----对象名.getClass()
第二种:
任意类型的Java类型的class属性----类型/接口.class
第三种:
Class类中静态方法
Class.forName("类或接口的全限定名称");//包名.类名:全限定名称
动态代理
jdk动态代理-----必须存在接口-----通过放射方式完成
代理:
最终目的使用代理角色帮助真实角色完成事情
程序中就是对业务功能进行增强
UserDao接口
void add() ;
void updte() ;
void delete() ;
void find() ;
java.lang.reflect.Proxy
public static Object newProxyInstance(
ClassLoader loader,
Class[] interfaces,
InvocationHandler handler);//接口 基于代理的处理程序,需要对业务功能代码进行增强
自定义类实现InvocationHandler,重写invoke方法,完后方法增强
jdbc的入门七大步骤
步骤:
1)导入数据库包
2)注册驱动
3)获取数据库的连接对象
4)准备sql语句
5)通过连接对象创建执行对象
6)执行sql语句
7)释放资源
实现步骤
//核心代码
//1)导包----jar包 mysql驱动包
//2)注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//3)获取数据库的链接对象
//驱动管理员的类DriverManager
//public static Connection getConnection(String url, // url:连接数据库的地址:
// String user, 数据库的用户名
// String password) 密码 throws SQLException---异常
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/数据库名称?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
"root",//------账号
"root"//-------密码);
//4)准备sql语句
String sql = "inster into student values(列表信息)" ;
//5)通过链接对象创建执行对象Statement
Statement state = con.createStatement();
//6)执行sql语句.3
int count = state.executeUpdate(sql);
System.oout.println("影响了"+count+"行");
//7)释放资源
state.close();//执行对象
con.close();//链接对象
删除和修改
public class JdbcDemo {
public static void main(String[] args) {
Connection connection = null ;
Statement stmt = null ;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver") ;
//获取连接对象
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/ee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
"root",
"123456"
) ;
//准备sql
String sql = "delete from account where id = 2" ;
// String sql = "update account set money = 2500 where id = 2" ;
//通过连接对象获取执行对象
stmt = connection.createStatement() ;
//执行sql
int count = stmt.executeUpdate(sql);
if(count>0){
System.out.println("添加成功...");
}
System.out.println("影响了"+count+"行");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//释放资源
if(stmt!=null){
try {
stmt.close() ;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close() ;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
封装之后的增删查改
package JdbcDome;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
@SuppressWarnings("ALL")
public class JdbcUtilsDome {
private static String url = null;
private static String user = null;
private static String password = null;
private static String driverClassName = null;
private JdbcUtilsDome(){}
static {
try {
//创建一个空的属性集合列表Properties
Properties p = new Properties();
//读取src下的JdbcUtils.properties
InputStream inputStream = JdbcUtilsDome.class.getClassLoader().getResourceAsStream("JdbcUtils.properties");
//获取配置文件中的内容
p.load(inputStream);
//获取配置文件中的key---对应的value
url = p.getProperty("url");
user = p.getProperty("user");
password = p.getProperty("password");
driverClassName = p.getProperty("driverClassName");
//注册驱动
Class.forName(driverClassName);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//封装获取链接对象的功能
public static Connection getConnection(){
Connection connection = null ;
try {
//使用驱动管理类
connection = DriverManager.getConnection(url,user,password) ;//从配置文件中获取
return connection ;
} catch (SQLException e) {
e.printStackTrace();
}
return null ;
}
//释放资源
public static void close(ResultSet rs, Statement stmt, Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//将释放资源添加到功能中
public static void close( Statement stmt, Connection con){
close(stmt,con);
}
}
package JdbcDome;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcUtilsTest {
public static void main(String[] args) {
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
con = JdbcUtilsDome.getConnection();
//添加元素
//String sql = "insert into student values(8,'龙龟','男','h5',34,88)";
//修改元素
//String sql = "update student set name = '易大师' where id = 8";
//删除元素
//String sql = "delete from student where id = 8 ";
//查询数据
String sql = "select * from student ";
try {
stmt = con.createStatement();
rs = stmt.executeQuery(sql);
System.out.println("编号t姓名tt性别tt课程t年龄t成绩");
while (rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
String gender = rs.getString(3);
String course = rs.getString(4);
int age = rs.getInt(5);
int score = rs.getInt(6);
System.out.println(id+"tt"+name+"tt"+gender+"ttt"+course+"tt"+age+"tt"+score);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC的本质是什么
就是类-----实现sun公司的数据库链接规范的接口实现类 java.sql.Driver ;接口 java.sql.Connection ;接口 com.mysql.cj.jdbc.Driver;实现类 com.mysql.cj.jdbc.Connection;实现类 jdbc操作过程中------面向接口编程-----(java.sql...)接口多态注册驱动为什么使用Class.forName("xx.xx"),里面做了什么
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
Properties文件
driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/ee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true user=root password=rootJDBC封装
public class JdbcUtilsDome {
private static String url = null;
private static String user = null;
private static String password = null;
private static String driverClassName = null;
private JdbcUtilsDome(){}
static {
try {
//创建一个空的属性集合列表Properties
Properties p = new Properties();
//读取src下的JdbcUtils.properties
InputStream inputStream = JdbcUtilsDome.class.getClassLoader().getResourceAsStream("JdbcUtils.properties");
//获取配置文件中的内容
p.load(inputStream);
//获取配置文件中的key---对应的value
url = p.getProperty("url");
user = p.getProperty("user");
password = p.getProperty("password");
driverClassName = p.getProperty("driverClassName");
//注册驱动
Class.forName(driverClassName);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//封装获取链接对象的功能
public static Connection getConnection(){
Connection connection = null ;
try {
//使用驱动管理类
connection = DriverManager.getConnection(url,user,password) ;//从配置文件中获取
return connection ;
} catch (SQLException e) {
e.printStackTrace();
}
return null ;
}
//释放资源
public static void close(ResultSet rs, Statement stmt, Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//将释放资源添加到功能中
public static void close( Statement stmt, Connection con){
close(null,stmt,con);
}
}
preparedStatement和Statement的区别
preparedStatement
预编译对象,执行都是参数化的sql
写的sql的参数都是占位符号?可以有效防止sql注入(不存在字符串拼接)
sql就执行一次,可以发送不同的参数进行赋值,执行sql效率相对大于Statemet
Statement
可以造成sql注入,不安全
执行sql效率低,每次executeUpdate/Query(String sql)都要发送sql
单元测试
junit使用
1)导包
2)自定义类,书写单元测试方法
3)没有返回值,没有参数类型,只有内容
4)方法注解@Test----启动器
单元测试提供其他的注解
@Before:它标记的方法是在执行@After方法之后执行
服务器的初始化代码
@After:它标记的方法是在执行@Test之后执行
存储的一些释放资源代码
断言功能:
asserEquals(预期的结果,单元测试中的结果)
举例:
调用相加的方法,预期的结果和真实的结果一致,断言成功,否则失败
int result = calcuator.add(10, 20);
Assert.assertEquals(30,result);
注解
jdk内置注解
@Overrid:标记当前这个方法是否重写的方法: 重写了类或抽象类/接口
@Deprecated:标记某个方法是过时方法
@SuppressWarnings:压制警告,一般企业中,项目部署上线的时候,代码中不能出现黄色警告线
@FunctionalInteface:函数式接口:jdk8以后
接口如果是一个抽象类:那么这个接口就可以是函数式接口----使用lambda表达式


