JDBC
JDBC:是用于在Java语言编程中与数据库连接的API。
IPC(跨进程交互):不同进程之间传播或交换信息
SPI(Service Provider Interface):可称之为服务供给接口
url一种特殊的格式:
协议 : // ip:port/若干路路径/资源?参数k-v用&连接
数据库在Java中的使用
//加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//连接数据库
String user = "root";
String password = "root";
String url = "jdbc:mysql://localhost:3306/db_test?serverTimezone=UTC&useSSL=true";
Connection conn = DriverManager.getConnection(url, user, password);
Statement st = conn.createStatement();
//增加数据
st.executeUpdate("insert into tb_stu(stuname, stuphone,major) values ('lvjie','123456789','外事学院计科')");
//查找数据
ResultSet rs = st.executeQuery("select s.id sid,c.id cid from tb_stu s,tb_cla c");
while(rs.next()) {
int id = rs.getInt("sid");
System.out.println(id);
}
DAO
查询原始数据
public Float queryAvgScoreById(int id) {
try {
String sql = "select sid, avg(score) av from tb_cv where sid = ? group bt sid";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
if(rs.next()) {
return rs.getFloat("av");
}
return null;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
Service
对数据进行二次加工
public Map<Student, Float> queryMaxAvgByStudent(){
List<Student> list = dao.queryAllStudent();
Student max = null;
Float maxScore = null;
for(Student item : list) {
Float temp = dao.queryAvgScoreById(item.getId());
if(maxScore == null || temp >= maxScore) {
maxScore = temp;
max = item;
}
}
HashMap<Student, Float> result = new HashMap<>();
result.put(max, maxScore);
return result;
}
单例模式
一.单例模式的定义
每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
二.单例模式的特点 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。单例模式保证了全局对象的唯一性。
饿汉模式:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题.
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成。
public class StudentService {
//构造方法私有化
private StudentService() {}
//创建私有的静态的本类实例
private static StudentService instance = new StudentService();
//创建一个公有的静态的以本类对象为返回值的,获取实例的方法
public static StudentService getInstance() {
return instance;
}
饱汉模式:
饱汉式本身是非线程安全的,
public class StudentService {
//构造方法私有化
private StudentService() {}
//创建私有的静态的本类实例
private static StudentService instance;
//创建一个公有的静态的以本类对象为返回值的,获取实例的方法
public static StudentService getInstance() {
if(instance == null) {
instance = new StudentService();
}
return instance;
}
双重检查锁模式:
综合了懒汉式和饿汉式两者的优缺点整合而成。看上面代码实现中,特点是在synchronized关键字内外都加了一层 if 条件判断,这样既保证了线程安全,又比直接上锁提高了执行效率,还节省了内存空间。
public class StudentService {
//构造方法私有化
private StudentService() {}
//创建私有的静态的本类实例
private static StudentService instance;
//创建一个公有的静态的以本类对象为返回值的,获取实例的方法
public static StudentService getInstance() {
if(instance == null) {
synchronized (StudentService.class) {
if(instance == null) {
instance = new StudentService();
}
}
}
return instance;
}
何为连接池?连接池的作用?
顾名思义,就是一个池子,里面放着数据库连接,应用服务需要的时候就去池子里面拿,用完之后归还给池子。数据库连接池负责分配、管理、释放数据库连接,它允许应用服务重复使用数据库连接,而非重新建立。
ThreadLocal (线程本地)
ThreadLocal
中填充的的是当前线程的变量,该变量对其他线程而言是封闭且隔离的,ThreadLocal
为变量在每个线程中创建了一个副本,这样每个线程都可以访问自己内部的副本变量。
1、线程隔离:ThreadLocal主要功能就是给每个线程创建变量副本,这样就可以保证一个线程对某个变量的修改不会影响到其他线程对该变量的使用。
2、线程共享变量:ThreadLocal提供了线程的本地变量,即当创建一个变量后,每个线程对其进行访问的时候访问的是自己线程的变量。
ThreadLocal底层实现原理
每个Thread维护一个ThreadLocalMap,这个Map的key是ThreadLocal实例本身,value才是真正要存储的值。具体过程如下:
每个Thread线程内部都有一个Map(ThreadLocalMap),Map里面存储ThreadLocal对象(key)和线程的变量副本(value),Thread内部的Map是由ThreadLocal维护的,由ThreadLoal负责向map获取和设置线程的变量值。对于不同线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。