当前位置: 首页 > news >正文

外贸商城网站建设公司/关键词的优化和推广

外贸商城网站建设公司,关键词的优化和推广,东莞网站优化一般多少钱,网站里的网页是一个一个做的么//Author 流云 //Version 1.0 一. 引言 1.1 如何操作数据库 使用客户端工具访问数据库,需要手工建立连接,输入用户名和密码登录,编写 SQL 语句,点击执行,查看操作结果(结果集或受影响行数)。…

//Author 流云

//Version 1.0
   

一. 引言

1.1 如何操作数据库
使用客户端工具访问数据库,需要手工建立连接,输入用户名和密码登录,编写 SQL 语句,点击执行,查看操作结果(结果集或受影响行数)。

   
1.2 实际开发中,不会采用数据库客户端操作
在实际开发中,当用户的数据发生改变时,不可能通过客户端操作执行 SQL 语句,因为操作量过大,无法保证效率和正确性。
    

二. JDBC

2.1 介绍
JDBC(Java Database Connectivity) Java 连接数据库的规范(标准),可以使用 Java 语言连接数据库完成 CRUD 操作。
     
2.2 核心思想
Java 中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver 数据库驱动)。

  
2.3 驱动包
mysql-connector-java-5.1.X 适用于 5.X 版本
mysql-connector-java-8.0.X 适用于 8.X版本
  
2.4 常用类
JDBC 是由多个接口和类进行功能实现。

    
2.5 环境搭建
在项目下新建 lib 文件夹,用于存放 jar 文件。
将 mysql 驱动mysql-connector-java-5.1.X复制到项目的 lib 文件夹中。
选中 lib 文件夹右键 Add as Libraay,点击 OK。
    

三. 开发步骤

3.1 注册驱动
使用 Class.forName("com.mysql.jdbc.Driver");手动加载字节码文件到 JVM 中。
Class.forName("com.mysql.jdbc.Driver");//加载驱动
  
3.2 连接数据库
通过 DriverManager.getConnection(url,user,password) 获取数据库连接对象。
        URL:jdbc:mysql://localhost:3306/database
        username:root
        password:1234
Connection conn = 
DriverManager.getConnection("jdbc:mysql://localhost:3306/database?
useUnicode=true&characterEncoding=utf8", "root","1234");
  
URL(Uniform Resource Locator) 统一资源定位符:由协议、IP、端口、SID(程序实例名称)组成。
   
3.3 获取执行对象
通过 Connection 对象获得 Statement 对象,用于对数据库进行通用访问。
Statement statement = conn.createStatement();
  
3.4 执行SQL 语句
执行 SQL 语句并接收执行结果。
String sql ="INSERT INTO t_jobs(JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES('JAVA_Le','JAVA_Lecturer',4000,10000);";int result = statement.executeUpdate(sql);//执行SQL语句并接收结果
   
注意:在编写 DML 语句时,一定要注意字符串参数的符号是单引号 '值'。
DML 语句:增删改时,返回受影响行数(int 类型)。
DQL 语句:查询时,返回结果数据(ResultSet 结果集)。
    
3.5 处理结果
接受处理操作结果。
if(result == 1){System.out.println("Success");
}
   
受影响行数:逻辑判断、方法返回。
查询结果集:迭代、依次获取。
  
3.6 释放资源
遵循先开后关原则,释放所使用到的资源对象。
statement.close();
conn.close();
   
3.7 综合案例
整合以上核心六步,实现向数据库表中插入一条数据。
package com.jdbc;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;public class DeleteJdbc {public static void main(String[] args) throws Exception{//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.获得连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","1234");//3.获得执行SQL的对象Statement statement = connection.createStatement();//4.执行SQL语句,并接收结果int result = statement.executeUpdate("delete from t_jobs where job_id = 'H5_mgr';");//5.处理结果if(result==1){System.out.println("删除成功!");}else{System.out.println("删除失败!");}//6.释放资源statement.close();connection.close();}
}
  

四. ResultSet

在执行查询 SQL 后,存放查询到的结果集数据。
  
4.1 接收结果集
ResultSet rs = statement.executeQuery(sql);
ResultSet rs= statement.executeQuery("SELECT * FROM t_employees;");
  
4.2 遍历结果集
ResultSet 以表(table)结构进行临时结果的存储,需要通过 JDBC API 将其中数据进行依次获取。
        数据行指针:初始位置在第一行数据前,每调用一次 boolean next()方法ResultSet 的指针向下移动一行,结果为 true,表示当前行有数据。
        rs.getXxx(整数);代表根据列的编号顺序获得,从 1 开始。
        rs.getXxx("列名");代表根据列名获得。
boolean next() throws SQLException //判断 rs 结果集中下一行是否存在数据
  
4.2.1 遍历方法
int getInt(int columnIndex) throws SQLException //获得当前行第N列的int值
int getInt(String columnLabel) throws SQLException //获得当前行columnLabel列的int值double getDouble(int columnIndex) throws SQLException //获得当前行第N列的double值
double getDouble(String columnLabel) throws SQLException //获得当前行columnLabel列的double值String getString(int columnIndex) throws SQLException //获得当前行第N列的String值
String getString(String columnLabel) throws SQLException //获得当前行columnLabel列的String值......
  
注意:列的编号从 1 开始。
  
4.3 综合案例
对 t_jobs 表中的所有数据进行遍历。
    
4.3.1 根据列名
package com.www.test;import java.sql.*;public class JobsQuery {public static void main(String[] args) {//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/product", "root", "1234");//3.获取发送 sql 语句对象Statement statement = connection.createStatement();//4.执行 SQL 语句并接收结果集ResultSet resultSet = statement.executeQuery("select * from t_jobs");//5 处理结果集while(resultSet.next()){//5.1有数据,依据列名获取数据String job_id = resultSet.getString("job_id");String job_title = resultSet.getString("job_title");int min_salary = resultSet.getInt("min_salary");int max_salary = resultSet.getInt("max_salary");System.out.println(job_id+"\t"+job_title+"\t"+min_salary+"\t"+max_salary);}//6.释放资源rs.close();statement.close();connection.close();}
}
    
4.3.2 根据编号
//。。。。与上无异
while(resultSet.next()){//5.2有数据,依据列名获取数据String job_id = resultSet.getString(1);String job_title = resultSet.getString(2);int min_salary = resultSet.getInt(3);int max_salary = resultSet.getInt(4);System.out.println(job_id+"\t"+job_title+"\t"+min_salary+"\t"+max_salary);
}
//释放资源
  

五. 常见错误

java.lang.ClassNotFoundException:找不到类(类名书写错误、没有导入jar包)。
java.sql.SQLException:与sql语句相关的错误 (约束错误、表名列名书写错误) 建议:在客户端工具中测试SQL语句之后再粘贴在代码中。
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 原因:列值Sting类型没有加单引号。
Duplicate entry '1' for key 'PRIMARY' 原因,主键值已存在或混乱,更改主键值或清空表。
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'password' in 原因:可能输入的值的类型不对,确定是否插入的元素时对应的值的类型正确。
    

六. 登录案例

6.1 创建表
创建一张用户表 User
        id ,主键、自动增长。
        用户名,字符串类型,唯一、非空
        密码,字符串类型,非空
        手机号码,字符串类型
插入 2 条测试语句
   
6.2 实现登录
通过控制台用户输入用户名和密码。
用户输入的用户名和密码作为条件,编写查询 SQL 语句。
如果该用户存在,提示登录成功,反之提示失败。
    

七. SQL注入

7.1 介绍
用户输入的数据中有 SQL 关键字或语法并且参与了 SQL 语句的编译,导致 SQL 语句编译后的条件含义为 true,一直得到正确的结果。这种现象称为 SQL 注入。
  
7.2 方案
由于编写的 SQL 语句是在用户输入数据,整合后再进行编译。所以为了避免 SQL 注入的问题,我们要使 SQL 语句在用户输入数据前就已进行编译成完整的 SQL 语句,再进行填充数据。
  

八. PreparedStatement

PreparedStatement 继承了 Statement 接口,执行 SQL 语句的方法无异。
  
8.1 应用
作用:
预编译SQL 语句,效率高。
安全,避免SQL注入 。
可以动态的填充数据,执行多个同构的 SQL 语句。
  
8.1.1 参数标记
//1.预编译 SQL 语句
PreparedStatement pstmt = conn.prepareStatement("select * from user where username=? and password=?");
  
注意:JDBC中的所有参数都由 ?符号占位,这被称为参数标记。在执行SQL语句之前,必须为每个参数提供值。 
    
8.1.2 动态参数绑定
pstmt.setXxx(下标,值) 参数下标从 1 开始,为指定参数下标绑定值。
//1.预编译 SQL 语句
PreparedStatement pstmt = conn.prepareStatement("select * from user where username=? and password=?");//2.为参数下标赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
  

九. 封装工具类

在实际JDBC的使用中,存在着大量的重复代码:例如连接数据库、关闭数据库等这些操作!
我们需要把传统的JDBC代码进行重构,抽取出通用的JDBC工具类!以后连接任何数据库、释放资源都可以使用这个工具类。

  
9.1 重用性方案
封装获取连接、释放资源两个方法。
        提供public static Connection getConnection(){}方法。
        提供public static void closeAll(Connection conn , Statement sm , ResultSet rs){}方法。
  
9.1.1 实现
package com.jdbc;import java.sql.*;/**
* 重用性方案
* 获取连接
* 释放资源
*/public class DBUtils {static {//类加载,执行一次!try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}//1.获取连接public static Connection getConnection() {Connection connection = null;try {connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb", "root","1234");} catch (SQLException e) {e.printStackTrace();}return connection;}//2.释放资源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();}} catch (SQLException e) {e.printStackTrace();}}
}
  
9.2 跨平台方案
定义public static final Properties prop = new Properties(); //读取配置文件的Map。
定义static{
        //首次使用工具类时,加载驱动
InputStream is = JDBCUtil.class.getResourceAsStream("路径"); //通过复用本类自带流,读取jdbc.properties配置文件。classPath = bin
prop.load(is); //通过prop对象将流中的配置信息分割成键值对。
String driverName = prop.getProperty("driver"); //通过driverName的键获取对应的值(com.mysql.jdbc.Driver)
Class.forName(driverName); //加载驱动。
}
    
9.2.1 实现
在src 目录下新建 db.properties 文件。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb3
user=root
password=123456
    
工具类的封装。
package com.jdbc2;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class DBUtils {private static final Properties PROPERTIES = new Properties();//存储配置文件的mapstatic {InputStream is = DBUtils.class.getResourceAsStream("/db.properties");try {PROPERTIES.load(is);//通过流,将配置文件内容加载到properties集合Class.forName(PROPERTIES.getProperty("driver"));} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConnection() {Connection connection = null;try {connection = DriverManager.getConnection(PROPERTIES.getProperty("url"),PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));} 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();}} catch (SQLException e) {e.printStackTrace();}}
}
   

十. ORM

ORM(Object Relational Mapping)。
从数据库查询到的结果集(ResultSet)在进行遍历时,逐行遍历,取出的都是零散的数据。在实际应用开发中,我们需要将零散的数据进行封装整理。
   
10.1 实体类
一行数据中,多个零散的数据进行整理。
通过entity的规则对表中的数据进行对象的封装。
表名=类名;列名=属性名;提供各个属性的get、set方法。
提供无参构造方法、(视情况添加有参构造)。
      
10.1.1 ORM应用
entity实体类
package com.www.test;public class T_Jobs {private String job_id;private String job_title;private int min_salary;private int max_salary;@Overridepublic String toString() {return "T_Jobs{" +"job_id='" + job_id + '\'' +", job_title='" + job_title + '\'' +", min_salary=" + min_salary +", max_salary=" + max_salary +'}';}public String getJob_id() {return job_id;}public void setJob_id(String job_id) {this.job_id = job_id;}public String getJob_title() {return job_title;}public void setJob_title(String job_title) {this.job_title = job_title;}public int getMin_salary() {return min_salary;}public void setMin_salary(int min_salary) {this.min_salary = min_salary;}public int getMax_salary() {return max_salary;}public void setMax_salary(int max_salary) {this.max_salary = max_salary;}public T_Jobs() {}public T_Jobs(String job_id, String job_title, int min_salary, int max_salary) {this.job_id = job_id;this.job_title = job_title;this.min_salary = min_salary;this.max_salary = max_salary;}
}
   
查询结果封装
package com.www.test;import java.sql.*;public class JobsQuery {public static void main(String[] args) {Connection connection = null;Statement statement = null;ResultSet resultSet = null;String URL = "jdbc:mysql://localhost:3306/product";String user = "root";String password = "1234";try {//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接对象connection = DriverManager.getConnection(URL, user, password);//3.编写 SQL 语句String sql = "select * from t_jobs";//4.获取发送 sql 语句对象statement = connection.createStatement();//5.执行 SQL 语句并接收结果集resultSet = statement.executeQuery(sql);//5.1使用 while 循环判断下一行是否有数据while(resultSet.next()){//5.2有数据,依据列名获取数据String job_id = resultSet.getString(1);String job_title = resultSet.getString(2);int min_salary = resultSet.getInt(3);int max_salary = resultSet.getInt(4);//5.3 创建实体类对象T_Jobs t_jobs = new T_Jobs();//5.4 每列数据对应属性进行赋值t_jobs.setJob_id(job_id);t_jobs.setJob_title(job_title);t_jobs.setMin_salary(min_salary);t_jobs.setMax_salary(max_salary);System.out.println(t_jobs);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {try {//6.释放资源if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException e) {e.printStackTrace();}}}
}
   

十一. 数据访问对象

DAO 实现了业务逻辑与数据库访问相分离。
        对同一张表的所有操作封装在XxxDaoImpl对象中。
        根据增删改查的不同功能实现具体的方法(insert、update、delete、select、 selectAll)。

  
11.1 创建数据库
创建一张表 Person,有以下列:
        id:int,主键,自动增长
        name:varchar(20) 非空
        age:int 非空
        bornDate:Date
        email:字符串
        address:字符串
   
11.2 封装实体类
创建entity实体类 Person,编写属性私有化,构造方法,get/set 方法。
  
11.3 编写 DaoImpl 类
编写 DaoImpl 类,提供增删改查方法,使用 JDBC 开发步骤,完成功能。
package com.person;import sun.awt.image.DataBufferNative;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/**
* 增、删、改、查单个、查所有
* 只做数据库访问操作!不参与逻辑判断
* 数据库一张表的访问的操作复用!
*/public class PersonDaoImpl {//新增public int insert(Person person){Connection connection = null;PreparedStatement preparedStatement = null;String sql = "insert into person(name,age,borndate,email,address) values(?,?,?,?,?);";try {connection = DBUtils.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,person.getName());preparedStatement.setInt(2,person.getAge());preparedStatement.setDate(3,null);preparedStatement.setString(4,person.getEmail());preparedStatement.setString(5,person.getAddress());int result = preparedStatement.executeUpdate();return result;} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.closeAll(connection,preparedStatement,null);}return 0;}//修改public int update(Person person){Connection connection =null;PreparedStatement preparedStatement = null;String sql = "update person setname=?,age=?,borndate=?,email=?,address=? where id = ?";try {connection = DBUtils.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,person.getName());preparedStatement.setInt(2,person.getAge());preparedStatement.setDate(3,null);preparedStatement.setString(4,person.getEmail());preparedStatement.setString(5,person.getAddress());preparedStatement.setInt(6,person.getId());int result = preparedStatement.executeUpdate();return result;} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.closeAll(connection,preparedStatement,null);}return 0;}//删除public int delete(int id){Connection connection = null;PreparedStatement preparedStatement = null;String sql = "delete from person where id= ?;";connection = DBUtils.getConnection();try {preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,id);int result = preparedStatement.executeUpdate();return result;} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.closeAll(connection,preparedStatement,null);}return 0;}//查单个public Person select(int id){Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;String sql = "select * from person where id = ?;";Person person = null;try {connection = DBUtils.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,id);resultSet = preparedStatement.executeQuery();if(resultSet.next()){person = new Person();int pid= resultSet.getInt("id");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");person.setId(pid);person.setName(name);person.setAge(age);person.setBornDate(bornDate);person.setEmail(email);person.setAddress(address);}return person;} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.closeAll(connection,preparedStatement,resultSet);}return null;}//查所有public List<Person> selectAll(){Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;Person person = null;List<Person> personList = new ArrayList<>();try {connection = DBUtils.getConnection();preparedStatement = connection.prepareStatement("select * from person;");resultSet = preparedStatement.executeQuery();while(resultSet.next()){int pid= resultSet.getInt("id");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");person = new Person(pid,name,age,bornDate,email,address);personList.add(person);}return personList;} catch (Exception e) {e.printStackTrace();}return null;}
}
  

十二. 三层架构

12.1 什么是三层
 表示层:
命名:XXXView
职责:收集用户的数据和需求、展示数据。
   
业务逻辑层:
命名:XXXServiceImpl
职责:数据加工处理、调用DAO完成业务实现、控制事务。
   
数据访问层:
命名:XXXDaoImpl
职责:向业务层提供数据,将业务层加工后的数据同步到数据库。

   
12.2 三层搭建
utils 存放工具类(DBUtils)
entity 存放实体类(Person)
dao 存放 DAO 接口(PersonDao)
        impl 存放 DAO 接口实现类(PersonDaoImpl)
service 存放 service 接口(PersonService)
        impl 存放 service 接口实现类(PersonServiceImpl)
view 存放程序启动类(main)
程序设计时,考虑易修改、易扩展,为Service层和DAO层设计接口,便于未来更换实现类。
     

十三. 通用工具类

在DAO层中,对数据库表的增、删、改、查操作存在代码冗余,可对其进行抽取封装DaoUtils工具类实现复用。
  
13.1通用DML
/**
* 将所有数据表的操作,抽离成一个公用的方法;
* @Param sql 语句
* @Param sql语句对应的参数
* @return
*/
public static boolean executeDML(String sql,Object... params){try {//获取连接Connection connection = getConnection();//获取预处理的对象PreparedStatement ps = connection.prepareStatement(sql);//设置参数if(null != params){for(int i = 0 ; i < params.length ; i++){//1:给占位符设置参数;2:获取参数ps.setObject(i+1,params[i]);}}int i = ps.executeUpdate();close(null,ps,connection);return i > 0;} catch (SQLException sqlException) {sqlException.printStackTrace();}return false;
}
  
13.2 通用DQL
/**
* 通用的查询;需要将我们的数据表信息,封装到List里面进行返回
* @param sql 查询语句
* @param cls 实体类的字节码对象
* @param params 查询语句里面的占位符
* @param <T> 实体类类型泛型
* @return 就是我们查询到的数据集合
*/public static <T> List<T> executeDQL(String sql, Class<T> cls , Object...params) {try {Connection connection = getConnection(); //获取连接//获取预处理sqlPreparedStatement preparedStatement = connection.prepareStatement(sql);//设置参数if(null != params){for(int i = 0 ; i < params.length ; i++){preparedStatement.setObject(i+1,params[i]);}}//执行查询 得到结果集ResultSet resultSet = preparedStatement.executeQuery();//获取元数据(我们的列名)ResultSetMetaData metaData = resultSet.getMetaData();//列的总数int columnCount = metaData.getColumnCount();//用来保存我们所有的表数据List<T> list = new ArrayList<T>();T t;//用来保存我们一条数据//遍历结果集while(resultSet.next()){ //每一行记录的遍历过程中t = cls.newInstance();//根据字节码文件,构建一个实体类的对象//获取所有列的数据for(int i = 1 ; i <= columnCount ; i++){//你的查询语句有时候有别名String columnLabel = metaData.getColumnLabel(i);//根据列名获取我们的记录Object object = resultSet.getObject(columnLabel);//需要将拿到的这一列的记录,放到t对象指定的属性里面;//需要拿到这个t对象的属性,然后赋值;//解决方案2: 如果Object是NULL没有必要设置了if(null != object){try {Field field = cls.getDeclaredField(columnLabel);//根据属性的名称通过反射获取他的属性对象field.setAccessible(true);field.set(t,object);} catch (NoSuchFieldException e) {//代表我们当前这个实体类里面,没有这个属性}}}//需要将t对象保存到listlist.add(t);}close(resultSet,preparedStatement,connection);return list;} catch (SQLException sqlException) {sqlException.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}return null;
}
   
13.3 Apache的DbUtils
13.3.1 简介
DbUtils是Java编程中数据库操作实用小工具,小巧、简单、实用。
        对于数据表的查询操作,可以把结果转换为List、Array、Set等集合。便于操作。
        对于数据表的DML操作,也变得很简单(只需要写SQL语句)。
  
13.3.2 API
ResultSetHandler接口:转换类型接口
        BeanHandler类:实现类,把一条记录转换成对象
        BeanListHandler类:实现类,把多条记录转换成List集合。
        ScalarHandler类:实现类,适合获取一行一列的数据。
QueryRunner:执行sql语句的类
        增、删、改:update();
        查询:query();
  
13.3.3 使用步骤
导入jar包
        mysql连接驱动jar包
        druid-1.1.5.jar
        database.properties配置文件
        commons-dbutils-1.6.jar
     
13.3.4 代码
package com.project.utils;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;/**
* 连接池工具类
*/public class DBUtils {private static DruidDataSource dataSource;static {Properties properties = new Properties();InputStream is = DBUtils.class.getResourceAsStream("/database.properties");try {properties.load(is);dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}// 返回一个数据源public static DataSource getDataSource(){return dataSource;}
}
package com.project.dao.impl;import com.project.dao.UserDao;
import com.project.entity.User;
import com.project.utils.DBUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;public class UserDaoImpl implements UserDao {//1.创建QueryRunner对象,并传递一个数据源对象private QueryRunner queryRunner = new QueryRunner(DBUtils.getDataSource());@Overridepublic int insert(User user) {Object[] params={user.getId(),user.getUsername(),user.getPassword(),user.getSex(),user.getEmail(),user.getAddress()};try {return queryRunner.update("insert into user(id,username,password,sex,email,address) values(?,?,?,?,?,?)",params);} catch (SQLException e) {e.printStackTrace();}return 0;}@Overridepublic int update(User user) {Object[] params={user.getUsername(),user.getPassword(),user.getSex(),user.getEmail(),user.getAdd ress(),user.getId()};try {return queryRunner.update("update user setusername=?,password=?,sex=?,email=?,address=? where id = ?",params);} catch (SQLException e) {e.printStackTrace();}return 0;}@Overridepublic int delete(int id) {try {return queryRunner.update("delete from user where id = ?",id);} catch (SQLException e) {e.printStackTrace();}return 0;}@Overridepublic User select(int id) {try {//把查询到的记录封装成 指定对象return queryRunner.query("select * from user where id = ?", newBeanHandler<User>(User.class), id);} catch (SQLException e) {e.printStackTrace();}return null;}/*** 查询所有* @return*/@Overridepublic List<User> selectAll() {try {return queryRunner.query("select * from user;",newBeanListHandler<User>(User.class));} catch (SQLException e) {e.printStackTrace();}return null;}
}
  

十四. 连接池

在程序初始化时,预先创建指定数量的数据库连接对象存储在池中。当需要连接数据库时,从连接池中取出现有连接;使用完毕后,也不会进行关闭,而是放回池中,实现复用,节省资源。
资源重用。
更快的系统响应速度。
新的资源分配手段。
统一的连接管理,避免数据库连接泄漏。
  
14.1 Druid
14.1.1 步骤
创建 druid.properties 配置文件。
引入druid-xxx.jar 文件。
  
14.1.2 druid.properties
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytest
username=root
password=123456
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
maxWait=5000
    
14.1.3 连接池工具类
public class DbUtils {//声明连接池对象private static DruidDataSource ds;static{//实例化配置对象Properties properties=new Properties();try {//加载配置文件内容properties.load(DbUtils.class.getResourceAsStream("druid.properties"));ds = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);} catch (IOException e) {e.printStackTrace();}}//获取连接对象public static Connection getConnection() {try {return ds.getConnection();} catch (SQLException e) {e.printStackTrace();}return null;}//释放资源。。
}
   
14.2 HikariCP
引入HikariCP-xxx.jar 文件。
/*
一、主要配置
1、dataSourceClassName
这是DataSourceJDBC驱动程序提供的类的名称。请注意,如果您正在使用jdbcUrl“旧式”基于DriverManager的JDBC驱动程序配置,则不需要此属性 。 默认值:无
2、jdbcUrl
请注意,如果使用此属性,您仍然可以使用DataSource属性来配置您的驱动程序,实际上建议您使用URL本身中指定的驱动程序参数。 默认值:无
3、username
此属性设置从基础驱动程序获取连接时使用的默认身份验证用户名。
4、password
此属性设置从基础驱动程序获取连接时使用的默认身份验证密码。
*/
public static void main(String[] args) throws SQLException {HikariConfig hikariConfig = new HikariConfig();//设置urlhikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/mytest?characterEncoding=UTF-8");//数据库帐号hikariConfig.setUsername("root");//数据库密码hikariConfig.setPassword("123456");HikariDataSource ds = new HikariDataSource(hikariConfig);
}
    

十五 . 批处理

addBatch(); 添加到批处理
executeBatch(); 执行批处理
clearBatch(); 清空批处理
//如果保存1w条记录
String sql = "insert into userinfo(uname,upass) values(?,?)";
Connection connection = DBUtilPool.getConnectionByDruid();
long start = System.currentTimeMillis();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for(int i = 0 ; i < 10000 ; i++){preparedStatement.setObject(1,"jack"+i);preparedStatement.setObject(2,"aaaa"+i);preparedStatement.addBatch(); //将当前的sql预编译好以后,加到批处理; 不会直接执行到数据库里面if(i % 500 == 0){preparedStatement.executeBatch(); //执行我们批处理preparedStatement.clearBatch(); //把上面的执行了,需要清空}
}
preparedStatement.executeBatch(); //最后一次进行批处理
long end = System.currentTimeMillis();
System.out.println("");
System.out.println(end-start);
  

十六. 事务

16.1 业务
代表用户完成的一个业务功能,可以由一个或多个DAO的调用组成。(软件所提供的一个功能都叫业务)。
  
16.2 service层

   
16.3 转账案例
BEGIN ;-- 代表我们开启了一个事务
UPDATE user_acount SET umoney = umoney-200 WHERE uname = 'jack';-- 断网了 断电了
UPDATE user_acount SET umoney = umoney+200 WHERE uname = 'rose';ROLLBACK -- 回滚事务(代表整个事务执行失败)
COMMIT; -- 提交事务
   
16.4 事务
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
   
16.5 转账事务案例
-- 默认提交事务
begin;
commit; -- 提交事务
rollback; -- 事务回滚//代码里面默认回滚事务
connection.setAutoCommit(false); //不自动提交事务
connection.commit();//提交事务
connection.rollback();//回滚事务

相关文章:

JavaWeb笔记之JavaWeb JDBC

//Author 流云 //Version 1.0 一. 引言 1.1 如何操作数据库 使用客户端工具访问数据库&#xff0c;需要手工建立连接&#xff0c;输入用户名和密码登录&#xff0c;编写 SQL 语句&#xff0c;点击执行&#xff0c;查看操作结果&#xff08;结果集或受影响行数&#xff09;。…...

pytorch网络的增删改

本文介绍对加载的网络的层进行增删改, 以alexnet网络为例进行介绍。 1. 加载网络 import torchvision.models as models alexnet models.alexnet(weightsmodels.AlexNet_Weights.DEFAULT) print(alexnet)2. 删除网络 在做迁移学习的时候&#xff0c;我们通常是在分类网络的…...

Tomcat (Linux系统)详解全集

点击标题进入对应模块学习&#xff0c;你也可以完全拿捏Tomcat&#xff01; 1 Tomcat及JDK下载安装&#xff08;Linux系统&#xff09; 2 Tomcat目录介绍 3 Tomcat的启动关闭及日志说明 4 完美解决Tomcat启动慢的三种方法 5 Tomcat管理功能使用 6 Tomcat主配置文件&#xff08;…...

[德人合科技]——设计公司 \ 设计院图纸文件数据 | 资料透明加密防泄密软件

国内众多设计院都在推进信息化建设&#xff0c;特别是在异地办公、应用软件资产规模、三维设计技术推广应用以及协同办公等领域&#xff0c;这些加快了业务的发展&#xff0c;也带来了更多信息安全挑战&#xff0c;尤其是对于以知识成果为重要效益来源的设计院所&#xff0c;防…...

数字化转型中的6S管理

在当今竞争激烈的制造业中&#xff0c;数字化转型已经成为企业保持竞争力和实现可持续发展的关键。科技的飞速发展&#xff0c;数字化已经成为推动制造业变革的引擎。在这个信息时代&#xff0c;数字化转型不仅仅是追求效率和成本节约的问题&#xff0c;更是企业在市场中生存和…...

Linux学习(1)——初识Linux

目录 一、Linux的哲学思想 1.1 基础知识 1.2 根目录下的文件夹 二、Shell 1、Shell的定义 2、Shell的作用 三、Linux命令行 1、Linux通用命令行使用格式 四、Linux命令的分类 1、内部命令和外部命令的理解 2、内部命令和外部命令的区别 3、命令的执行过程 五、编辑…...

2.5 - 网络协议 - HTTP协议工作原理,报文格式,抓包实战

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 HTTP协议 1、HTTP协议工作原理2、HTTP协议报文3、HTTP请求方法4、HTTP响应状态码5、…...

新增工具箱管理功能、重构网站证书管理功能,1Panel开源面板v1.9.0发布

2023年12月18日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.9.0版本。 在这一版本中&#xff0c;1Panel引入了新的工具箱管理功能&#xff0c;包含Swap分区管理、Fail2Ban管理等功能。此外&#xff0c;1Panel针对网站证书管理功能进行了全面重构&…...

棋牌的电脑计时计费管理系统教程,棋牌灯控管理软件操作教程

一、前言 有的棋牌室在计时的时候&#xff0c;需要使用灯控管理&#xff0c;在开始计时的时候打开灯&#xff0c;在结账后关闭灯&#xff0c;也有的不需要用灯控&#xff0c;只用来计时。 下面以 佳易王棋牌计时计费管理系统软件为例说明&#xff1a; 软件试用版下载或技术支…...

《Kotlin核心编程》笔记:设计模式

创建型模式 主流的创建型模式有&#xff1a;工厂方法模式、抽象工厂模式、构建者模式 伴生对象增强工厂模式 在有些地方会把工厂模式细分为简单工厂、工厂方法模式以及抽象工厂。 这里主要介绍简单工厂的模式&#xff0c;它的核心作用就是通过一个工厂类隐藏对象实例的创建…...

hive企业级调优策略之数据倾斜

测试所用到的数据参考&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135080511 本教程的计算环境为Hive on MR。计算资源的调整主要包括Yarn和MR。 数据倾斜概述 数据倾斜问题&#xff0c;通常是指参与计算的数据分布不均&#xff0…...

MATLAB版本、labview版本、UHD版本 互相对应

LabVIEWMATLABUHD2019R2021bUHD_3.15.0.0-vendor2020R2022bUHD_4.1.0.4-vendorR2023bUHD_4.2.0.0-vendor 更换固件 MATLAB 更换固件指令 status sdruload(Device "X310", IPAddress 192.168.10.2)...

13 v-show指令

概述 v-show用于实现组件的显示和隐藏&#xff0c;和v-if单独使用的时候有点类似。不同的是&#xff0c;v-if会直接移除dom元素&#xff0c;而v-show只是让dom元素隐藏&#xff0c;而不会移除。 在实际开发中&#xff0c;v-show也经常被用到&#xff0c;需要重点掌握。 基本…...

23级新生C语言周赛(6)(郑州轻工业大学)

题目链接:ZZULIOJ 3110: 数(shu)数(shu)问题 分析: 看到这个题第一步想的是 先把每个平方数给求出来 然后枚举 但是时间复杂度大于1e8 交了一下TLE 但后来打表发现,好数太多了要是枚举的话 注定TLE 能不能间接的去做呢? 把不是的减去,那不就是好数了吗? 这个时候又是打表,会…...

关于“Python”的核心知识点整理大全24

目录 ​编辑 10.1.6 包含一百万位的大型文件 pi_string.py 10.1.7 圆周率值中包含你的生日吗 10.2 写入文件 10.2.1 写入空文件 write_message.py programming.txt 10.2.2 写入多行 10.2.3 附加到文件 write_message.py programming.txt 10.3 异常 10.3.1 处理 Ze…...

Vue - 基于Element UI封装一个表格动态列组件

1 组件需求背景 在后台管理系统中&#xff0c;表格的使用频率非常高&#xff0c;统一封装表格动态列组件并全局注册使用&#xff0c;可大大提升代码的复用性和可维护性。 2 全局注册 src/plugins/index.js&#xff1a; import columns from ./columns/indexexport default …...

计算机网络:DNS域名解析系统

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…...

java面试:==和equals有什么区别?

在 Java 中&#xff0c;"" 和 "equals" 有着不同的作用&#xff1a; "" 运算符&#xff1a; 在基本数据类型&#xff08;如 int、char 等&#xff09;中&#xff0c;"" 用于比较它们的值是否相等。 在引用类型中&#xff0c;"&q…...

数字人SaaS系统无限生成AI数字人!

市面上数字人软件层出不穷&#xff0c;选择一款适合的数字人软件是成功的第一步&#xff0c;只需要一款软件就解决数字人直播和数字人短视频的制作&#xff0c;青否数字人SaaS系统&#xff08;数字人源码&#xff1a;zhibo175&#xff09;你值得拥有&#xff01; 青否数字人Saa…...

【MySQL】——数据类型及字符集

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…...

Redis cluster集群设置密码

Redis cluster集群设置密码 1 备份数据 # 链接redis集群,执行rdb快照 bgsave # 备份dump.rdb文件 cp /data/redis/cluster/dump.rdb /data/redis/cluster/backup/dump.rdb.202312202 设置密码 必须保证每个节点的密码保持一致&#xff0c;不然 Redirected 的时候会失败 2.1…...

Docker 核心技术

Docker 定义&#xff1a;于 Linux 内核的 Cgroup&#xff0c;Namespace&#xff0c;以及 Union FS 等技术&#xff0c;对进程进行封装隔离&#xff0c;属于操作系统层面的虚拟化技术&#xff0c;由于隔离的进程独立于宿主和其它的隔离的进程&#xff0c;因此也称其为容器Docke…...

15 使用v-model绑定单选框

概述 使用v-model绑定单选框也比较常见&#xff0c;比如性别&#xff0c;要么是男&#xff0c;要么是女。比如单选题&#xff0c;给出多个选择&#xff0c;但是只能选择其中的一个。 在本节课中&#xff0c;我们演示一下这两种常见的用法。 基本用法 我们创建src/component…...

go语言指针变量定义及说明

go语言指针主要需要记住两个特殊符号&#xff0c; 一个是 & 用来获取变量对应的内存地址 另一个是 * 用来获取指针对应的变量值 下面是个最简单的go语言指针说明 package mainimport "fmt"//指针为内存地址func main() {var a string "指针对应的变量&…...

基于“Galera+MariaDB”搭建多主数据库集群的实例

1、什么是多主数据库集群 多主数据库集群是一种数据库集群架构&#xff0c;每个节点都可以接收写入操作和读取操作&#xff0c;并且通过心跳机制同步数据&#xff0c;保证数据一致性和高可用性。因多主数据库集群每个节点都可以承担读写操作&#xff0c;因此它可以充分利用各个…...

arcgis javascript api4.x加载天地图cgs2000坐标系

需求&#xff1a;arcgis javascript api4.x加载天地图cgs2000坐标系 效果&#xff1a; 示例代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…...

算法学习——回溯算法

回溯算法 理论基础回溯法的效率回溯法解决的问题回溯法模板 组合思路回溯法三部曲 代码 组合&#xff08;优化&#xff09;组合总和III思路代码 电话号码的字母组合思路回溯法来解决n个for循环的问题回溯三部曲代码 组合总和思路代码 组合总和II思路代码 理论基础 什么是回溯法…...

C语言—小小圣诞树

这个代码会询问用户输入圣诞树的高度&#xff0c;然后根据输入的高度在控制台上显示相应高度的圣诞树。 #include <stdio.h>int main() {int height, spaces, stars;printf("请输入圣诞树的高度: ");scanf("%d", &height);spaces height - 1;st…...

Android消息公告上下滚动切换轮播实现

自定义控件 通过继承TextSwitcher实现 直接上代码 public class NoticesSwitcher extends TextSwitcher implements ViewSwitcher.ViewFactory {private Context mContext;private List<Notice> mData;private final long DEFAULT_TIME_SWITCH_INTERVAL 1000;//1spri…...

tensorflow入门 自定义模型

前面说了自定义的层&#xff0c;接下来自定义模型&#xff0c;我们以下图为例子 这个模型没啥意义&#xff0c;单纯是为了写代码实现这个模型 首先呢&#xff0c;我们看有几个部分&#xff0c;dense不需要我们实现了&#xff0c;我们就实现Res&#xff0c;为了实现那个*3,我们…...