既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
案例:连接数据库方法
类加载采用了反射的方式
采用枚举方式封装JDBC单例
方法程序:
package com.tianju.util;
import java.sql.\*;
import java.util.Objects;
/\*\*
\* 采用枚举单例封装数据库
\*/
public enum DbUtilEnum {
INSTANCE;
private Connection conn;
private PreparedStatement pst;
private ResultSet rs;
private DbUtilEnum() {
// 注册驱动-类加载
register();
}
/\*\*
\* 第一步:注册驱动,类加载
\*/
private void register(){
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
// 建立数据库连接
// 192.168.0.134:3306
// root,123
/\*\*
\* 第二步:建立数据库连接
\* @param ipAdress ip地址+端口号
\* @param user 用户名root
\* @param password 密码123
\*/
public void connect(String ipAdress,String user,String password){
String url = "jdbc:mysql://"+ipAdress+"/emp\_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
try {
conn = DriverManager.getConnection(url,user,password);
System.out.println("成功连接数据库:"+ipAdress);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/\*\*
\* 第三步:准备SQL语句,
\* @param sql sql语句
\*/
public void setPreparedStatement(String sql, Object...values){
try {
pst = conn.prepareStatement(sql);
// 逐个填充 ? 处的空缺
for (int i=0;i<values.length;i++){
pst.setObject(i+1, values[i]);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/\*\*
\* 第四步:增加,删除,修改
\*/
public void executeUpdate(){
try {
pst.executeUpdate();
System.out.println("执行增删改操作");
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/\*\*
\* 第四步:查询ResultSet,调用next()方法
\* @return 返回查询的ResultSet
\*/
public ResultSet executeQuery(){
try {
rs = pst.executeQuery();
System.out.println("执行查询操作,返回结果");
return rs;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/\*\*
\* 第五步:关闭连接
\*/
public void close(){
try {
if (Objects.nonNull(rs)){
rs.close();
}
if (Objects.nonNull(pst)){
pst.close();
}
if (Objects.nonNull(conn)){
conn.close();
}
System.out.println("操作完成,关闭数据库连接");
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
3.克隆(拷贝)clone
- 继承的时候,可以将子类的访问控制符扩大,但不能缩小;子类不得比父类抛出更多,更大的异常。
- 浅拷贝、深拷贝问题:
浅拷贝
// protected:代表本包或者继承
// 继承的时候,可以将子类的访问控制符扩大,但不能缩小;
// 子类不能比父类抛出更多的异常
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
深拷贝
public Book deepClone(){
Book book = new Book();
Author au = new Author();
au.setName(author.getName());
book.setAuthor(au);
book.setTitle(this.title);
book.setPrice(this.price);
return book;
}
案例
Author.java实体类
package com.tianju.auth.reflect;
import lombok.Data;
@Data
public class Author {
private String name;
}
Book.java实体类
implements Cloneable{ // 可以克隆的
package com.tianju.auth.reflect;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book implements Cloneable{ // 可以克隆的
private String title;
private Author author;
public double price;
static {
System.out.println("book的静态代码块");
}
// protected:代表本包或者继承
// 继承的时候,可以将子类的访问控制符扩大,但不能缩小;
// 子类不能比父类抛出更多的异常
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Book deepClone(){
Book book = new Book();
Author au = new Author();
au.setName(author.getName());
book.setAuthor(au);
book.setTitle(this.title);
book.setPrice(this.price);
return book;
}
}
进行测试
package com.tianju.auth.reflect;
public class TestDemo{
public static void main(String[] args) throws CloneNotSupportedException {
Author author = new Author();
author.setName("吴承恩");
Book book = new Book("三国演义", author,12.56);
Book book1 = book;
System.out.println(book1==book);// == 两个引用是否指向同一个对象
// clone创建了一个新的对象,只是值一样
Book bookClone = (Book) book.clone();
// 深拷贝,创建了新的对象,上面的浅拷贝,只是拷贝了引用
Book deepClone = book.deepClone();
System.out.println(bookClone==book);
System.out.println("克隆前:"+book);
System.out.println("克隆后:"+bookClone);
author.setName("小柯基");
System.out.println("修改后的原对象:"+book);
System.out.println("修改后的clone对象:"+bookClone);
// 深拷贝
System.out.println("\*\*\*\*\*\*\*\*\*\*\*");
System.out.println("深拷贝的方法:"+deepClone);
}
}
序列化和反序列化
对象流-把对象存储为dat文件
要点:
(1)实体类需要实现序列化接口 public class Car implements Serializable;【标记接口】
(2)序列化的版本号最好不要写,交给JVM实现,要保证版本号一致;
功能:
ObjectOutputStream—->对象写入文件
serialVersionUID :在序列化的时候指定的编号, 在反序列化时应该保证版本号一致。
案例:把car类存储到dat文件中
1)类需要实现序列化的接口
public class Car implements Serializable { // 需要实现序列化的接口
// 序列化的版本号,不要写,交给jvm实现;保证读的和写的对象实体类要一样
// private static final long serialVersionUID = 2L;
private Integer id;
private String name;
public Car() {
}
}
2)从内存写入硬盘文件,为out,用write
ObjectOutputStream out =
new ObjectOutputStream(
new FileOutputStream("D:\\Myprogram\\idea-workspace\\IOStrem\\IOStrem\\src\\com\\woniuxy\\resources\\car.dat")
);
// 存多个的解决方法,存到List中
List<Car> list = new ArrayList<>();
list.add(new Car(1, "BMW"));
list.add(new Car(2, "BYD"));
list.add(new Car(3, "BMW"));
out.writeObject(list); // list也实现了Serializable
out.flush();
out.close();
3)从硬盘读入内存,为in,用read
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
实现了Serializable
out.flush();
out.close();
3)从硬盘读入内存,为in,用read
[外链图片转存中...(img-wqniACTt-1715791743000)]
[外链图片转存中...(img-ePU9ZoDg-1715791743000)]
[外链图片转存中...(img-vca1KEtA-1715791743001)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.youkuaiyun.com/topics/618631832)**