本周内容
1.数据库的约束
定义:约束用户在操作数据表的一种"行为"
1.1 默认约束default
当前操作表的时候,如果某个字段没有插入值的时候,默认约束可以起作用
指定字段 default 默认值;---给指定字段一个默认值
删除默认约束---modify
2.2 非空约束not null
指定字段 not null;---给指定字段不能为空
删除非空约束---modify
3.3 唯一约束unique
unique:约束字段值不能重复
指定字段 uniquel;---给指定字段不能重复
删除唯一约束:alter table 表名 drop index 唯一约束所在的字段名称;
添加唯一约束:modify;
4.4 主键约束primary key(非空且唯一)
特点:一般主键作用在一张表的非业务字段(id),--非空且唯一,一般和自增长约束一起使用
指定字段 primary key;
添加主键约束:modify
删除主键约束:alter table 表名 drop primary key;---只删除主键约束,非空约束并没有删除
5.5 自增长约束auto_increment
一般和主键约束一起使用,作用在非业务字段(id)
字段名称 primary key auto_increment;
添加自增长约束:modify
删除自增长约束:modify
先删除主键约束,再删除自增长约束
select last_insert_id;查询到最后一次自增长主键的id值;
6.6 外键约束(表和表之间的关系)foreign key
CONSTRAINT -- 声明
dept_employee_fk -- 后面跟外键名称 (命名规范:主表名_从表名_fk)
FOREIGN KEY (dept_id) -- 外键作用的从表字段名称;格式--
REFERENCES -- -- 关联
dept(id) -- 主表的主键id
删除外键约束:alter table 表名 drop foreign key 外键名称;
添加外键:alter table 表名 add constraint 外键名称 foreign key(从表字段名称) references 主表(字段名称)
6.7 级联操作–cascade
级联操作是外键约束的基础之后后面加如这两个约束
级联修改:on updata cascade;
级联删除:on delete cascade;
2.数据库的备份和还原
2.1 图形界面化的方式–SQLyog
SQLYog图形界面化工具
备份:选中库---->右键---->backup/export----> 以sql转存文件导出到指定的目录中---->选中structure and data--->选择指定的路径
还原:将原来的库删除,然后在创建新的库--->右键--->import--->Execute Sql Script(执行sql脚本)--->找到sql脚本路径--->将sql脚本中的存储的表数据和结构全部执行!
2.2 命令行的方式
备份:使用dos控制台的方式
管理员身份运行dos控制台,不需要登录mysql
mysqldump -uroot -p密码 库名 > 路径\xxx.sql
还原:命令的方式还原
mysql -uroot -p -->回车输入密码--->dos控制台登录mysql-->source 路径\xxx.sql
3.表和表的关系
4. 数据库的三大范式(重点)–数据库的基本标准
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小,关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
第一范式(1NF):数据库表的每一列都是不可分割的原子项,即实体中的某个属性有多个值时,必须拆分为不同的属性。每列不能再拆分
第二范式(2NF):在1NF的基础上,非主键的列(字段)完全依赖于主键列(字段),不产生局部依赖;
特点:1)一张表只描述一件事情;
2)表中的每一列都依赖于主键;
第三范式(3NF):在2NF基础上,非主键列不能产生传递依赖于主键列;
5. 多表查询
操作步骤:1)查询哪些表
2)查询表中的哪些字段
3)表和表之间的关系:连接条件
5.1 内连接查询–隐式和显示内连接
隐式内连接:使用where条件
select 字段列表 from 表名1,表名2 where 表名1.某个字段=表名2.某个字段;
SELECT
*
FROM
emp e,
dept d
WHERE e.`dept_id` = d.`id` ;
显示内连接:关键字 select 字段列表 from 表名1 inner join 表名2 on 表名1.某个字段 = 表名2.某个字段;(inner可以省略不写)
SELECT
e.*,
d.`NAME` '部门名称'
FROM
emp e
INNER JOIN dept d
ON e.`dept_id` = d.`id` ;
实际开发中,多去使用where语句
5.2 外连接查询–左外和右外连接
左外连接查询:select 字段列表 from 左表 left outer join 右表 on 连接条件;--将左表的信息全部查询出来以及交集部分的数据
右外连接查询 和左外相反:将右表的数据全部查询出来以及交集部分的数据 -->rigth (outer可以省略不写) join
SELECT * FROM emp e
RIGHT JOIN dept d
ON e.`dept_id` = d.`id` ;
5.3 子查询—select嵌套
1)利用聚合函数以及比较运算符
select 嵌套
2)利用in集合语句 in(值1,值2,值3)
字段名称 in(值1,值2,值3)
3)将某个查询语句的结果--多行多列--看做"虚表"和当前其他表进行关联查询
--将第一查询的结果表起一个别名,作为虚表
6.数据库的事物
在实际开发中,每一个业务操作(看成一个整体)可能同时操作多个表或者多个sql语句,要么同时执行成功要么同时执行失败!
6.1 传统事物的特点:ACID(必须记住)
1)A(原子性):针对当前某个事物,执行多个sql的时候,要么同时成功,要么同时失败
2)C(一致性):事物操作的前后,总量保持一致的
3)I(隔离性):事物和事物(业务和业务)之间是独立的,不能相互影响
4)D(持久性):如果开启了事物,并且提交事物,对数据的修改它是持续的,即使关机,数据依然存在!
6.2 事物的隔离级别
1)read uncommitted:读未提交(安全行低,效率最高),严重会导致"脏读",一个事物读到另一个没有提交的事物!
2)read committed:读已提交(安全性高于前者),有效防止脏读,但是出现新的问题-->不可重复读的问题;
3)repeatable read:可重复的默认隔离级别,有效防止脏读,不可重复的问题;
4)serializable:串行话:级别最高,效率低;有效防止脏读,不可重复的问题,幻读的问题;
5.5版本,SELECT @@tx_transaction;查看隔离级别
set global transaction isolation level 隔离级别名称---设置隔离级别;
6.3 在命令行操作事物
1)start transaction:开启事物
2)执行sql语句:updata/delete/insert...
3)commit:提交事物
4)rollback:回滚事物-->回到最初始的状态
7.什么是JDBC?repet
JDBC((java database connectivity)java操作数据库的一种连接器
7.1 jdbc的本质
就是java连接特定的数据库,本质是实现了sun公司提供的接口的实现类(数据库厂商提供的)
7.2 jdbc原生的7大操作步骤
1.加载驱动--导入数据库的驱动包
2.注册驱动
3.获取数据库的连接对象
4.准备静态sql语句
5.通过连接对象获取执行对象
6.通过执行对象执行静态sql语句并返回结果
7.释放资源
public class JDBCdemo {
public static void main(String[] args) throws Exception{
//1)加载驱动,导包
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver");//驱动类的全限定名称
//3)获取数据库的连接对象
/*sun公司提供类:驱动管理类DriverManager 用于管理一组JDBC驱动程序的基本服务。
*静态功能:public static Connection getConnection(
* String url, 统一资源定位符
* String user, 数据库的用户 root
* String password) 数据库的密码
* throws SQLException 获取数据库的连接对象
* url =jdbc:关系型数据库的类型://域名:端口号/库名"
* mysql-server:安装mysql版本8.0后面库名要带上 一堆参数 字符集是utf8,是否进行数据库验证(false),以及服务器时区还有是否公开访问
*mysql-server:安装mysql8.0以下的版本,5.0以上的版本 :库名的后面通常情况下可以不带参数 (备注5.7的版本最起码带上?characterEncoding=utf8)
* */
String url = "jdbc:mysql://localhost:3306/myee_2113";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url,user,password);
//4)准备静态sql语句
String sql = "insert into amount values (3,'王五',1500,2000)";
//5)通过数据库的连接对象获取执行对象
//java.sql.Connection--->Statement createStatement() throws SQLException
Statement stmt = connection.createStatement();
//6)执行sql语句并返回结果
//Statement:通用的方法:
// int executeUpdate(String sql)throws SQLException :
// 执行DML语句 inseret into/update/delete,DDL (创建表/修改表...);
//ResultSet executeQuery(String sql)throws SQLException 执行DML语句,查询
int count = stmt.executeUpdate(sql);
System.out.println("本次操作影响了"+count+"行");
//7)释放资源
stmt.close();
connection.close();
}
}
7.3 优化–自定义一个工具类:JDBCUtils
作用:为了简写7大步骤的书写格式,将加载驱动,获取数据的连接对象,以及释放资源都封装到静态成员方法中
import java. io. IOException ;
import java. io. InputStream ;
import java. sql. * ;
import java. util. Properties ;
public class JDBCUtil {
private static String url = null ;
private static String user = null ;
private static String password = null ;
private static String driverClass = null ;
static {
try {
Properties popo = new Properties ( ) ;
InputStream inputStream = JDBCUtil . class . getClassLoader ( ) .
getResourceAsStream ( "jdbc.properties" ) ;
popo. load ( inputStream) ;
driverClass = popo. getProperty ( "driverClass" ) ;
url = popo. getProperty ( "url" ) ;
user = popo. getProperty ( "user" ) ;
password = popo. getProperty ( "password" ) ;
Class . forName ( driverClass) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( IOException 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 ( Statement stmt, Connection connection, ResultSet rs) {
if ( stmt!= null ) {
try {
stmt. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( connection!= null ) {
try {
connection. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( rs!= null ) {
try {
rs. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
public static void main ( String [ ] args) {
Connection connection = JDBCUtil . getconnection ( ) ;
System . out. println ( connection) ;
}
}
7.4 使用JDBC方式如何操作DQL语句(数据库查询语句)
ResultSet executeQuery ( String sql) throws SQLException ; 执行查询语句( select)
boolean next ( ) throws SQLException 将光标从当前位置移动到下一行
public class JDBC_Demo2 {
public static void main ( String [ ] args) {
Statement stmt = null ;
ResultSet rs = null ;
Connection connection = null ;
try {
connection = JDBCUtil . getconnection ( ) ;
String sql = "select * from student1;" ;
stmt = connection. createStatement ( ) ;
rs = stmt. executeQuery ( sql) ;
while ( rs. next ( ) ) {
int id = rs. getInt ( 1 ) ;
String name = rs. getString ( "name" ) ;
int age = rs. getInt ( 3 ) ;
System . out. println ( id+ "\t" + name+ "\t" + age) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
JDBCUtil . close ( stmt, connection, rs) ;
}
}
}
7.5 JDBC操作数据库,使用PreparedStatement的预编译操作步骤
定义: 表示预编译的SQL语句的对象
操作: 在通过连接对象获取预编译对象的时候, 同时将参数化的SQL语句发送到数据库并且保存到编译对象中
参数化Sql 的写法: 1 ) insert into ( 字段名称) values ( ? . . ?) : -- -- ? 是占位符号
2 ) PreparedStatement 给占位符号赋值, 通过void setXXX ( 占位符号, XXX是实际参数)
public class PreparedStatementDemo {
public static void main ( String [ ] args) {
Connection connection = JDBCUtil . getconnection ( ) ;
String sql = "insert into user values (?,?,?)" ;
try {
PreparedStatement stmt = connection. prepareStatement ( sql) ;
stmt. setInt ( 1 , 1 ) ;
stmt. setString ( 2 , "liu" ) ;
stmt. setString ( 3 , "liubaoshou" ) ;
int i = stmt. executeUpdate ( ) ;
System . out. println ( "影响了:" + i+ "行" ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
7.5.1面试题: 数据库的操作的执行对象PreparedStatement和Statement具体区别–>通过"sql注入弊端"区分
1)能有效防止sql注入
2)比statement对象执行效率高
sql语句:String sql = "select * from user where username = '"+user+"' and password = '"+psw+"';"
当输入用户名和密码时,密码输入格式为 a' or '1=1',那么修改了原来的sql语句,则会重现sql注入现象,无论正确还是错误,都会全部查询;
通过preparedStatement防止sql注入:select * from user where username = ? and password = ?;
具体区别:
Statement对象:1)执行的静态sql语句,存在一种硬编码行为,sql语句会有字符串拼接行为-->就可能出现"sql注入",不安全!
2)执行sql效率比较与prepareStatement低
PreparedStatement:
1)执行的参数化的sql语句,不存在字符串拼接行为,有效防止"sql注入'现象;
2)通过预编译对象给占位符号"?"赋值,赋值多次,执行sql效率高;
8 JDBC数据库管理"事物"
connection管理事物;
1)void setAutoCommit(boolean autoCommit) throws SQLException---参数true:表示自动提交模式,false,禁用自动提交,手动提交
2)void rollback() throws SQLException:事务回滚,撤销之前的所有操作,回滚到操作之前的状态
3)void commit() throws SQLException使上次提交/回滚之后所做的所有更改都将永久性 (提交事务
public class Shiwu {
public static void main ( String [ ] args) {
Connection connection = JDBCUtil . getconnection ( ) ;
PreparedStatement stmt = null ;
PreparedStatement stmt2 = null ;
String sql1 = "update amount set balance = balance - 500 where id = ?" ;
String sql2 = "update amount set balance = balance + 500 where id = ?" ;
try {
stmt = connection. prepareStatement ( sql1) ;
stmt2 = connection. prepareStatement ( sql2) ;
connection. setAutoCommit ( false ) ;
stmt. setInt ( 1 , 1 ) ;
stmt2. setInt ( 1 , 2 ) ;
int i = stmt. executeUpdate ( ) ;
int j = stmt2. executeUpdate ( ) ;
System . out. println ( i+ "----" + j) ;
connection. commit ( ) ;
} catch ( SQLException e) {
try {
connection. rollback ( ) ;
} catch ( SQLException ex) {
ex. printStackTrace ( ) ;
}
} finally {
JDBCUtil . close ( connection, stmt) ;
}
}
}
9.数据库的连接池
数据库连接池的目的:创建一些固定的可重用的连接对象,当使用完连接对象之后不会将对象真正释放,而是归还到连接池中,等待下一次继续去利用!
c3p0;---两种使用方式
方式(1):src下面提供配置文件,名称必须是c3po-config.xml
方式(2):src下面提供c3p0.properties
dbcp:功能非常强大--->是阿里提供的开源,不仅仅是作为"连接池",而且提供SQL Parser
(推荐使用)druid(德鲁伊)--功能非常强大--->是阿里提供的开源,不仅仅是作为"连接池",而且提供SQL Parser
数据库连接池的操作步骤:
1)导入druid-1.1.10.jar包 /junit的jar包以及依赖包/mysql驱动包
2)准备好的德鲁伊的配置文件
9.1 数据库连接池的操作步骤
数据库连接池的操作步骤:
1)导入druid-1.1.10.jar包 /junit的jar包以及依赖包/mysql驱动包
2)准备好的德鲁伊的配置文件jdbc.properties/druid.properties;名称需要查看jar包的datasource中的名称
3)创建配置文件对象,获取配置文件的资源输入流
4)将资源输入流内容保存到属性列表集合中
5)获取数据源的方法,通过中间关系"druitdatafactory工厂类",连接数据库
4)获取连接对象
< druid. properties?
driverClassName= com. mysql. jdbc. Driver
url= jdbc: mysql: / / localhost: 3306 / myee_2113
username= root
password= root
public class DruidDemo {
public static void main ( String [ ] args) throws Exception {
Properties popo = new Properties ( ) ;
InputStream inputStream = DruidDemo .
class . getClassLoader ( ) . getResourceAsStream ( "Druid.properties" ) ;
popo. load ( inputStream) ;
DataSource dataSource = DruidDataSourceFactory . createDataSource ( popo) ;
Connection connection = dataSource. getConnection ( ) ;
System . out. println ( connection) ;
}
}
10.模拟真实场景–JDBCUtil优化
import com. alibaba. druid. pool. DruidDataSourceFactory ;
import javax. sql. DataSource ;
import java. io. IOException ;
import java. io. InputStream ;
import java. sql. Connection ;
import java. sql. PreparedStatement ;
import java. sql. ResultSet ;
import java. sql. SQLException ;
import java. util. Properties ;
public class JDBCUtil {
private static DataSource ds = null ;
private static ThreadLocal < Connection > t1 = new ThreadLocal < > ( ) ;
private static Connection conn;
private static ResultSet rs;
static {
Properties prop = new Properties ( ) ;
InputStream inputStream = JDBCUtil . class . getClassLoader ( ) .
getResourceAsStream ( "Druid.properties" ) ;
try {
prop. load ( inputStream) ;
ds = DruidDataSourceFactory . createDataSource ( prop) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public static Connection getConnection ( ) {
try {
Connection conn = t1. get ( ) ;
if ( conn == null ) {
conn = ds. getConnection ( ) ;
t1. set ( conn) ;
}
return conn;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
return null ;
}
public static DataSource getDataSource ( ) {
return ds;
}
public static void close ( ResultSet rs, PreparedStatement stmt, Connection conn) {
if ( rs!= null ) {
try {
rs. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( stmt!= null ) {
try {
stmt. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( conn!= null ) {
try {
t1. remove ( ) ;
conn. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
public static void close ( PreparedStatement stmt, Connection conn) {
close ( null , stmt, conn) ;
}
public static void setAotoClose ( ) {
Connection connection = getConnection ( ) ;
try {
connection. setAutoCommit ( false ) ;
t1. remove ( ) ;
connection. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
public static void rollbackAndClose ( ) {
Connection connection = getConnection ( ) ;
try {
connection. rollback ( ) ;
t1. remove ( ) ;
connection. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
public static void commitAndClose ( ) {
Connection connection = getConnection ( ) ;
try {
connection. commit ( ) ;
t1. remove ( ) ;
connection. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
public static void main ( String [ ] args) {
DataSource dataSource = getDataSource ( ) ;
System . out. println ( dataSource) ;
Connection connection = getConnection ( ) ;
System . out. println ( connection) ;
}
}
11.Apache机构提供的工具(对jdbc封装)–>comments-dbutils.jar
Common-dbtuls就是针对原生jdbc的操作进行简易封装
1)导入jar包 commons-dbutils-1.7.jar
2)操作数据库 ---> 创建QueryRunner对象
执行对象:QueryRunner
创建QueryRunner对象
public QueryRunner() :手动提交模式
创建QueryRunner对象
public QueryRunner(DataSource ds) :参数为数据源 自动提交模式(推荐)
3) 准备的sql ,参数化的sql语句
4)QueryRunner对象执行的sql语句
4.1)针对添加,删除,修改的sql语句通用的方式
public int update(String sql, Object... params),返回值是int类型
参数1:参数化的sql语句
参数2:给"占位符?" 赋值实际参数
4.2)针对查询的sql语句
通用的查询方法
public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
参数1:查询的sql语句 举例:select * from 表名 where id = ? ;
参数2:接口
ResultSetHandler :针对查询的结果集的数据表的处理
子实现类
BeanListHandler<T> :将查询的每一条记录封装到T中,然后结果多条记录
封装到一个List<T> 集合中
BeanHandler<T> :将查询的某一条记录封装到T中,返回就是当前T
ScalarHandler<T>:查询单行单列数据封装到Object中
举例
查询总记录数 select count(id) from 表名;
Object obj = qr.query(sql, new ScalarHandler<>());
...
参数3:带条件的实际参数
针对增删改的语句update:
public void addStudent ( Student s) {
QueryRunner qr = new QueryRunner ( JDBCUtil2 . getDataSource ( ) ) ;
String sql = "insert into student2 values (?,?,?,?,?)" ;
try {
int x = qr. update ( sql, s. getId ( ) , s. getName ( ) ,
s. getAge ( ) , s. getGender ( ) , s. getAddress ( ) ) ;
System . out. println ( "影响了:" + x+ "行" ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
针对查询的语句, 并且返回的是一个集合;
public List < Student > findAllStudent ( Student s) throws SQLException {
QueryRunner qr1 = new QueryRunner ( JDBCUtil2 . getDataSource ( ) ) ;
String sql1 = "select * from student2" ;
List < Student > list = qr1. query ( sql1, new BeanListHandler < Student > ( Student . class ) ) ;
return list;
}
针对查询的语句, 并且返回的是一个单独的事物, 单条查询
public Student findOneStudent ( int id) throws SQLException {
QueryRunner qr2 = new QueryRunner ( JDBCUtil2 . getDataSource ( ) ) ;
String sql2 = "select * from student2 where id = ?" ;
Student s2 = qr2. query ( sql2, new BeanHandler < Student > ( Student . class ) , id) ;
return s2;
}
查询的是一个单行单列的数据( 有多少列, 多少行) , 返回的是一个单独的object类, 需要转换成int 类型, 输出
public int countEmpl ( String file) throws SQLException {
QueryRunner qr = new QueryRunner ( JDBCUtil2 . getDataSource ( ) ) ;
String sql = "select count(?) from emp" ;
Emploee obj = qr. query ( sql, new ScalarHandler < Emploee > ( ) , id) ;
String s = String . valueOf ( obj) ;
int count = Integer . parseInt ( s) ;
return count;
}
11.动态代理
代理设计模式属于"结构型设计模式"
代理设计模式:1)静态代理 2)动态代理
动态代理:1)jdk动态代理 2)cglib动态代理(第三方)
前提条件:必须存在一个接口,基于这个接口来完成加强代理的!
通过反射的方式直接产生代理实例对象
操作步骤:
1)创建代理类的对象
2)获取调用代理对象的处理程序对象,参数为代理类的实例
3)通过proxy的newproxyinstance来获取经过调用处理程序加强的代理类对象
4)调用方法
public class ProxyTest {
public static void main ( String [ ] args) {
UserDao ud = new UserDaoImpl ( ) ;
InvocationHandler handler = new MyInvocationHandler ( ud) ;
UserDao udo = ( UserDao ) Proxy . newProxyInstance ( ud. getClass ( ) . getClassLoader ( ) , ud. getClass ( ) .
getInterfaces ( ) , handler) ;
udo. add ( ) ;
udo. delete ( ) ;
udo. select ( ) ;
udo. update ( ) ;
}
}
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler ( Object target) {
this . target = target;
}
@Override
public Object invoke ( Object proxy, Method method, Object [ ] args) throws Throwable {
System . out. println ( "校验日志" ) ;
method. invoke ( target, args) ;
System . out. println ( "产生日志文件" ) ;
return target;
}
}
真实接口和它的代理子实现类此处省略;
12.单元测试的步骤
junit使用步骤
1)Java项目 导包 需要导入核心包:junit-4.13.jar以及它的依赖包hamcrest-core-1.3.jar,以后 "maven管理工具",只需要导入junit-4.13.jar,后面的依赖包自动导入
2)定义一个类:专门针对不同的功能进行测试的
3)在类中成员方法,单元测试的方法必须在成员方法上加入@Test, 这个方法没有任何参数,也不需要写返回值 都是void
4) 使用 "断言",将预期的结果和最终结果进行对比,如果不一致,单元测试通过不了,如果一致,单元测试就是正常数据!使用"断言"Assert (junit提供的)的assertEquals(预期值,实际值)
在单元测试里面:
@Test标记当前这个单元测试方法
@Before 标记某个方法是在@Test标记的单元测试方法之前先执行
举例:初始化的功能
@After 标记某个方法是@Test标记的单元测试方法之后执行的
举例,释放相关的资源
public class Calculatortest {
private Calculator cal;
@Before
public void inuit(){
cal = new Calculator();
System.out.println("在测试方法执行前先执行@Before");
}
@Test
public void addtest(){
int num = cal.add(3,4);
Assert.assertEquals(7,num);
System.out.println("测试成功");
}
@After
public void shifang(){
System.out.println("在测试方法执行后再执行@After");
}
}