JDBC技术

Java访问数据库技术概述

在JDBC出现之前,早期java需要访问数据库时,需要根据不同的数据库管理系统(DBMS)编写不同的数据源,使用一项称之为JDBC-ODBC桥链接模式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G9IQuuRy-1596978444053)(D:\Java\图片\1596418546788.png)]

通过以上访问方式,程序员会在访问数据方面花费大把精力,因此SUN在后来设计的JDBC接口,将访问数据库的具体实现交给不同的数据库厂商各自实现,从而减少java程序的压力。

JDBC入门

JDBC(Java Database Connectivity),java 链接数据库技术,是由java.sql包中提供的一系列接口构成,通过这些接口结合不同的数据库管理系统的驱动包,可以非常轻松的实现java访问数据库。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MG6BklFt-1596978444058)(D:\Java\图片\1596418709023.png)]

入门案例

//1.加载数据库驱动(注册驱动)  JDBC4之后无需编写
Class.forName("com.mysql.jdbc.Driver"); 
//2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb2", "root", "123456");
//3.获取执行sql语句命令的对象
Statement stat = conn.createStatement();
//4.执行sql
boolean f = stat.execute("insert into tbuser(username,password) values('java-jdbc','112233')");
//5.处理结果
System.out.println("执行结果:"+f);
//6.关闭资源
stat.close();
conn.close();

JDBC相关接口介绍

jdbc中常用的类和接口:

  • DriverManager
  • Connection
  • Statement/PreparedStatement
  • ResultSet

DriverManager

​ 驱动管家类,java.sql中提供的一个具体类,内部包含了一些用于加载数据库驱动的方法以及获取连接的操作:getConnection

使用DriverManager获取数据库连接的三种方式

// 方法一:
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb2", "root", "123456");//方法二:
//		Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb2?user=root&password=123456");//方法三:
//		Properties info = new Properties();
//		info.put("user", "root");
//		info.put("password","123456");
//		Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb2", info);

Connection

Connection用于表示从Java程序到数据库的连接通道,通过Connection可以向数据库传输sql命令,并且返回执行结果.另外Connection也可以用于对数据库事务管理,具体使用:

//获取执行sql的命令对象
Statement stat = connection.createStatement();//获取sql语句的预处理对象(防止sql注入)
PreparedStatement ps = connection.parepareStatement();//获取一个用于发送存储过程调用命令对象
CallableStatement pc = connection.prepareCall();//设置禁止事务自动提交
connection.setAutoCommit(false);//回滚事务
connection.rollback();//事务提交
connection.commit();

Statement&PreparedStatement

​ 是一个用于执行sql命令的对象,主要用于执行静态sql(事先准备好的,固定的);由于Statement的固有不安全性(很有可能导致sql注入的风险),因此还提供一个直接子接口:PreparedStatement(预处理命令对象),可以有效的防止sql注入的风险。

Statement中提供的常见方法:

  • boolean execute(String sql)
  • int executeUpdate(String sql)
  • ResultSet executeQuery(String sql)

PreparedStatement提供的方法:

  • int executeUpdate();
  • ResultSet executeQuery();
//方式SQL注入,使用PreparedStatement
public static void login2(String username,String password) throws ClassNotFoundException, SQLException {String sql = "select * from tbuser where username=? and password=?";//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.获取连接Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb2", "root", "123456");//3.获取预处理sql命令的对象(对传入的sql与进行预编译,防止出现sql注入问题)PreparedStatement ps = conn.prepareStatement(sql);//预处理ps.setString(1, username);ps.setString(2, password);//4.执行ResultSet rs = ps.executeQuery();//5.处理结果if(rs.next()) {System.out.println("登录成功!");}else {System.out.println("请检查账号和密码!");}//6.关闭资源rs.close();ps.close();conn.close();
}//Statement可能导致sql注入
public static void login(String username,String password) throws ClassNotFoundException, SQLException {String sql = "select * from tbuser where username='" + username + "' and password='" + password + "'";System.out.println("执行sql语句:" + sql);//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.获取连接Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb2", "root", "123456");//3.获取处理sql命令的对象Statement stat = conn.createStatement();//4.执行sqlResultSet rs = stat.executeQuery(sql);//5.处理结果if(rs.next()) {System.out.println("登录成功!");}else {System.out.println("请检查账号和密码!");}//6.关闭资源rs.close();stat.close();conn.close();
}

测试:

login2("sdrfsdf", "' or '1=1");

Statement和PreparedStatement的区别?

Statement是原始的执行sql命令的对象,不对sql语句做任何处理,可能会因为传入的参数问题导致sql注入,因此存在注入的风险;所以在实际开发中更加推荐使用PreparedStatement,该接口的实现针对sql语句进行了预编译,解决了可能出现的sql注入风险;另外PreparedStatement内部使用预编译机制,从运行效率来看,略高于Statement。

ResultSet

结果集对象,用于表示对于查询语句执行之后的结果,内部的数据可能是一条也可以是多条

CRUD操作

CRUD,增删改查,基于Java对数据库表中的数据进行增删改查操作(insert ,delete,update,select)

CRUD操作

package com.softeem.lesson48.crud;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import com.softeem.lesson48.utils.DBUtils;public class UserCRUD {private Connection conn;/*** 	添加数据* @param username* @param password* @return* @throws ClassNotFoundException* @throws SQLException*/public boolean insert(String username,String password) throws ClassNotFoundException, SQLException {PreparedStatement ps = null;try {//DBUtil类参考JDBC基本封装conn = DBUtils.getConn();String sql = "insert into tbuser(username,password) values(?,?)";//3.获取sql语句预处理对象ps = conn.prepareStatement(sql);ps.setString(1, username);ps.setString(2, password);//4.执行int i = ps.executeUpdate();//5.处理结果return i > 0;}finally {DBUtils.close(null, ps, conn);}}/*** 	修改数据* @param id* @param password* @return* @throws ClassNotFoundException* @throws SQLException*/public boolean update(int id,String password) throws ClassNotFoundException, SQLException {String sql = "update tbuser set password=? where id=?";PreparedStatement ps = null;try {conn = DBUtils.getConn();//3.获取sql语句预处理对象ps = conn.prepareStatement(sql);ps.setString(1, password);ps.setInt(2, id);//4.执行int i = ps.executeUpdate();return i > 0;}finally {DBUtils.close(null, ps, conn);}}/*** 	删除数据* @param id* @return* @throws ClassNotFoundException* @throws SQLException*/public boolean delete(int id) throws ClassNotFoundException, SQLException {String sql = "delete from tbuser where id=?";PreparedStatement ps = null;try {conn = DBUtils.getConn();//3.获取sql语句预处理对象ps = conn.prepareStatement(sql);ps.setInt(1, id);//4.执行int i = ps.executeUpdate();return i > 0;}finally {DBUtils.close(null, ps, conn);}}/*** 	查询一条数据* @param username* @return* @throws SQLException*/public Map<String,Object> selectOne(String username) throws SQLException{//声明map作为返回值Map<String,Object> map = new HashMap<String, Object>();String sql = "select * from tbuser where username=?";PreparedStatement ps = null;ResultSet rs = null;try {conn = DBUtils.getConn();//3.获取预处理是sql命令的对象ps = conn.prepareStatement(sql);ps.setString(1, username);//4.执行查询rs = ps.executeQuery();if(rs.next()) {//根据列的标签(默认列名,如有设置别名,则标签为别名)获取列值int id = rs.getInt("id");String name = rs.getString("username");String pwd = rs.getString("password");//将获取的数据装入map集合map.put("id", id);map.put("username", name);map.put("password", pwd);}} finally {DBUtils.close(rs, ps, conn);}return map;}/*** 	查询所有* @return* @throws SQLException*/public List<Map<String,Object>> selectAll() throws SQLException{List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();String sql = "select * from tbuser";PreparedStatement ps = null;ResultSet rs = null;try {conn = DBUtils.getConn();//3.获取预处理是sql命令的对象ps = conn.prepareStatement(sql);//4.执行查询rs = ps.executeQuery();while(rs.next()) {Map<String,Object> map = new HashMap<String, Object>();//根据列的标签(默认列名,如有设置别名,则标签为别名)获取列值int id = rs.getInt("id");String name = rs.getString("username");String pwd = rs.getString("password");//将获取的数据装入map集合map.put("id", id);map.put("username", name);map.put("password", pwd);list.add(map);}} finally {DBUtils.close(rs, ps, conn);}return list;}public static void main(String[] args) throws ClassNotFoundException, SQLException {UserCRUD crud = new UserCRUD();//		boolean f = crud.insert("softeem123", "123softeem");//		boolean f = crud.update(2, "666666");//		boolean f = crud.delete(12);//		System.out.println("执行结果:"+f);//		Map<String,Object> map = crud.selectOne("softeem");List<Map<String, Object>> list = crud.selectAll();list.forEach(u->System.out.println(u));}
}

JDBC基本封装

/*** 	数据库工具类V1.0* 	将访问数据库的公共代码抽取:*  1.加载驱动*  2.获取连接*  6.关闭资源* @author mrchai**/
public class DBUtils {/**驱动类路径*/private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";/**url地址*/private static final String URL = "jdbc:mysql://127.0.0.1:3306/mydb2";/**数据库服务器登录用户名*/private static final String USER = "root";/**数据库服务器登录密码*/private static final String PASSWORD = "123456";static {try {//1.加载驱动Class.forName(DRIVER_CLASS);} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 	2. 获取数据库连接对象* @return*/public static synchronized Connection getConn() {try {return DriverManager.getConnection(URL, USER, PASSWORD);} catch (SQLException e) {e.printStackTrace();}return null;}/*** 	6.关闭资源* @param rs* @param stat* @param conn*/public static void close(ResultSet rs,Statement stat,Connection conn) {try {if(rs != null)rs.close();if(stat != null)stat.close();if(conn != null)conn.close();} catch (SQLException e) {e.printStackTrace();}}
}

JDBC查询详解

分页查询

public static List<Emp> queryByPage(int start,int limit) {List<Emp> list = new ArrayList<Emp>();String sql = "select * from emp limit ?,?";Connection conn = DBUtils.getConn();ResultSet rs = null;PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);ps.setInt(1,start);ps.setInt(2, limit);rs = ps.executeQuery();while(rs.next()) {int eno = rs.getInt("eno");String ename = rs.getString("ename");String job = rs.getString("job");Date hiredate = rs.getDate("hiredate");int age = rs.getInt("age");String sex = rs.getString("sex");double sal = rs.getDouble("sal");int dno = rs.getInt("dno");//将获取的员工信息存储到对象中Emp e = new Emp(eno, ename, job, hiredate, age, sex, sal, dno);//将对象装入集合list.add(e);}} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.close(rs, ps, conn); }return list;
}

查询单行单列

/*** 	查询总记录数*/public static void queryCount() {String sql = "select count(*) from emp";Connection conn = DBUtils.getConn();PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement(sql);rs = ps.executeQuery();if(rs.next()) {int count = rs.getInt(1);
//				int count = rs.getInt("count(*)");System.out.println("总数据行数:"+count);}} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.close(rs, ps, conn); }}

执行关联查询

/*** 	多表联合查询*/
public static List<EmpInfo> queryMultipleTable() {List<EmpInfo> list = new ArrayList<EmpInfo>();String sql = "select e.ename ename,e.job job,e.hiredate hiredate,d.dname dname from emp e,dept d where e.dno=d.dno";Connection conn = DBUtils.getConn();ResultSet rs = null;PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);rs = ps.executeQuery();while(rs.next()) {String ename = rs.getString("ename");String job = rs.getString("job");Date hiredate = rs.getDate("hiredate");String dname = rs.getString("dname");Emp e = new Emp();e.setEname(ename);e.setJob(job);e.setHiredate(hiredate);Dept d = new Dept();d.setDname(dname);EmpInfo info = new EmpInfo();info.setEmp(e);info.setDept(d);list.add(info);}} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.close(rs, ps, conn); }return list;
}

JDBC执行DDL操作

public class DDLDemo {public static void main(String[] args) throws SQLException {String sql = "create table tblog("+ "id int primary key auto_increment,"+ "event_name varchar(30),"+ "event_time timestamp default CURRENT_TIMESTAMP)";Connection conn = DBUtils.getConn();PreparedStatement ps = conn.prepareStatement(sql);boolean f = ps.execute();System.out.println(f);DBUtils.close(null, ps, conn);}}

getGeneratedKeys获取自动生成键

public class JDBCGenKeys {public static int insert(String eventName) {int id = 0;String sql = "insert into tblog(event_name) values(?)";Connection conn = DBUtils.getConn();PreparedStatement ps = null;ResultSet rs = null;try {//获取预处理sql命令的对象,该对象允许返回自动生成的键ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);ps.setString(1, eventName);int i = ps.executeUpdate();if(i > 0) {//返回包含自动生成的键的结果集rs = ps.getGeneratedKeys();id = rs.next() ? rs.getInt(1) : 0;}} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.close(rs, ps, conn);}return id;}public static void main(String[] args) {int id = insert("修改数据了");System.out.println(id);}
}

SQL语句批处理

public class JDBCBatchDemo {public static void batchByPs() throws SQLException {String sql = "insert into tblog(event_name) values(?)";//eclipse:ctrl+1   idea:alt+enterConnection conn = DBUtils.getConn();PreparedStatement ps = conn.prepareStatement(sql); for (int i = 0; i < 100000; i++) {ps.setString(1, "数据添加"+i); //批处理ps.addBatch();}//执行int[] results = ps.executeBatch();for (int i : results) {System.out.println("受影响数据行:"+i);}DBUtils.close(null, ps, conn);}public static void batchByStatement() throws SQLException {String sql1 = "insert into tblog(event_name) values('查询100条数据')";String sql2 = "delete from tblog where id>100";String sql3 = "update tblog set event_name='修改前5条数据'  where id<=5";Connection conn = DBUtils.getConn();Statement state = conn.createStatement();state.addBatch(sql1);state.addBatch(sql2);state.addBatch(sql3);int[] results = state.executeBatch();for (int i : results) {System.out.println("受影响数据行:"+i);}DBUtils.close(null, state, conn);}public static void main(String[] args) throws SQLException {batchByStatement();}}

DAO与Entity(vo/dto/po/pojo)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u8xpZyjG-1596978444061)(D:\带班资料\2020\j2003\线下\part3-mysql&jdbc\20200804\笔记\assets\1596538588031.png)]

​ 以上时序图是常见的web项目架构模式,其中对于频繁的数据访问操作,实际开发中通常会抽取一层DAO(Data Access Object)层;DAO层主要负责访问数据库,对数据表进行CRUD操作,DAO层并不关注具体的业务逻辑,因此称之为数据访问层。

常见DAO层的定义语法:

public class EmpDAO{public boolean insert(Emp d) {// 执行添加操作return false;}public boolean delete(int id) {// 执行删除操作return false;}public boolean update(Emp d) {// 执行更新操作return false;}public Emp findById(int id) {// 根据id查询return null;}public Emp findById(int id) {// 查询所有return null;}
}

基于接口和泛型的IBaseDAO定义

由于大多数针对实体类的操作无外乎insert,update,delete,select操作,因此,可以将这些常见操作抽取出一个公共的接口,该接口只定义相关的标准,具体实现可以由对应的实现类完成:

public interface IBaseDAO<T> {/*** 	执行插入操作* @param d* @return*/boolean insert(T d);/*** 执行删除操作* @param id* @return*/boolean delete(int id);/*** 执行更新操作* @param d* @return*/boolean update(T d);/*** 根据id查询对象* @param id* @return*/T findById(int id);/*** 查询所有对象* @return*/List<T> findAll();}

实现

public class DeptDAO implements IBaseDAO<Dept> {@Overridepublic boolean insert(Dept d) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean delete(int id) {// TODO Auto-generated method stubreturn false; }@Overridepublic boolean update(Dept d) {// TODO Auto-generated method stubreturn false;}@Overridepublic Dept findById(int id) {// TODO Auto-generated method stubreturn null;}@Overridepublic List<Dept> findAll() {// TODO Auto-generated method stubreturn null;}public Dept findByDname(String dname) {// TODO Auto-generated method stubreturn null}
}

通用更新封装

观察所有的INSERT,DELETE,UPDATE操作,基本都会存在以下几个步骤:

  • 准备sql语句
  • 连接获取
  • 获取预处理sql命令的对象
  • 预处理
  • 执行更新
  • 关闭资源

而以上除了sql语句和预处理操作不一致以外,其他步骤几乎一致,因此可以通过以下封装来简化对于所有更新的操作:

/**
* 封装通用的更新操作:INSERT UPDATE DELETE
* 
* @param sql
* @param params 
* @return
*/
public static boolean exeUpdate(String sql, Object... params) {// 获取连接Connection conn = getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);if (params != null) {for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}}return  ps.executeUpdate() > 0;} catch (SQLException e) {e.printStackTrace();}finally {close(null, ps, conn);}return false;
}

ResultSetMetaData

public class ResultSetMetaDataDemo {public static void main(String[] args) throws SQLException {String sql = "select * from tblog";Connection conn = DBUtils.getConn();PreparedStatement ps = conn.prepareStatement(sql);ResultSet rs = ps.executeQuery();//获取结果集的元数据ResultSetMetaData rsmd = rs.getMetaData();//查询的列数int count = rsmd.getColumnCount();System.out.println("查询总列数:"+count);while(rs.next()) {//遍历所有的列for (int i = 1; i <= count; i++) {//获取列名称String name = rsmd.getColumnName(i);String label = rsmd.getColumnLabel(i);int type = rsmd.getColumnType(i);Object value = rs.getObject(label);System.out.print(name+"--"+label+"--"+type+"==="+value);}System.out.println();}}
}

基于反射实现查询封装

/*** 封装通用查询单条数据的方法* * JDBC,反射,集合框架,lambda表达式,新增Objects类* * @param <T>* @param t* @param sql* @param params* @return*/
public static <T> T queryOne(Class<T> t, String sql, Object... params) {// 获取查询到到数据集合List<Map<String, Object>> list = queryMaps(sql, params);if (list.size() > 0) {// 获取一个Map对象Map<String, Object> map = list.get(0);// 将map集合转换为Javabean并返回return mapToBean(map, t);}return null;
}/*** 封装通用查询多条数据的方法* * @param <T>* @param t* @param sql* @param params* @return*/
public static <T> List<T> queryList(Class<T> t, String sql, Object... params) {List<T> list = new ArrayList<T>();// 获取所有查询的到的数据List<Map<String, Object>> maps = queryMaps(sql, params);// 遍历集合中每一条数据(map)maps.forEach(m -> {// 将map转换为JavabeanT obj = mapToBean(m, t);// 将Javabean装入listlist.add(obj);});return list;
}/*** 将Map集合转换为一个确定的类型* * @param <T>* @param map* @param t* @return*/
private static <T> T mapToBean(Map<String, Object> map, Class<T> t) {//		T obj = null;try {// 根据提供的Class对象创建对应类型的ObjectT obj = t.newInstance();map.forEach((k, v) -> {try {// 根据Field名称获取字段对象Field field = t.getDeclaredField(k);// 设置字段的可访问性field.setAccessible(true);// 为字段设置值field.set(obj, v);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}});return obj;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}// 返回对象return null;
}/*** 执行相关查询并将结果返回为List<Map<String,Object>> 集合* * @param sql* @param params* @return*/
public static List<Map<String, Object>> queryMaps(String sql, Object... params) {// 声明动态数组用于存储每一个查询到的Map对象List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();// 获取连接Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {// 获取预处理sql命令的对象ps = conn.prepareStatement(sql);if (params != null) {for (int i = 0; i < params.length; i++) {// 对指定位置的占位符填充值(预处理)ps.setObject(i + 1, params[i]);}}// 执行查询获取结果集rs = ps.executeQuery();// 获取结果集的元数据对象ResultSetMetaDataResultSetMetaData rsmd = rs.getMetaData();// 获取总查询列数int columnCount = rsmd.getColumnCount();// 遍历结果集while (rs.next()) {// 声明map集合存储每一条数据(临时缓存)Map<String, Object> map = new HashMap<String, Object>();// 遍历获取每一列的信息for (int i = 1; i <= columnCount; i++) {// 获取列名称(作为map集合的键)String key = rsmd.getColumnName(i);// 获取列标签String label = rsmd.getColumnLabel(i);// 获取列值(作为map集合的值)Object value = rs.getObject(label);if (Objects.nonNull(value)) {// 将取到的每一列的列名与列值存储到mapmap.put(key, value);}}// 将map集合装入listlist.add(map);}} catch (SQLException e) {e.printStackTrace();} finally {close(rs, ps, conn);}return list;
}/*** 根据提供的查询语句以及查询参数,返回符合条件的数目* * @param sql* @param params* @return*/
public static int queryCount(String sql, Object... params) {Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement(sql);if (params != null) {for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}}rs = ps.executeQuery();if(rs.next()) {return rs.getInt(1);}} catch (SQLException e) {e.printStackTrace();}finally {close(rs, ps, conn);}return 0;
}

DBUtils完全版

package com.softeem.lesson50.utils;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;/*** ORM框架(Mybatis,Hibernate,spring Data JPA)* 数据库工具类V2.0 将访问数据库的公共代码抽取: 1.加载驱动 2.获取连接 6.关闭资源* @author mrchai**/
public class DBUtils {/** 驱动类路径 */private static String DRIVER_CLASS;/** url地址 */private static String URL;/** 数据库服务器登录用户名 */private static String USER;/** 数据库服务器登录密码 */private static String PASSWORD;static {try {//读取属性文件获取连接数据库相关的字符串InputStream is = DBUtils.class.getResourceAsStream("/jdbc.properties");//创建属性对象Properties p = new Properties();//加载包含属性信息的输入流p.load(is);//根据属性名获取属性值DRIVER_CLASS = p.getProperty("driver");URL = p.getProperty("url");USER = p.getProperty("user");PASSWORD = p.getProperty("password");//			 1.加载驱动Class.forName(DRIVER_CLASS);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/*** 2. 获取数据库连接对象* * @return*/public static synchronized Connection getConn() {try {return DriverManager.getConnection(URL, USER, PASSWORD);} catch (SQLException e) {e.printStackTrace();}return null;}/*** 6.关闭资源* * @param rs* @param stat* @param conn*/public static void close(ResultSet rs, Statement stat, Connection conn) {try {if (rs != null)rs.close();if (stat != null)stat.close();if (conn != null)conn.close();} catch (SQLException e) {e.printStackTrace();}}/*** 封装通用的更新操作:INSERT UPDATE DELETE* * @param sql* @param params Object[] params* @return*/public static boolean exeUpdate(String sql, Object... params) {// 获取连接Connection conn = getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);if (params != null) {for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}}return ps.executeUpdate() > 0;} catch (SQLException e) {e.printStackTrace();} finally {close(null, ps, conn);}return false;}/*** 封装通用查询单条数据的方法* * JDBC,反射,集合框架,lambda表达式,新增Objects类* * @param <T>* @param t* @param sql* @param params* @return*/public static <T> T queryOne(Class<T> t, String sql, Object... params) {// 获取查询到到数据集合List<Map<String, Object>> list = queryMaps(sql, params);if (list.size() > 0) {// 获取一个Map对象Map<String, Object> map = list.get(0);// 将map集合转换为Javabean并返回return mapToBean(map, t);}return null;}/*** 封装通用查询多条数据的方法* * @param <T>* @param t* @param sql* @param params* @return*/public static <T> List<T> queryList(Class<T> t, String sql, Object... params) {List<T> list = new ArrayList<T>();// 获取所有查询的到的数据List<Map<String, Object>> maps = queryMaps(sql, params);// 遍历集合中每一条数据(map)maps.forEach(m -> {// 将map转换为JavabeanT obj = mapToBean(m, t);// 将Javabean装入listlist.add(obj);});return list;}/*** 将Map集合转换为一个确定的类型* * @param <T>* @param map* @param t* @return*/private static <T> T mapToBean(Map<String, Object> map, Class<T> t) {
//		T obj = null;try {// 根据提供的Class对象创建对应类型的ObjectT obj = t.newInstance();// 获取Class中的所有Field
//			Field[] fields = t.getDeclaredFields();
//			//遍历获取每一个属性对象
//			for (Field field : fields) {
//				//获取属性名
//				String fname = field.getName();
//				//获取属性值
//				Object value = map.get(fname);
//				if(Objects.nonNull(value)) {
//					//设置属性对象的可访问性
//					field.setAccessible(true);
//					//将从map中获取的值设置给属性  obj.name=XX
//					field.set(obj, value);
//				}
//			}map.forEach((k, v) -> {try {// 根据Field名称获取字段对象Field field = t.getDeclaredField(k);// 设置字段的可访问性field.setAccessible(true);// 为字段设置值field.set(obj, v);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}});return obj;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}// 返回对象return null;}/*** 执行相关查询并将结果返回为List<Map<String,Object>> 集合* * @param sql* @param params* @return*/public static List<Map<String, Object>> queryMaps(String sql, Object... params) {// 声明动态数组用于存储每一个查询到的Map对象List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();// 获取连接Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {// 获取预处理sql命令的对象ps = conn.prepareStatement(sql);if (params != null) {for (int i = 0; i < params.length; i++) {// 对指定位置的占位符填充值(预处理)ps.setObject(i + 1, params[i]);}}// 执行查询获取结果集rs = ps.executeQuery();// 获取结果集的元数据对象ResultSetMetaDataResultSetMetaData rsmd = rs.getMetaData();// 获取总查询列数int columnCount = rsmd.getColumnCount();// 遍历结果集while (rs.next()) {// 声明map集合存储每一条数据(临时缓存)Map<String, Object> map = new HashMap<String, Object>();// 遍历获取每一列的信息for (int i = 1; i <= columnCount; i++) {// 获取列名称(作为map集合的键)String key = rsmd.getColumnName(i);// 获取列标签String label = rsmd.getColumnLabel(i);// 获取列值(作为map集合的值)Object value = rs.getObject(label);if (Objects.nonNull(value)) {// 将取到的每一列的列名与列值存储到mapmap.put(key, value);}}// 将map集合装入listlist.add(map);}} catch (SQLException e) {e.printStackTrace();} finally {close(rs, ps, conn);}return list;}/*** 根据提供的查询语句以及查询参数,返回符合条件的数目* * @param sql* @param params* @return*/public static int queryCount(String sql, Object... params) {Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement(sql);if (params != null) {for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}}rs = ps.executeQuery();if(rs.next()) {return rs.getInt(1);}} catch (SQLException e) {e.printStackTrace();}finally {close(rs, ps, conn);}return 0;}}

连接池技术

由于数据库连接是一种资源,这种资源在使用前必须先创建,而这个创建过程是存在时间和空间的开销的,如果每次在执行数据库访问时都创建连接,并且使用完后要关闭连接,这个过程必然是效率低下的;因此,在实际开发中可以考虑在进行数据库操作前,先提前创建并维护一批数据库连接对象,当需要使用时,从这批对象中获取一个连接,用完之后再返还,从而避免了不必要的时间开销,提高程序的运行效率,这种技术在JDBC中称之为连接池技术(Connection Pool).

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QjV43j54-1596978444066)(D:/%E5%B8%A6%E7%8F%AD%E8%B5%84%E6%96%99/2019/j1909/%E8%AF%BE%E7%A8%8B%E8%B5%84%E6%96%99/%E8%AF%BE%E7%A8%8B%E5%86%85%E5%AE%B9/note/assets/1565689065391.png)]

​ 目前比较常用的连接池技术包含:apache-DBCP、C3P0(Spring/Hibernate框架在使用)、Proxool、阿里巴巴的Druid以及HikariCP(SpringBoot2.0默认连接池),这里我们分别使用Druid和HikariCP连接池:

Druid连接池使用:

使用前先导入Druid的依赖:druid-1.1.9.jar

实现代码:

public class DruidDemo {public static void main(String[] args) throws SQLException {// 创建数据源DruidDataSource dataSource = new DruidDataSource();
//		dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/mydb2");dataSource.setUsername("root");dataSource.setPassword("123456");// 设置最大链接数dataSource.setMaxActive(5);// 最小闲置链接数dataSource.setMinIdle(1);// 初始连接个数dataSource.setInitialSize(2);// 设置获取连接的最大等待时间dataSource.setMaxWait(10000);// 获取连接Connection conn1 = dataSource.getConnection();System.out.println("conn1:" + conn1);Connection conn2 = dataSource.getConnection();System.out.println("conn2:" + conn2);Connection conn3 = dataSource.getConnection();System.out.println("conn3:" + conn3);Connection conn4 = dataSource.getConnection();System.out.println("conn4:" + conn4);	new Thread() {public void run() {try {sleep(15000);//关闭第四个连接conn4.close();} catch (InterruptedException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}};}.start();Connection conn5 = dataSource.getConnection();System.out.println("conn5:" + conn5);Connection conn6 = dataSource.getConnection();System.out.println("conn6:" + conn6);}
}

HikariCP使用

HikariCP使用需要以下几个依赖:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9E5nZdAT-1596978444068)(D:\带班资料\2020\j2003\线下\part3-mysql&jdbc\20200805\笔记\assets\1596621762539.png)]

实现代码:

public class HikariCPDemo {public static void main(String[] args) throws SQLException {HikariDataSource ds = new HikariDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/mydb2");ds.setUsername("root");ds.setPassword("123456");//设置最大链接数ds.setMaximumPoolSize(10);//设置最小闲置连接ds.setMinimumIdle(1);//设置最长等链接获取时间ds.setConnectionTimeout(10000);Connection conn = ds.getConnection();System.out.println(conn);}
}

day4 - idea使用 & JDBC(四)

InteillJ Idea使用入门

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jymHg9vx-1596978444069)(D:\Java\图片\1596642951480.png)]

项目创建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pjxOEW2Q-1596978444070)(D:\Java\图片\1596675913610.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RCuQB6UO-1596978444071)(D:\Java\图片\1596676161363.png)]

基本设置

主题设置

字体设置

文件过滤

文件版权设置

类名注解配置

对象序列化UID自动生成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GifhF9e5-1596978444072)(D:\Java\图片\1596677861659.png)]

重复代码提示去除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vBUSHdSN-1596978444074)(D:\Java\图片\1596678534646.png)]

去除参数提示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EnQg4eVS-1596978444075)(D:\Java\图片\1596679024818.png)]

忽略大小写提示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdSr9cKh-1596978444076)(D:\Java\图片\1596679153420.png)]

新增自定义实时代码提示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mBoROyLl-1596978444077)(D:\Java\图片\1596679281646.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ViQta1mp-1596978444079)(D:\Java\图片\1596679663165.png)]

插件安装

  • Alibaba Java Coding Guidelines 编码规约检测
  • CodeGlance 代码缩略图
  • GsonFormat 将json字符串转换为实体类

JDBC事务

/*** @Author mrchai 2020/8/6 15:35*/
public class AccountService {/*** 转账操作 从a账户转出money金额到b账户** @param a* @param b* @param money*/public void changeMoney(Account a, Account b, double money) {Connection conn = DBUtils.getConn();try {//1. 禁止事务自动提交conn.setAutoCommit(false);//创建dao对象,并且传入连接对象,保证所有的更新操作来自同一个连接AccountDAO dao = new AccountDAO(conn);//查询a账户a = dao.selectById(a.getId());//查询b账户b = dao.selectById(b.getId());if (a.getMoney() < money) {System.out.println("账户余额不足!");return;}//ctrl+alt+l 代码格式化    ctrl+d 代码复制    ctrl+y 删除代码   ctrl+shift+up/down 代码上下移动//减少a账户余额a.setMoney(a.getMoney() - money);//增加b账户余额b.setMoney(b.getMoney() + money);dao.update(a);System.out.println(10 / 0);dao.update(b);//逻辑正常执行时提交事务conn.commit();} catch (Exception e) {e.printStackTrace();try {//事务回滚conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}} finally{DBUtils.close(null,null,conn);}}public static void main(String[] args) {Account a = new Account();a.setId(1);Account b = new Account();b.setId(2);AccountService service  = new AccountService();service.changeMoney(a,b,10000);}
}
  • 组合
  • 代理模式(动态代理)

存储过程调用

编写过程

-- 过程1,根据员工共工号查询员工
create procedure sp_emp(empno int)
beginselect * from emp where eno=empno;
end-- 分页查询(包含输出参数)
create procedure sp_emp_paging(pagenum int,pagesize int,out pagecount int,out totalnum int)
begindeclare startpage int;set startpage=(pagenum-1)*pagesize;-- 分页查询select * from emp limit startpage,pagesize;-- 将总数据行数查询到并设置给输出参数select count(*) into totalnum from emp;-- 计算获取总页码数set pagecount = CEILING(totalnum/pagesize);
end

JDBC代码

/*** @Author mrchai 2020/8/6 17:24*/
public class ProcedureDemo {/*** 调用普通存储过程* @throws SQLException*/public static void proc1() throws SQLException {Connection conn = DBUtils.getConn();CallableStatement cs = conn.prepareCall("{call sp_emp(?)}");cs.setInt(1,1);boolean f = cs.execute();ResultSet rs = cs.getResultSet();if(rs.next()){int eno = rs.getInt("eno");String ename = rs.getString("ename");String job = rs.getString("job");double sal = rs.getDouble("sal");Date hiredate = rs.getDate("hiredate");System.out.println(eno+"/"+ename+"/"+job+"/"+sal+"/"+hiredate);}rs.close();cs.close();conn.close();}/*** 调用包含输出参数的存储过程*/public static void proc2(int pagenum,int pagesize) throws SQLException {Connection conn = DBUtils.getConn();CallableStatement cs = conn.prepareCall("{call sp_emp_paging(?,?,?,?)}");cs.setInt(1,pagenum);cs.setInt(2,pagesize);//输出参数需要注册(注册输出参数)cs.registerOutParameter(3, Types.INTEGER);cs.registerOutParameter(4, Types.INTEGER);//执行cs.execute();//获取总页码数int totalPage = cs.getInt(3);//获取总数据行数int totalNum  = cs.getInt(4);System.out.println("totalNum-->"+totalNum);System.out.println("totalPager--->"+totalPage);//获取结果集ResultSet rs = cs.getResultSet();while(rs.next()){int eno = rs.getInt("eno");String ename = rs.getString("ename");String job = rs.getString("job");double sal = rs.getDouble("sal");Date hiredate = rs.getDate("hiredate");System.out.println(eno+"/"+ename+"/"+job+"/"+sal+"/"+hiredate);}rs.close();cs.close();conn.close();}public static void main(String[] args) throws SQLException {proc2(1,10);}}
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. OpenSTF 初体验

    本文主要介绍,Windows下通过虚拟机部署Docker,并通过Docker安装OpenSTF,来完成试用体验。01OpenSTFOpenSTF是一个手机设备管理平台,可以对手机进行远程管理、调试、远程手机桌面监控等操作。这个系统类似于目前很流行的云测服务比如Testin,虽然网页上提供的设备很像模拟器…...

    2024/5/3 5:57:44
  2. 转:德鲁克:把员工当自己人照顾,是取得成功的前提

    个人理解:优先考虑他人的需求,主动承担责任 绝大多数人不可能在未受尊重或受到不公平对待时,仍能包容他人。 你可能不喜欢某个人,但你仍需公平诚实地对待他们,尊重他们。 功劳归于员工,责任自己承担。作为领导,别无选择。 人们只愿意服从在考虑其利益方面比他们自己更睿…...

    2024/4/29 7:17:29
  3. 数据库开发技术的课程记录

    数据库开发技术复习「部分」 oracle的无阻塞读。修改才会加锁,行级锁。读写器不会阻塞写入器。提高了并发效率,缺点,无阻塞设计需要保证一次最多只有一个用户读取一行。 where xxx【 FOR UPDATE】关键字 NULL处理的差异,基本差别(并发控制机制) SQL优化方向:索引,执行计…...

    2024/5/4 19:46:58
  4. 谈下对微*1软“服务*1协议”的一点看法

    如果微*1*软的服务*1协议确实是真的,这基本确定了脱*1钩是必然的了,重建软硬件生态就是我们必须干,而且要加快干的事情了。这当然不是个好消息,但如果他们真的这么做,其实也没什么大不了的,既然都撕破脸了,一是可以放肆破1*解老*1外的东西先顶几年,另外就要老老实实加大…...

    2024/5/4 18:47:45
  5. OpenCV-Python 将摄像头捕获的视频灰度处理并保存(代码+详解)

    import numpy as np import cv2 as cv cap = cv.VideoCapture(0)#通过本地摄像头捕获视频 fourcc = cv.VideoWriter_fourcc(*DIVX)#指定fourcc编码 out = cv.VideoWriter(C:\\Users\\DELL4\\Desktop\\output.mp4,fourcc,20.0,(640,480),0)用于灰度图 这里,out是一个VideoWri…...

    2024/5/4 22:54:04
  6. 安卓GreenDao基本使用

    配置参考github官方https://github.com/greenrobot/greenDAO不过发现配置似乎需要翻墙首先在build.gradlerepositories {google()jcenter()mavenCentral() // add repository}classpath org.greenrobot:greendao-gradle-plugin:3.3.0在build.gradle(app中)上部apply plugin: or…...

    2024/5/1 2:12:55
  7. VMware下的Linux的安装配置详解

    点击创建新的虚拟机自定义创建直接下一步选择一个CentOS镜像文件,可以去官网下载,然后下一步为虚拟机取一个名字,以及虚拟机要安装的位置根据自己电脑的配置分配处理器核数,电脑好一点可以给8个内核,差一点可以给2~4个内核这里根据自己电脑内存大小给定虚拟机内存,我电脑…...

    2024/5/4 14:55:00
  8. Koa2基础入门教程

    一、koa安装与hello world示例: koa需要node v7.6.0以上(因为需要ES6) npm install koa --save 习惯性加上save,不加也可以。 koa的hello world示例 const Koa = require(koa); const app = new Koa(); app.use(async(ctx)=>{ctx.body = hello koa!; }) app.listen(3000)…...

    2024/4/29 2:51:27
  9. VMware 桥接,NAT模式,仅主机模式理解

    VMware网络设置里面有三种模式1,桥接模式:实际是使用电脑的真实网卡和VMware通讯,需要网卡和虚拟机在同一个网段,并且手动分配一个IP地址桥接模式配置方法:VMware选择桥接模式电脑上 -> cmd 输入 ipconfig 查看 电脑使用的网段,因为我是网线直连路由器,所以查看以太网…...

    2024/5/4 22:42:03
  10. PYTHON从娃娃学起教程 教案 第三课键盘的使用

    第一应该是先认识键盘,正好我有两个键盘样板,一个是日语键盘,一个是英语键盘下载图片解释然后下面是快捷键说明,然后用python开发的一个小程序,让孩子熟悉键盘,所以我下载了贪吃蛇,还有打飞机的小游戏,一键运行,前十课不能让孩子觉得编程的枯燥,兴趣教学下面是电脑使…...

    2024/5/4 18:55:09
  11. gradle 各种版本下载(自取自用)

    CSDN全都要积分下载 自取自用(ps:如果没有你想要的版本,可以留言,我帮你下载) 官方地址 官方下载gradel地址 不翻墙不能下载司机 下载地址 gradle-2.0-all下载 gradle-2.1-all下载 gradle-2.2-all下载 gradle-2.3-all下载 gradle-2.4-all下载 gradle-2.5-all下载 gradle-2…...

    2024/4/29 7:17:03
  12. U校园自动刷课浏览器-源代码分析

    每个平台的网课都有相应的测试,然鹅这些测试对于那些坚持快乐学习至上原则的同学就不是那么友好了,本着让这部分同学也能享受考高分的乐趣,找到了一些让网课学习更快乐的小帮手。正式教程:内置刷课插件,添加下列代码,实现自动刷课链接:https://wws.lanzous.com/b01hl6qzc…...

    2024/5/1 11:58:04
  13. 深度学习入门之PyTorch学习笔记:卷积神经网络

    深度学习入门之PyTorch学习笔记绪论1 深度学习介绍2 深度学习框架3 多层全连接网络4 卷积神经网络4.1 主要任务及起源4.2 卷积神经网络的原理和结构4.2.1 卷积层1.概述2.局部连接3.空间排列4.零填充的使用5.步长限制6.参数共享7.总结4.2.2 池化层4.2.3 全连接层4.2.4 卷积神经网…...

    2024/4/29 7:16:47
  14. JVM详解(一)之初识JVM

    前言: 一些有一定工作经验的开发人员,觉得SSM、微服务等上层技术才是重点,而忽略了基础的技术,这其实是不可取的,作为一个想向上发 展的开发人员,打好基础是最关键的,不然基础的知识永远是你的致命缺点! 关于JVM详解的博文将以连载方式持续发布到个人分类专栏的JVM详解…...

    2024/5/4 22:49:29
  15. 博文目录索引

    博文目录索引 整理下博客分类,只按时间分有点乱。一. 基础理论:机器学习基础,深度学习基础 二. 流行技术:生成对抗,强化学习,图神经网络 三. 应用领域:推荐系统,计算机视觉,自然语言处理,多媒体和多模态,金融量化 四. 其他:备忘和github一. 基础理论 机器学习基础文…...

    2024/4/29 7:16:48
  16. AOM(Accessibility Object Model 无障碍对象模型)草案解读

    最近在看 AOM(Accessibility Object Model) 相关的草案,草案推出一两年了,发现还没有相关的中文文档或者博客谈到这个,看来国内做的人还是太少了,一般也只有大厂会去跟进这一块。下面我就介绍 AOM 相关的特性,内容主要翻译自草案,也会加上自己的一些理解,同时复现草案…...

    2024/5/4 20:45:39
  17. 英读廊——一个人的旅行:原汁原味希腊克里特游记

    * 用英语自身来理解和学习英语是最好的方式,《英读廊》是《满庭说英语》中的拓展阅读系列,这一系列的文章力求帮助大家在英语阅读能力上有所提升,并树立英语思维; * 推荐的阅读的方法是:先原文,适当看解析阅读,还有疑惑再看双语对照。 * 解析中英语单词的音标使用Dictco…...

    2024/5/4 20:07:17
  18. 10 监听器 watch

    被监听的变量或对象发生改变就执行相应的方法,不建议过多使用,影响性能。 例如: 监听变量:监听数组:反序:...

    2024/4/29 7:16:49
  19. IDM下载---一键安装版

    IDM下载器 1.平时我们在下载一些外网上面的文件或者网盘上的文件的时候,那个速度那叫一个惨不忍睹.下面我将分享一个我个人正在使用的IDM下载器,下载链接我会放在本文下面,希望对大家有帮助。 这里我就不多解释IDM的原理-----有想法的朋友可以去度娘 2. 使用步骤 1.下载好文…...

    2024/4/29 7:16:24
  20. 【学习笔记】:SpringBoot集成Swagger2

    一、认识Swagger Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。是当前最好用的Restful API文档生成的开源项目。官网:https://swagger.io/ 直接运行,在线测试API 支持多种语言 (如:Java,PHP等) Restful Api 文档在线自动生成…...

    2024/4/29 7:16:31

最新文章

  1. 前端页面平滑过渡解决方案

    一、问题产生 在使用图片作为页面背景时&#xff0c;无法使用transtion进行平滑过渡&#xff0c;直接切换背景又会降低使用体验。 二、解决方式 使用clip-path对背景图片裁剪配合transtion实现平滑过渡的效果 三、效果展示 网址&#xff1a;ljynet.com 四、实现方式 tem…...

    2024/5/4 23:49:22
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Go语言map、slice、channel底层实现(go面试)

    slice 切片是一个引用类型&#xff0c;其底层实现是一个结构体&#xff0c;包含以下字段&#xff1a; ptr&#xff1a;一个指向底层数组的指针&#xff0c;指针指向数组的第一个元素。 len&#xff1a;切片当前包含的元素数量。 cap&#xff1a;切片的容量&#xff0c;即底层…...

    2024/4/29 18:34:36
  4. Linux——gdb

    gdb调试 (1)debug版本: 在编译阶段会加入某些调试信息; 调试信息是在编译的过程中加入到中间文件.o文件的; gcc -c main.c -g:生成包含调试信息的中间文件 gcc -o main main.o 一步执行:gcc -o main main.c -g (1) (2)release版本: 发行版本,没有调试信息; gcc默认生成relea…...

    2024/5/2 2:33:15
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/4 12:05:22
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/4 11:23:32
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/4 14:46:16
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/3 16:00:51
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/4 12:10:13
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/3 21:22:01
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/3 23:17:01
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/4 14:46:12
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/4 14:46:11
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/4 14:46:11
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/4 2:14:16
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/4 21:24:42
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/4 12:39:12
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/4 13:16:06
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/4 16:48:41
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/4 14:46:05
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/4 2:00:16
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/3 22:03:11
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/4 9:07:39
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/4 14:46:02
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57