Day 14 JDBC

JDBC

  • 1、简单入门 Statement
  • 2、preparedStatement
  • 3、主键回显
  • 4、批量操作
  • 5、事务
  • 6、Druid
    • 6.1 工具类V1
    • 6.2 工具类V2
    • 6.3

在这里插入图片描述

1、简单入门 Statement

步骤:
1、注册驱动
2、创建连接
3、创建 Statement对象
4、编写sql语句 并且发送sql语句获得结果集
5、解析结果集
6、释放资源
注意事项 都在写下面代码里了

import com.mysql.cj.jdbc.Driver;import java.sql.*;
import java.util.Properties;public class day1 {public static void main(String[] args) throws Exception {new test();new test();//注册驱动  不推荐 会注册两次 new Driver中有静态代码块//DriverManager.registerDriver(new Driver());//new Driver();//不推荐 不能显示出 是什么驱动 如果是8+ 则是com.mysql.cj.jdbc 如果是5+ 则是com.mysql.jdbcClass.forName("com.mysql.cj.jdbc.Driver");  //推荐 通过反射获得类加载//建立连接 3种方式 ①
//        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");// ②Properties properties=new Properties();properties.put("user","ckytest");properties.put("password","123456");
//        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test",properties);//③Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?user=ckytest&password=123456");//创建 mqlStatement statement = ckytest.createStatement();//mql 并发送 获取结果集String mysql="select * from u_ser";//  statement.executeUpdate();  非DMLResultSet resultSet = statement.executeQuery(mysql);while(resultSet.next()){int anInt = resultSet.getInt(1);
//            int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println(anInt+"---"+name);}}
}

2、preparedStatement

步骤:
1、注册驱动
2、创建连接
3、编写sql语句
4、创建preparedStatement 对象并且传入sql语句
5、占位符赋值
从左到右 索引从1开始
6、发送sql语句获得结果集
7、解析结果集
8、释放资源

import com.mysql.cj.jdbc.Driver;
import org.junit.Test;import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class test {@Testpublic void testinsert() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");String mysql="insert into u_ser(id,name) values(?,?);";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);preparedStatement.setObject(1,3);preparedStatement.setObject(2,"yue");int i = preparedStatement.executeUpdate();if (i>0)System.out.println("成功");preparedStatement.close();ckytest.close();}@Testpublic void testupdate() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");String mysql="update u_ser set name=? where id=?;";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);preparedStatement.setObject(1,"cui");preparedStatement.setObject(2,3);int i = preparedStatement.executeUpdate();if (i>0)System.out.println("成功");preparedStatement.close();ckytest.close();}@Testpublic void testdelete() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");String mysql="delete from u_ser where  id=?;";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);//preparedStatement.setObject(1,"cui");preparedStatement.setObject(1,3);int i = preparedStatement.executeUpdate();if (i>0)System.out.println("成功");preparedStatement.close();ckytest.close();}//查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value@Testpublic void testquery() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");String mysql="select * from u_ser;";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);ResultSet resultSet = preparedStatement.executeQuery();//得到表信息ResultSetMetaData metaData = resultSet.getMetaData();//得到列数量int columnCount = metaData.getColumnCount();List<Map> list=new ArrayList<>();while(resultSet.next()) {Map map = new HashMap();for (int i = 1; i <= columnCount; i++) {//获得结果Object object = resultSet.getObject(i);//获得列名String columnLabel = metaData.getColumnLabel(i);map.put(columnLabel, object);}list.add(map);}System.out.println(list);resultSet.close();preparedStatement.close();ckytest.close();}
}

String columnLabel = metaData.getColumnLabel(i);
getColumnLabel 有别名可以获得别名而getColumnName 不能获取别名。
getColumnCount 获取列的数量
getMetaData 获取列的信息

3、主键回显

  /*** * 得到自增长的主键* 在创建prepareStatement,告知它拿回自增长的主键* getGeneratedKeys 得到一个自增长主键的结果 首先通过next 移动光标* 之后通过getxx 获取结果,插入一行 肯定只获取一个结果 所以是一行一列 索引为1 即使回显的主键*/@Testpublic void testinsertkey() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");String mysql="insert into u_ser(name) values(?);";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS);preparedStatement.setObject(1,"yue1");int i = preparedStatement.executeUpdate();if (i>0)System.out.println("成功");ResultSet generatedKeys = preparedStatement.getGeneratedKeys();generatedKeys.next();Object id = generatedKeys.getObject(1);System.out.println("回显主键:"+id);preparedStatement.close();ckytest.close();}

4、批量操作

在url中添上rewriteBatchedStatements=true,允许批量操作。
sql语句不要加分号
preparedStatement.addBatch();
preparedStatement.executeBatch();

    @Testpublic void testinsert1() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456");String mysql="insert into u_ser(name) values(?)";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS);long start = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {preparedStatement.setObject(1,"yue1"+i);preparedStatement.executeUpdate();}long end = System.currentTimeMillis();System.out.println("时间为:"+(end-start)/1000+"s"); //14spreparedStatement.close();ckytest.close();}@Testpublic void testabatchinsert() throws  Exception{Class.forName("com.mysql.cj.jdbc.Driver");Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456");String mysql="insert into u_ser(name) values(?)";PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);long start = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {preparedStatement.setObject(1,"yue"+i);preparedStatement.addBatch();}preparedStatement.executeBatch();long end = System.currentTimeMillis();System.out.println("时间为:"+(end-start)+"s");//0.77spreparedStatement.close();ckytest.close();}

5、事务

原子性 一致性 隔离性 持久性
事务的发生 必须是在同一个连接中。
对于事务,我们应该在业务层进行开启和关闭。mysql是自动提交业务,我们可以手动开启或者关闭。
比如转账业务,我们可以在业务层获取一个连接,之后将该连接传入加钱和转钱方法,这样可以确保是一个连接。
事务,我们一般使用try,catch,如果成功就提交,捕捉到错误就回滚。

6、Druid

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;public class DruidTest {public void druid1() throws  Exception{//创建连接池对象DruidDataSource druidDataSource=new DruidDataSource();//一些必要和不必要的选项 url,name,pwd,driver都是必须的 连接池数量这些不是必须的druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");druidDataSource.setPassword("123456");druidDataSource.setUsername("ckytest");druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");druidDataSource.setInitialSize(5);druidDataSource.setMaxActive(10);//获得一个连接。DruidPooledConnection connection = druidDataSource.getConnection();//回收connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。}public void druid2() throws  Exception{//读取配置文件Properties properties=new Properties();//只要在src下 就可以使用类加载器InputStream resourceAsStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");properties.load(resourceAsStream);//加载到properties中DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//获得一个连接。Connection connection = dataSource.getConnection();//回收connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。}
}
Url=jdbc:mysql://127.0.0.1:3306/test
Password=123456
Username=ckytest
DriverClassName=com.mysql.cj.jdbc.Driver

6.1 工具类V1

每次都去初始化连接池太麻烦了,我们封装一个工具类,对外提供一个获取连接和回收连接的方法。

import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/*
*   工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法
*  创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次*/
public class DruidUtils {//连接池private static DataSource dataSource=null;static {Properties properties=new Properties();InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");try {properties.load(resourceAsStream);} catch (IOException e) {e.printStackTrace();}try {dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}public Connection getConnection() throws SQLException {return dataSource.getConnection();}public void closeConnection(Connection connection){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}
}

6.2 工具类V2

我们的工具类V1,只是单例模式了连接池,但是每次获取连接都是新的连接。
如果我们在Serve层获得一个连接,这个连接还需要传给Dao层来获取,能不能让同一个线程,Serve层和Dao层获取的都是同一个连接,而不用使用参数传递呢?可以使用线程局部变量。只要一个线程里边的属性就是通用的。

import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/*
*   工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法
*  创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次*/
public class DruidUtils {//连接池private static DataSource dataSource=null;private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();static {Properties properties=new Properties();InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");try {properties.load(resourceAsStream);} catch (IOException e) {e.printStackTrace();}try {dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}public Connection getConnection() throws SQLException {Connection connection=threadLocal.get();if (connection==null){connection = dataSource.getConnection();threadLocal.set(connection);}return connection;}public void closeConnection() throws Exception{Connection connection = threadLocal.get();if (connection!=null){threadLocal.remove();connection.setAutoCommit(true);connection.close();}}
}

6.3

对于Dao层的封装,写一个基础BaseDao,对语句进行封装,可以分为DQL和非DQl两种。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class A {public static int  executUpdate(String sql,Object ... args) throws Exception{Connection connection = DruidUtils.getConnection();PreparedStatement preparedStatement = connection.prepareStatement(sql);for (int i = 0; i <args.length ; i++) {preparedStatement.setObject(i+1,args[i]);}int i = preparedStatement.executeUpdate();if (connection.getAutoCommit()){//没有开启事务DruidUtils.closeConnection();}return i;}public static  <T>  List<T> executQuery(Class<T> tClass,String sql, Object ... args) throws Exception{Connection connection = DruidUtils.getConnection();PreparedStatement preparedStatement = connection.prepareStatement(sql);if(args!=null&&args.length>0){for (int i = 0; i <args.length ; i++) {preparedStatement.setObject(i+1,args[i]);}}ResultSet resultSet = preparedStatement.executeQuery();//得到表信息ResultSetMetaData metaData = resultSet.getMetaData();//得到列数量int columnCount = metaData.getColumnCount();List<T> list=new ArrayList<>();while(resultSet.next()) {Constructor<T> constructor = tClass.getConstructor();T t = constructor.newInstance();for (int i = 1; i <= columnCount; i++) {//获得结果Object object = resultSet.getObject(i);//获得列名String columnLabel = metaData.getColumnLabel(i);Field declaredField = tClass.getDeclaredField(columnLabel);declaredField.set(t,object);}list.add(t);}if (connection.getAutoCommit()){//没有开启事务DruidUtils.closeConnection();}return list;}
}

数据库每个表都对应java中的一个实体类,查询时我们返回的是一个装有实体类的集合。

封装过工具类之后的增删改查 简化了很多。

import com.mysql.cj.jdbc.Driver;
import org.junit.Test;import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class test {@Testpublic void testinsert() throws  Exception{String mysql="insert into u_ser(id,name) values(?,?);";int a = A.executUpdate(mysql, 50001, "a");System.out.println(a);}@Testpublic void testupdate() throws  Exception{String mysql="update u_ser set name=? where id=?;";int a = A.executUpdate(mysql, "cui", 1);System.out.println(a);}@Testpublic void testdelete() throws  Exception{String mysql="delete from u_ser where  id=?;";int a = A.executUpdate(mysql, 1);System.out.println(a);}//查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value@Testpublic void testquery() throws  Exception{String mysql="select * from u_ser;";List<User> users = A.executQuery(User.class, mysql);System.out.println(users);}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jmeter使用方法---自动化测试

HTTP信息头管理器 一个http请求会发送请求到服务器&#xff0c;请求里面包含&#xff1a;请求头、请求正文、请求体&#xff0c;请求头就是信息头Authorization头的主要用作http协议的认证。 Authorization的作用是当客户端访问受口令保护时&#xff0c;服务器端会发送401状态…

微光图像增强算法学习记录(一)

微光图像增强&#xff08;LLIE&#xff09;旨在恢复照明并提高微光图像的可见性&#xff0c;本文对阅读的文献进行记录和分享&#xff0c;帮助回顾和大家建立学习资料。 文献一摘要及前沿摘选主要贡献网络结构实验结论 文献二摘要 文献三摘要主要贡献网络架构实验 文献四摘要实…

C++一维数组练习oj(2)

这时上次的C一维数组练习&#xff1a;C一维数组练习oj-CSDN博客 这到题目我承认非常难&#xff01;当然这只是我认为&#xff0c;因为我只学到了一维数组&#xff01; 对于你们来说可能不难。 好了我不客套了。 这题我们可以将他理解为一条时间轴&#xff1a; 时间轴上小李每1…

分布式搜索引擎ES-RestClient查询文档快速入门

RestClient查询文档快速入门 文章目录 RestClient查询文档快速入门1.1、match_all1.2、全文检索查询1.3、精确查询1.4、复合查询-boolean query1.5、排序和分页1.6、高亮&#xff08;解析查询高亮结果&#xff09; 1.1、match_all package cn.mannor.hotel;import org.apache.…

深度学习pytorch——多层感知机反向传播(持续更新)

在讲解多层感知机反向传播之前&#xff0c;先来回顾一下多输出感知机的问题&#xff0c;下图是一个多输出感知机模型&#xff1a; 课时44 反向传播算法-1_哔哩哔哩_bilibili 根据上一次的分析深度学习pytorch——感知机&#xff08;Perceptron&#xff09;&#xff08;持续更新…

基于python+vue的街道办管理系统flask-django-php-nodejs

在此基础上&#xff0c;结合现有街道办管理体系的特点&#xff0c;运用新技术&#xff0c;构建了以 python为基础的街道办管理信息化管理体系。首先&#xff0c;以需求为依据&#xff0c;根据需求分析结果进行了系统的设计&#xff0c;并将其划分为管理员和用户二种角色和多个主…

分布式搜索引擎-DSL查询文档

分布式搜索引擎-DSL查询文档 文章目录 分布式搜索引擎-DSL查询文档1、DSL Query的分类1.1、全文检索查询1.2、精确查询1.3、地理查询1.4、复合查询1.5、Function Score Query1.6、复合查询Boolean Query 2、搜索结果处理2.1、排序2.2、分页2.3、深度分页2.4、高亮 1、DSL Query…

Fabric Measurement

Fabric Measurement 布料测量

SpringBoot 文件上传(二)

上一节讲解了如何利用MultipartFile接收浏览器端上传的文件&#xff0c;这节讲解服务器端如何将文件保存到本地目录下&#xff0c;下节讲解服务端如何将文件保存在阿里云上。 本节需要解决两个难点&#xff1a; 文件重名问题文件大小限制问题 存储文件 首先解决如何存储文件…

【Qt】使用Qt实现Web服务器(七):动态模板引擎

1、示例 2、源码 2.1 模板配置参数 配置文件中关于模板配置参数如下 path为存放模板的目录suffix为模板文件后缀[templates] path=templates suffix=.tpl encoding=UTF-8 cacheSize=1000000

案例实践 | 基于长安链的煤质检测智慧实验室

案例名称-煤质检测智慧实验室 ■ 建设单位 国能数智科技开发&#xff08;北京&#xff09;有限公司 ■ 用户群体 煤炭生产单位、电力单位、化工单位等产业链上下游单位 ■ 应用成效 化验效率提升50%&#xff0c;出验时间缩短40%&#xff0c;提高化验数据市场公信力 案例…

【漏洞复现】福建科立迅通信指挥调度平台pwd_update.php SQL注入漏洞 (CVE-2024-2621)

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…