【JAVA高级】——封装JDBC中的DaoUtils工具类(Object类型方法)

news2024/11/15 8:12:24

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:JAVA开发者成长之路
✨特色专栏:国学周更-心性养成之路
🥭本文内容:封装JDBC中的DaoUtils工具类(Object类型方法)

文章目录

    • 一、commonsUpdae方法
    • 二、commonsSelect方法
    • 三、RowMapper类封装resultSet结果集
    • 四、综合案例
      • 1、com.cxyzxc.www.utils包
        • 【1】DaoUtils工具类完整代码
        • 【2】DBUtils工具类完整代码
        • 【3】DateUtils工具类完整代码
      • 2、com.cxyzxc.www.entity包
      • 3、com.cxyzxc.www.advanced包
      • 4、com.cxyzxc.www.advanced.impl包
      • 5、com.cxyzxc.www.dao包
      • 6、com.cxyzxc.www.dao.impl包
      • 7、com.cxyzxc.www.service包
      • 8、com.cxyzxc.www.service.impl包
      • 9、com.cxy.zxc.view包
        • 【1】测试插入数据
        • 【2】测试删除数据
        • 【3】测试修改数据
        • 【4】测试查询一条数据
        • 【5】测试查询所有数据

在Dao层的DaoImpl类中,对数据表进行的增、删、改、查操作方法中存在很多相同的代码,可以将这些相同的代码抽取出来封装到一个类中,形成DaoUtils工具类,实现复用。以查询teacher表为例。

一、commonsUpdae方法

该方法是对数据表进行增、删、改的公共方法。

// 增、删、改三个方法封装成一个方法
public int commonsUpdate(String sql, Object... args) {
	Connection connection = null;
	PreparedStatement preparedStatement = null;
	// 获取数据库连接对象
	connection = DBUtils.getConnection();

	try {
		// 获取SQL语句发送对象
		preparedStatement = connection.prepareStatement(sql);
		if (args != null) {
			// 绑定参数
			for (int i = 0; i < args.length; i++) {
				preparedStatement.setObject(i + 1, args[i]);
			}
		}
		// 执行SQL语句
		int result = preparedStatement.executeUpdate();
		return result;
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		DBUtils.closeAll(null, preparedStatement, null);
	}
	return 0;
}

二、commonsSelect方法

该方法是对数据表进行查询的公共方法,可以查询一条数据,也可以查询多条数据。不管是查询一条数据还是查询多条数据,都将查询到的数据封装到Object类型的集合中。

public List<Object> commonsSelect(String sql,RowMapper rowMapper, Object... args) {
		Connection connection = null;
	PreparedStatement preparedStatement = null;
	ResultSet resultSet = null;
	List<Object> objectList = new ArrayList<Object>();
	// 获取数据库连接对象
	connection = DBUtils.getConnection();

	try {
		// 获取SQL语句发送对象
		preparedStatement = connection.prepareStatement(sql);
		if (args != null) {
			// 绑定参数
			for (int i = 0; i < args.length; i++) {
				preparedStatement.setObject(i + 1, args[i]);
			}
		}
		// 执行SQL语句
		resultSet = preparedStatement.executeQuery();

		while (resultSet.next()) {
			Object object = rowMapper.getRow(resultSet);
			objectList.add(object);
		}
		return objectList;

	} catch (SQLException e) {
		e.printStackTrace();
	}finally {
		DBUtils.closeAll(null, preparedStatement, resultSet);
	}

	return null;
}

三、RowMapper类封装resultSet结果集

使用查询方法从表中查询出来的结果存储在ResultSet结果集中,需要从ResultSet结果集中遍历出数据封装成对应对象,然后将封装出来的对象返回给DaoImpl类使用。这个封装的过程由RowMapper类完成。

package com.cxyzxc.www.examples01;

/**
 * 数据封装类,专门用来处理查询返回的resultSet结果集
 * 
 * 针对每一个实体类,封装一个RowMapper类
 */
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

public class RowMapper {
	
	public static Object getRow(ResultSet resultSet){
		
		Teacher teacher = null;
		
		try {
			//返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类
			int tid = resultSet.getInt("tid");
			String name = resultSet.getString("name");
			int age = resultSet.getInt("age");
			Date bornDate = resultSet.getDate("bornDate");
			String email = resultSet.getString("email");
			String address = resultSet.getString("address");
			
			teacher = new Teacher(tid, name, age, bornDate, email, address);
			return teacher;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return null;
		
	}

}

四、综合案例

综合案例完全按照三层架构实现,创建不同的包存放不同的接口、实现类、工具类、测试类等代码。使用数据库中的teacher表来完成综合案例。

1、com.cxyzxc.www.utils包

该包用来存放项目开发所需要的数据库连接工具类DBUtils类、日期时间转换工具类DateUtils类,数据库操作工具类DaoUtils类

【1】DaoUtils工具类完整代码

package com.cxyzxc.www.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.cxyzxc.www.advanced.RowMapper;

public class DaoUtils {

	// 增、删、改三个方法封装成一个方法
	public int commonsUpdate(String sql, Object... args) {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		// 获取数据库连接对象
		connection = DBUtils.getConnection();

		try {
			// 获取SQL语句发送对象
			preparedStatement = connection.prepareStatement(sql);
			if (args != null) {
				// 绑定参数
				for (int i = 0; i < args.length; i++) {
					preparedStatement.setObject(i + 1, args[i]);
				}
			}
			// 执行SQL语句
			int result = preparedStatement.executeUpdate();
			return result;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(null, preparedStatement, null);
		}
		return 0;
	}

	public List<Object> commonsSelect(String sql,RowMapper rowMapper, Object... args) {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		List<Object> objectList = new ArrayList<Object>();
		// 获取数据库连接对象
		connection = DBUtils.getConnection();

		try {
			// 获取SQL语句发送对象
			preparedStatement = connection.prepareStatement(sql);
			if (args != null) {
				// 绑定参数
				for (int i = 0; i < args.length; i++) {
					preparedStatement.setObject(i + 1, args[i]);
				}
			}
			// 执行SQL语句
			resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				Object object = rowMapper.getRow(resultSet);
				objectList.add(object);
			}
			return objectList;

		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBUtils.closeAll(null, preparedStatement, resultSet);
		}

		return null;
	}

}

【2】DBUtils工具类完整代码

package com.cxyzxc.www.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * 跨平台方案 注册驱动 获取连接 释放资源
 */
public class DBUtils {
	// 读取配置文件的Map
	private static final Properties PROPERTIES = new Properties();
	// 声明一个ThreadLocal<Connection>对象用来存储数据库连接对象
	private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

	static {
		// 通过复用本类自带流,读取配置文件中的数据
		InputStream is = DBUtils.class.getResourceAsStream("/db.properties");

		try {
			// 通过prop对象将流中的配置信息分隔成键值对,将配置文件内容加载到properties集合
			PROPERTIES.load(is);
			// 注册驱动,通过driverName的键获取对应的值(com.mysql.jdbc.Driver)
			Class.forName(PROPERTIES.getProperty("driver"));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 获取连接对象
	public static Connection getConnection() {
		// 将当前线程中绑定的Connection对象赋值给connection变量
		Connection connection = threadLocal.get();
		try {
			// 如果连接对象为null,则创建一个连接对象
			if (connection == null) {
				connection = DriverManager.getConnection(
						PROPERTIES.getProperty("url"),
						PROPERTIES.getProperty("username"),
						PROPERTIES.getProperty("password"));
				// 将创建的连接对象存储到当前线程中共享
				threadLocal.set(connection);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
		return connection;
	}

	// 释放所有资源
	public static void closeAll(Connection connection, Statement statement,
			ResultSet resultSet) {
		try {
			if (resultSet != null) {
				resultSet.close();
			}
			if (statement != null) {
				statement.close();
			}
			if (connection != null) {
				connection.close();
				// 将connection从threadLocal中移除
				threadLocal.remove();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// 3、开启事务
	public static void startTransaction() {
		Connection connection = null;
		try {
			connection = getConnection();
			connection.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// 4、提交事务
	public static void commitTransaction() {
		Connection connection = getConnection();
		try {
			connection.commit();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(connection, null, null);
		}
	}

	// 5、回滚事务
	public static void rollbackTransaction() {
		Connection connection = getConnection();
		try {
			connection.rollback();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(connection, null, null);
		}
	}
}

【3】DateUtils工具类完整代码

package com.cxyzxc.www.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * 日期时间工具类DateUtils
 */
public class DateUtils {

	private static final SimpleDateFormat SIMPLEDATEFORMAT = new SimpleDateFormat("yyyy-MM-dd");

	// 字符串转换为java.util.Date类型日期时间
	public static java.util.Date strDateToUtilDate(String strDate) {
		try {
			return SIMPLEDATEFORMAT.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	// java.util.Date类型日期时间转换为java.sql.Date类型日期时间
	public static java.sql.Date utilDateToSqlDate(java.util.Date date) {
		// long date.getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT以来此 Date对象表示的毫秒数
		return new java.sql.Date(date.getTime());
	}

	// java.util.Date类转换为字符串类型
	public static String utilDateToString(java.util.Date date) {
		return SIMPLEDATEFORMAT.format(date);
	}

}

2、com.cxyzxc.www.entity包

该包用来存储实体类,根据teacher表创建实体类Teacher类

package com.cxyzxc.www.entity;

import java.util.Date;

public class Teacher {
	/** 教师编号 */
	private int tid;
	/** 姓名 */
	private String name;
	/** 年龄 */
	private int age;
	/** 出生日期 */
	private Date bornDate;
	/** 邮箱 */
	private String email;
	/** 住址 */
	private String address;

	// 无参构造方法
	public Teacher() {
		super();
	}

	// 有参构造方法
	public Teacher(String name, int age, Date bornDate, String email,
			String address) {
		super();
		this.name = name;
		this.age = age;
		this.bornDate = bornDate;
		this.email = email;
		this.address = address;
	}

	public Teacher(int tid, String name, int age, Date bornDate, String email,
			String address) {
		super();
		this.tid = tid;
		this.name = name;
		this.age = age;
		this.bornDate = bornDate;
		this.email = email;
		this.address = address;
	}

	// getXxx()/setXxx()方法
	public int getTid() {
		return tid;
	}

	public void setTid(int tid) {
		this.tid = tid;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getBornDate() {
		return bornDate;
	}

	public void setBornDate(Date bornDate) {
		this.bornDate = bornDate;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	// 重写Object类中的toString()方法
	@Override
	public String toString() {
		return "tid=" + tid + ", name=" + name + ", age=" + age + ", bornDate="
				+ bornDate + ", email=" + email + ", address=" + address;
	}

}

3、com.cxyzxc.www.advanced包

该包中存放RowMapper接口,用来约束封装对象的ORM

package com.cxyzxc.www.advanced;

import java.sql.ResultSet;

/**
 * 该接口用来约束封装对象的ORM
 */
public interface RowMapper {
	
	Object getRow(ResultSet resultSet);

}

4、com.cxyzxc.www.advanced.impl包

package com.cxyzxc.www.advanced.impl;

/**
 * 数据封装类,专门用来处理查询返回的resultSet结果集
 * 
 * 针对每一个实体类,封装一个RowMapper类
 */
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import com.cxyzxc.www.advanced.RowMapper;
import com.cxyzxc.www.entity.Teacher;

public class TeacherRowMapper implements RowMapper {

	@Override
	public Object getRow(ResultSet resultSet) {
		Teacher teacher = null;
		try {
			// 返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类
			int tid = resultSet.getInt("tid");
			String name = resultSet.getString("name");
			int age = resultSet.getInt("age");
			Date bornDate = resultSet.getDate("bornDate");
			String email = resultSet.getString("email");
			String address = resultSet.getString("address");

			teacher = new Teacher(tid, name, age, bornDate, email, address);
			return teacher;
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return null;
	}

}

5、com.cxyzxc.www.dao包

该包用来存放操作数据库的接口

package com.cxyzxc.www.dao;

import java.util.List;

import com.cxyzxc.www.entity.Teacher;

public interface TeacherDao {
	//增
	int insert(Teacher teacher);
	
	//删
	int delete(int tid);
	
	//改
	int update(Teacher teacher);
	
	//查单个
	Teacher selectOne(int tid);
	
	//查所有
	List<Teacher> selectAll();
	

}

6、com.cxyzxc.www.dao.impl包

该包用来存放数据库操作接口的实现类

package com.cxyzxc.www.dao.impl;

import java.util.ArrayList;
import java.util.List;

import com.cxyzxc.www.advanced.RowMapper;
import com.cxyzxc.www.advanced.impl.TeacherRowMapper;
import com.cxyzxc.www.dao.TeacherDao;
import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.utils.DaoUtils;

public class TeacherDaoImpl implements TeacherDao {
	/*
	 * (1)该类中提供对teacher表进行增、删、改、查单个、查所有5个方法。
	 * 
	 * (2)该类中的代码只做数据库访问操作,不做任何业务逻辑操作。
	 * 
	 * (3)该类只对数据库一张表进行操作,从而实现复用
	 */

	DaoUtils daoUtils = new DaoUtils();
	RowMapper rowMapper = new TeacherRowMapper();

	// 新增:向teacher表中插入一条数据(一条数据对应一个Teacher对象),插入成功,返回一个受影响行数值(int类型)
	@Override
	public int insert(Teacher teacher) {

		String sql = "insert into `teacher`(name,age,bornDate,email,address) values(?,?,?,?,?);";

		// 赋值
		Object[] args = { teacher.getName(), teacher.getAge(),
				teacher.getBornDate(), teacher.getEmail(), teacher.getAddress() };

		return daoUtils.commonsUpdate(sql, args);
	}

	// 删除:根据教师tid删除一条数据,删除成功,返回一个受影响行数值(int类型)
	@Override
	public int delete(int tid) {

		String sql = "delete from teacher where tid = ?;";
		return daoUtils.commonsUpdate(sql, tid);

	}

	// 修改:修改teacher表中的数据,可能对任意的一个字段进行修改,所以方法中直接传递一个对象进行修改,修改成功,返回一个受影响行数值(int类型)
	@Override
	public int update(Teacher teacher) {

		String sql = "update teacher set name = ?,age = ?,bornDate = ?,email = ?,address = ? where tid = ?;";

		Object[] args = { teacher.getName(), teacher.getAge(),
				teacher.getBornDate(), teacher.getEmail(),
				teacher.getAddress(), teacher.getTid() };
		return daoUtils.commonsUpdate(sql, args);
	}

	// 查询单个:根据教师tid查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Teacher对象,将该对象返回
	@Override
	public Teacher selectOne(int tid) {

		String sql = "select * from teacher where tid = ?;";
		List<Object> objectList = daoUtils.commonsSelect(sql, rowMapper, tid);

		if (objectList.size() == 1) {
			Teacher teacher = (Teacher) objectList.get(0);
			return teacher;
		} else {
			return null;
		}
	}

	// 查询所有:将teacher表中的所有数据全部查询出来,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成多个Teacher对象,将多个对象存储在集合中,返回这个集合
	@Override
	public List<Teacher> selectAll() {

		List<Teacher> teacherList = new ArrayList<Teacher>();
		String sql = "select * from teacher;";
		DaoUtils daoUtils = new DaoUtils();
		Object[] args = null;
		List<Object> objectList = daoUtils.commonsSelect(sql, rowMapper, args);
		for (int i = 0; i < objectList.size(); i++) {
			teacherList.add((Teacher) objectList.get(i));
		}
		return teacherList;
	}

}

7、com.cxyzxc.www.service包

该包用来存储业务层接口代码

package com.cxyzxc.www.service;

import java.util.List;

import com.cxyzxc.www.entity.Teacher;

public interface TeacherService {
	
	//添加老师
	int addTeacher(Teacher teacher);
	
	//删除老师
	int deleteTeacher(int tid);
	
	//修改老师
	int updateTeacher(Teacher teacher);
	
	//查询一个老师
	Teacher selectOne(int tid);
	
	//查询所有老师
	List<Teacher> selectAll();

}

8、com.cxyzxc.www.service.impl包

该包用来存储service层实现类代码

package com.cxyzxc.www.service.impl;

import java.util.List;

import com.cxyzxc.www.dao.impl.TeacherDaoImpl;
import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;

public class TeacherServiceImpl implements TeacherService {

	@Override
	public int addTeacher(Teacher teacher) {

		TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();

		Teacher teacher2 = teacherDaoImpl.selectOne(teacher.getTid());

		if (teacher2 == null) {
			return teacherDaoImpl.insert(teacher);
		} else {
			System.out.println("老师已存在");
		}

		return 0;

	}

	@Override
	public int deleteTeacher(int tid) {
		TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
		Teacher teacher2 = teacherDaoImpl.selectOne(tid);

		if (teacher2 == null) {
			System.out.println("你要删除的老师不存在,无法删除");
		} else {
			return teacherDaoImpl.delete(tid);
		}
		return 0;

	}

	@Override
	public int updateTeacher(Teacher teacher) {
		TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
		Teacher teacher2 = teacherDaoImpl.selectOne(teacher.getTid());
		if (teacher2 == null) {
			System.out.println("你要修改的老师不存在,无法修改");
		} else {
			return teacherDaoImpl.update(teacher);
		}
		return 0;
	}
	
	@Override
	public Teacher selectOne(int tid){
		TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
		Teacher teacher =teacherDaoImpl.selectOne(tid);
		return teacher;
	}
	
	@Override
	public List<Teacher> selectAll(){
		TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
		return teacherDaoImpl.selectAll();
	}

}

9、com.cxy.zxc.view包

该包用来存储测试类

【1】测试插入数据

package com.cxyzxc.www.view;

import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;
import com.cxyzxc.www.utils.DateUtils;

public class TestTeacherServiceImpl01Insert {

	public static void main(String[] args) {

		
		TeacherService teacherService = new TeacherServiceImpl();
		
		Teacher teacher = new Teacher(1004, "王五", 30, DateUtils.strDateToUtilDate("1992-10-07"), "13645678912@qq.com", "安徽合肥庐阳区");
		
		int result =teacherService.addTeacher(teacher);
		
		if(result!=0){
			System.out.println("老师添加成功");
		}

	}

}

【2】测试删除数据

package com.cxyzxc.www.view;

import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;

public class TestTeacherServiceImpl02Delete {

	public static void main(String[] args) {
		
		TeacherService teacherService = new TeacherServiceImpl();
				
		int result =teacherService.deleteTeacher(1004);
		
		if(result!=0){
			System.out.println("删除成功");
		}

	}

}

【3】测试修改数据

package com.cxyzxc.www.view;

import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;
import com.cxyzxc.www.utils.DateUtils;

public class TestTeacherServiceImpl03Update {

	public static void main(String[] args) {

		TeacherService teacherService = new TeacherServiceImpl();

		Teacher teacher = new Teacher(1003, "王五", 30,
				DateUtils.strDateToUtilDate("1992-08-07"),
				"13677881122@qq.com", "安徽合肥政务区");

		int result = teacherService.updateTeacher(teacher);
		
		if(result!=0){
			System.out.println("修改成功");
		}
	}

}

【4】测试查询一条数据

package com.cxyzxc.www.view;

import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;

public class TestTeacherServiceImpl04SelectOne {

	public static void main(String[] args) {

		TeacherService teacherService = new TeacherServiceImpl();

		Teacher teacher = teacherService.selectOne(1002);

		if (teacher != null) {
			System.out.println(teacher);
		} else {
			System.out.println("你查询的老师不存在");
		}

	}

}

【5】测试查询所有数据

package com.cxyzxc.www.view;

import java.util.List;

import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;

public class TestTeacherServiceImpl05SelectAll {

	public static void main(String[] args) {
		
		TeacherService teacherService = new TeacherServiceImpl();

		List<Teacher> listTeacher = teacherService.selectAll();

		for (int i = 0; i < listTeacher.size(); i++) {
			System.out.println(listTeacher.get(i));
		}
	}

}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【文献整理】基于深度强化学习的知识图谱推理研究

目录DeepPath背景Core贡献几个要点&#xff1a;Training pipeline结论DIVINE背景Core贡献预备知识DIVINE推理过程模型文献整理基于综述论文&#xff1a;基于深度强化学习的知识推理研究进展综述_宋浩楠&#xff0c;赵刚&#xff0c;孙若莹 文中对知识图谱推理进行如下分类&…

SpringSecurity(十七)---OAuth2的运行机制(下)-实现一个简单的单点登录应用程序

一、前言 本章实现第一个使用带有Spring Boot和Spring Security 的OAuth2框架的应用程序。这个示例将展示如何将OAuth2应用到Spring Security中&#xff0c;并阐释你需要了解的一些接口的内容。顾名思义&#xff0c;单点登录&#xff08;SSO&#xff09;应用程序是通过授权服务…

如何使用一台电脑远程控制多台电脑

如今&#xff0c;远程控制软件已经广泛应用于我们的日常生活中。我们使用远程桌面软件远程控制另一台电脑来完成我们的工作和学习。在某些情况下&#xff0c;我们可能还需要同时远程控制多台电脑。例如&#xff1a; 您是一名培训师&#xff0c;正在寻找远程访问软件来同时远程…

[激光原理与应用-15]:《激光原理与技术》-1- 什么是激光,激光概述

目录 第1章 什么是激光 1.1 什么是激光 1.2激光在生活中应用 第2章 激光的特点 2.1 方向性好&#xff08;平行性、直线性&#xff09; 2.2 单色性好&#xff08;颜色纯度高&#xff09; 2.3 相干性比太阳光好 2.4 亮度高 2.5 能量极大 第3章 光产生的方式与核心概念 …

又爆冷了啦,日本半场逆转德国,怎么利用共享经济搅乱世界杯格局

近日世界杯热点逐渐升高&#xff0c;在23号晚上亚洲劲旅日本以2-1逆转多次捧得大力神杯的德国队&#xff0c;此前德国还从未输过日本队&#xff0c;因此德国再次吃到闭门羹&#xff0c;爆出了本届世界杯开赛以来既阿根廷惨败的又一大冷门。赛后&#xff0c;日本全国人民共同庆祝…

Web(二)html5基础-超链接的应用(知识训练和编程训练)

web知识训练_html5_超链接的应用 web编程训练_html5_超链接的应用 第1关_创建热字超链接 编程要求 在右侧编辑器中的Begin - End区域内补充代码&#xff0c;创建热字超链接&#xff0c;具体要求是&#xff1a; 1.链源文字为“听音乐找酷我”。 2.链宿地址为“https://www.ku…

FPGA——多路选择器实现按键控制LED灯的亮灭

文章目录前言一、多路选择器二、绘制模块框图及波形图三、Verilog HDL代码及测试代码四、创建工程五、仿真六、上板验证1、分配引脚2、烧录七、效果演示八、总结前言 软件&#xff1a;Quartus Prime Standard 18.0仿真软件&#xff1a;modelsim 10.5代码编写软件&#xff1a;V…

【虹科新品】 HK-MR430330绝对式光纤编码器介绍合集(下)

HK-MR430系列ZapFREE光纤位置传感器是一款外形小巧、具有13位单圈分辨率的旋转位置传感器。MR430设计新颖&#xff0c;开发了新的应用和OEM产品功能&#xff0c;这在以前的电子传感器是无法实现的。该传感器100%无源&#xff0c;不受EMI、RFI、微波和磁场的影响。创新型全绝缘设…

我参加NVIDIA Sky Hackathon 后端修改

文件架构 前面两个分别是执行语音识别和图片识别的代码templates 存放的是网页的模板&#xff0c; 前端将文件写在这里即可uploads 存放的是上传至后台的文件server.ipynb 用于启动 flash 服务器app.py 内是用 flash 写的 Python 后端install_tools.sh 是用于安装相关工具的 sh…

(十四)Spring之回顾代理模式

文章目录回顾代理模式动态代理常用技术CGLIB动态代理技术上一篇&#xff1a;&#xff08;十三&#xff09;Spring之JdbcTemplate 回顾代理模式 参考&#xff1a;代理模式Proxy Pattern 不用JDK的动态代理&#xff0c;手写JDK动态代理 动态代理常用技术 在程序运行阶段&…

CentOS 7 手动安装OpenStack

官网文档 因为之前已经在 Ubuntu 20.04 下完成了 Ubuntu 20.04 手动安装OpenStack &#xff0c;最后&#xff0c;想要学习 OVN 的时候&#xff0c;发现 ubuntu 上的 OVN 安装很复杂&#xff0c;没有 TripleO/RDO based deployments &#xff0c;所以&#xff0c;又在 CentOS 7…

项目开源!基于PaddleDetection打造实时人体姿态检测的多关节控制皮影机器人

本文已在【飞桨PaddlePaddle】公众号平台发布&#xff0c;详情请戳链接&#xff1a;项目开源&#xff01;基于PaddleDetection打造实时人体姿态检测的多关节控制皮影机器人 皮影戏是一种以兽皮或纸板做成的人物剪影以表演故事的民间戏剧&#xff0c;皮影一般由头、躯干&#x…

2003-2019年各省市场分割指数全步骤数据+最终结果

2003-2019年市场分割指数 1、时间&#xff1a;2003-2019年 2、数据包含&#xff1a;31各省份市场分割指数全步骤数据和最终结果 3、具体内容&#xff1a;市场分割指数差分形式相对价格、市场分割指数去均值、市场分割指数方差、市场分割指数最终结果。 4、指标说明&#xf…

vue3 框架学习概念笔记

文章目录前情提要框架设计概览命令式声明式小结虚拟dom性能运行时和编译时框架设计核心要素声明式描述UI渲染器组件的本质vue.js模板响应式系统概念完善的响应式系统响应式系统的调度计算属性Computedwatch 原理竞态问题非原始值的响应式方案javaScript 对象原始值的响应式方案…

毕业后河北种水稻 国稻种芯·中国水稻节:安徽姑娘承德务农

毕业后河北种水稻 国稻种芯中国水稻节&#xff1a;安徽姑娘承德务农 (新华每日电讯记者刘金海、方欣、牟宇) 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff1a;整…

【Linux】内存查看vmstat命令(虚拟内存统计)

vmstat命令&#xff1a;虚拟内存统计 CPU使用率内存试用虚拟内存交换情况IO读写情况 process r&#xff1a;运行和等待CPU时间片的进程数 超过cpu个数&#xff0c; 出现CPU瓶颈 长时间大于1&#xff0c;CPU不足&#xff0c;需要增加CPU b&#xff1a;正在等待资源的进程数&…

玩转MySQL:定位排查解决突发Bug

引言 前面MySQL优化、调化两文中&#xff0c;聊到了关于数据库性能优化的话题&#xff0c;而本文则再来聊一聊关于MySQL线上排查方面的话题。线上排查、性能优化等内容是面试过程中的“常客”&#xff0c;而对于线上遇到的“疑难杂症”&#xff0c;需要通过理性的思维去分析问…

Java岗位必备技能SpringBoot的面试题集锦

当下SpringBoot框架真的很火&#xff0c;大多数企业把它作为基础技能&#xff0c;考察求职者的能力。如下截图&#xff0c;是我从Boss直聘中找到的&#xff0c;要求SpringBoot是必备技能。 所以非常有必要为了面试&#xff0c;好好归纳下SpringBoot常被提起来的问题。 题目大纲…

Tesseract .Net SDK C# OCR 2022.1

Tesseract .Net SDK C# OCR 库 #将扫描的 PDF 转换为可搜索的文档 #快速准确的基于神经网络的引擎 #纠正低质量扫描 # 120 多种语言 # .Net 2.0, .Net 5, 标准, 核心 Tesseract OCR - industry-fastest .Net OCR library 4 行代码&#xff0c;仅此而已 var api OcrApi.Creat…

[附源码]java毕业设计疫情环境下的酒店管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…