一文学会JDBC实现java和mySQL的数据连接(尚硅谷学习课程代码+笔记+思路总结 ...

打印 上一主题 下一主题

主题 821|帖子 821|积分 2463

JDBC是指数据库连接技术,用于java连接mySQL等数据库。本文详细先容了尚硅谷课程中JDBC的学习内容和补充知识。
概述

  • java语言只提供规范接口,存在于java.sql.javax.sql包下,然后数据库软件根据java提供的规范实现详细的驱动代码(jar)
  • jar包是java步伐打成的一种压缩包格式,只要导入就可以利用对应方法
学习思路:(可以学完再看)


  • 六大根本步骤获取连接,包罗直接输入字符串的Statement和改进版的PreparedStatement(通过占位符解决了容易SQL攻击的问题)
  • JDBC的增删改查,此中插入数据需要思量主键自增长批量插入效率低的问题
  • 建立数据库事务(根本特征是关闭了自动提交,要同时完成多个操纵后再一起提交,如转账过程先增长A账户的钱,再扣除B账户的钱,一定要一起提交,防止出现只乐成一件事)
  • 连接池,优化建立连接的过程(每件事都去连接很繁琐,浪费资源,Druid连接池)


    • 硬编码:通过设置参数的方式
    • 软编码:通过读取外部配置文件的方式(读取方法利用了类加载器,补充阐明在末端)

  • 封装连接工具类(通过静态代码块的方式保证连接池只被创建一次,而不是每次调用方法都创建一个新的连接池对象。)


    • V1.0:不同方法调用拿到的是不同连接对象
    • V2.0:利用线程当地量的方法,保证同一个线程不同方法拿到的是同一个连接

  • 完备工具类封装(连接池优化了建立连接,那么把增删改查操纵也封装一下吧)


    • executeUpdate(实现数据的更新操纵,包罗增,删,改)
    • executeQuery(实现数据的查询操纵,通过反射机制,输入模板对象,返回查询出的对象列表)

根本步骤


  • 注册驱动,将依赖的jar包举行安装
  • 建立连接 connection
  • 创建发送SQL语句的对象statement
  • statement对象去发送SQL数据到数据库获取返回结果
  • 剖析结果集
  • 销毁资源
mySQL端 创建t_user表
  1. create database atguigu;
  2. use atguigu;
  3. create table t_user(
  4.      id int primary key auto_increment comment '用户主键',
  5.      account varchar(20) not null unique comment '账号',
  6.      password varchar(64) not null comment '密码',
  7.      nickname varchar(20) not null comment '昵称');
  8. insert into t_user(account,password,nickname) values('root','123456','经理'),('admin','666666','管理员');
复制代码
java端获取数据
  1. public class StatementQuery {
  2.     public static void main(String[] args) throws SQLException {
  3.         //1.注册驱动
  4.         DriverManager.registerDriver(new Driver());//8+驱动要选择带cj的
  5.         //2. 获取连接,需要数据库ip地址(127.0.0.1),数据库端口号(3306),账号(root),密码,连接数据库的名称(atguigu)
  6.         //jdbc:数据库厂商名//ip:端口号/数据库名
  7.         Connection connection=DriverManager.
  8.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  9.         //3. 创建statement
  10.         Statement statement = connection.createStatement();
  11.         //4. 发送SQL语句
  12.         String sql="select * from t_user";
  13.         ResultSet resultSet = statement.executeQuery(sql);
  14.         //5. 进行结果集更新
  15.         while(resultSet.next()){
  16.             int id = resultSet.getInt("id");
  17.             String account = resultSet.getString("account");
  18.             String password = resultSet.getString("password");
  19.             String nickname = resultSet.getString("nickname");
  20.             System.out.println(id+"--"+account+"--"+password+"--"+nickname);
  21.         }
  22.         //6. 关闭资源
  23.         resultSet.close();
  24.         statement.close();
  25.         connection.close();
  26.     }
  27. }
复制代码
模仿用户登录


  • 模仿用户登录
  • 键盘输入事件收集账号密码信息
  • 输入账号密码举行查询验证是否登录乐成
  1. public class SatetementUserLoginPart {
  2.     public static void main(String[] args) throws SQLException, ClassNotFoundException {
  3.         //0. 获取用户输入信息
  4.         Scanner scanner = new Scanner(System.in);
  5.         System.out.println("请输入账号");
  6.         String account = scanner.nextLine();
  7.         System.out.println("请输入密码");
  8.         String password = scanner.nextLine();
  9.         //1.注册驱动,有两种方案
  10.         /*方案一--------------
  11.         //DriverManager.registerDriver(new Driver());//会注册两次驱动,可以考虑仅触发静态代码块
  12.         //类加载机制:类记载时刻会触发静态代码块,可以通过new,静态方法,静态属性等触发
  13.         */
  14.         //方案二-------------
  15.         Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
  16.         //优点是字符串可以提取到外部的配置文件,便于更换数据驱动,会更加灵活
  17.         //2. 获取数据库连接,共有三种方法
  18.         //该方法是一个重载方法,允许开发者用不同的形式传入数据库连接的核心参数
  19.         //三个参数-------------
  20.         Connection connection=DriverManager.
  21.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  22.         //jdbc:mysql:///atguigu 如果本机和3306可以省略为///
  23.         //两个参数--------------
  24.         /*
  25.         Properties info=new Properties();
  26.         info.put("user","root");
  27.         info.put("password","root");
  28.         DriverManager.getConnection("jdbc:mysql:///atguigu",info);
  29.         //一个参数--------------
  30.         //jdbc:数据库厂商名//ip:端口号/数据库名?user=root&password=root
  31.         DriverManager.getConnection("jdbc:mysql:///atguigu?user=root&password=root");
  32.         //其他可选信息,如果是sql8.0以后的版本可以省略serverTimezone=Asia/Shanghai&UseUnicode=true&characterEncoding=utf8&useSSL=true
  33.         */
  34.         //3. 创建发送SQL语句的Statetment对象
  35.         Statement statement = connection.createStatement();
  36.         //4. 发送SQL语句
  37.         String sql="SELECT * FROM t_user WHERE account='"+account+"'AND PASSWORD='"+password+"';";
  38.         //executeUpdate用于更新数据,返回影响的函数,executeQuery负责返回查询结果,返回结果封装对象
  39.         ResultSet resultSet = statement.executeQuery(sql);
  40.         //5.查询结果集解析,resultSet给出的是逐行的对象,使用next可以逐行提取下一个,遍历完毕时返回false
  41.         /*仅查询的方案
  42.         while(resultSet.next()){
  43.             //光标已经移动,此时利用getInt\getString读取该行的数据
  44.             //getString输入可以是index(列的下角标,从左向右从1开始),可以是列名(有别名写别名)
  45.             int id = resultSet.getInt("id");
  46.             String account1 = resultSet.getString("account");
  47.             String password1 = resultSet.getString("password");
  48.             String nickname = resultSet.getString("nickname");
  49.             System.out.println(id+"--"+account+"--"+password+"--"+nickname);
  50.         }
  51.         */
  52.         //考虑实际需求,只需要有一行数据证明就可以登录成功
  53.         if(resultSet.next()){
  54.             System.out.println("登录成功");
  55.         }else {
  56.             System.out.println("登录失败,用户名或密码错误");
  57.         }
  58.         //6. 关闭资源
  59.         resultSet.close();
  60.         statement.close();
  61.         connection.close();
  62.     }
  63. }
复制代码
存在几个问题

  • SQL语句需要字符串拼接比较贫苦
  • 只能拼接字符串类型,其他的数据库类型无法处理
  • 可能发生注入攻击(动态值充当了SQL语句结构)
模仿用户登录(prepare改进)
  1. public class SPUserLoginPart {
  2.     public static void main(String[] args) throws ClassNotFoundException, SQLException {
  3.         //0. 获取用户输入信息
  4.         Scanner scanner = new Scanner(System.in);
  5.         System.out.println("请输入账号");
  6.         String account = scanner.nextLine();
  7.         System.out.println("请输入密码");
  8.         String password = scanner.nextLine();
  9.         //1.注册驱动,有两种方案
  10.         Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
  11.         //2. 获取数据库连接
  12.         Connection connection= DriverManager.
  13.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  14.         //3. 创建发送SQL语句的preparedstatetment对象
  15.         //(1). 编写SQL语句结构,动态值部分使用占位符?替代(2).创建preparedstatetment,传入动态值
  16.         //(3). 动态值 占位符 赋值? 单独赋值即可 (4). 发送
  17.         String sql="SELECT * FROM t_user where account=? and password=?;";
  18.         PreparedStatement preparedStatement = connection.prepareStatement(sql);
  19.         /*
  20.         参数一:index占位符的位置,从1开始
  21.         参数二:Object占位符的值,可以是任何类型
  22.          */
  23.         preparedStatement.setObject(1,account);
  24.         preparedStatement.setObject(2,password);
  25.         ResultSet resultSet = preparedStatement.executeQuery();
  26.         //5. 结果集解析
  27.         if(resultSet.next()){
  28.             System.out.println("登录成功");
  29.         }else {
  30.             System.out.println("登录失败,用户名或密码错误");
  31.         }
  32.         //6. 关闭资源
  33.         resultSet.close();
  34.         preparedStatement.close();
  35.         connection.close();
  36.     }
  37. }
复制代码
JDBC实现增删改查
  1. public class PSCURDPart {
  2.     @Test
  3.     public void testInsert() throws ClassNotFoundException, SQLException {
  4.         //1.注册驱动,有两种方案
  5.         Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
  6.         //2. 获取数据库连接
  7.         Connection connection= DriverManager.
  8.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  9.         //3. 创建发送SQL语句的preparedstatetment对象
  10.         String sql="insert into t_user(account,password,nickname) values(?,?,?)";
  11.         PreparedStatement preparedStatement = connection.prepareStatement(sql);
  12.         preparedStatement.setObject(1,"test");
  13.         preparedStatement.setObject(2,"test");
  14.         preparedStatement.setObject(3,"二狗");
  15.         int rows = preparedStatement.executeUpdate();
  16.         //5. 结果集解析
  17.         if(rows>0){
  18.             System.out.println("插入成功");
  19.         }else {
  20.             System.out.println("插入失败");
  21.         }
  22.         //6. 关闭资源
  23.         preparedStatement.close();
  24.         connection.close();
  25.     }
  26.     @Test
  27.     public void testUpdate() throws ClassNotFoundException, SQLException {
  28.         //1.注册驱动,有两种方案
  29.         Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
  30.         //2. 获取数据库连接
  31.         Connection connection= DriverManager.
  32.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  33.         //3. 创建发送SQL语句的preparedstatetment对象
  34.         String sql="update t_user set nickname=? where id=?";
  35.         PreparedStatement preparedStatement = connection.prepareStatement(sql);
  36.         preparedStatement.setObject(1,"张三");
  37.         preparedStatement.setObject(2,3);
  38.         int rows = preparedStatement.executeUpdate();
  39.         //5. 结果集解析
  40.         if(rows>0){
  41.             System.out.println("修改成功");
  42.         }else {
  43.             System.out.println("修改失败");
  44.         }
  45.         //6. 关闭资源
  46.         preparedStatement.close();
  47.         connection.close();
  48.     }
  49.     @Test
  50.     public void testDelete() throws ClassNotFoundException, SQLException {
  51.         //1.注册驱动,有两种方案
  52.         Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
  53.         //2. 获取数据库连接
  54.         Connection connection= DriverManager.
  55.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  56.         //3. 创建发送SQL语句的preparedstatetment对象
  57.         String sql="delete from t_user where id=?";
  58.         PreparedStatement preparedStatement = connection.prepareStatement(sql);
  59.         preparedStatement.setObject(1,3);
  60.         int rows = preparedStatement.executeUpdate();
  61.         //5. 结果集解析
  62.         if(rows>0){
  63.             System.out.println("删除成功");
  64.         }else {
  65.             System.out.println("删除失败");
  66.         }
  67.         //6. 关闭资源
  68.         preparedStatement.close();
  69.         connection.close();
  70.     }
  71.     //查询所有用户数据,并封装到一个List<Map> 集合中,key=列名,value=列的内容
  72.     @Test
  73.     public void testSelect() throws ClassNotFoundException, SQLException {
  74.         //1.注册驱动,有两种方案
  75.         Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
  76.         //2. 获取数据库连接
  77.         Connection connection= DriverManager.
  78.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  79.         //3. 创建发送SQL语句的preparedstatetment对象
  80.         String sql="SELECT id,account,password,nickname FROM t_user;";
  81.         PreparedStatement preparedStatement = connection.prepareStatement(sql);
  82.         ResultSet resultSet = preparedStatement.executeQuery();
  83.         //5. 结果集解析
  84.         List<Map> list=new ArrayList<>();
  85.         ResultSetMetaData metaData = resultSet.getMetaData();//获取当前结果集列的信息对象
  86.         int columnCount = metaData.getColumnCount();//为了水平遍历
  87.         while(resultSet.next()){
  88.             Map map=new HashMap();
  89.             for (int i = 1; i <columnCount ; i++) {
  90.                 Object value = resultSet.getObject(i);
  91.                 String columnLabel = metaData.getColumnLabel(i);//getlabel可以得到别名,name只能别名
  92.                 map.put(columnLabel,value);
  93.             }
  94.             list.add(map);
  95.         }
  96.         System.out.println(list);
  97.         //6. 关闭资源
  98.         preparedStatement.close();
  99.         connection.close();
  100.     }
  101. }
复制代码
批量插入
  1. public class PSOthePart {
  2.     //t_user 插入一条数据,并获取数据库自增长的主键
  3.     @Test
  4.     public void returnPrimaryKey() throws ClassNotFoundException, SQLException {
  5.         Class.forName("com.mysql.cj.jdbc.Driver");
  6.         Connection connection= DriverManager.
  7.                 getConnection("jdbc:mysql://127.0.0.1:3306/atguigu","root","mypassword");
  8.         String sql="Insert into t_user(account,password,nickname) values(?,?,?);";
  9.         //插入数据同时获取返回主键
  10.         PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
  11.         preparedStatement.setObject(1,"test1");
  12.         preparedStatement.setObject(2,"123456");
  13.         preparedStatement.setObject(3,"蛋");
  14.         int i=preparedStatement.executeUpdate();
  15.         if(i>0){
  16.             System.out.println("插入成功");
  17.             //获取主键的结果集对象,一行一列,id=值
  18.             ResultSet resultSet = preparedStatement.getGeneratedKeys();
  19.             resultSet.next();
  20.             int id=resultSet.getInt(1);
  21.             System.out.println("id="+id);
  22.         }else{
  23.             System.out.println("插入失败");
  24.         }
  25.         preparedStatement.close();
  26.         connection.close();
  27.     }
  28. }
复制代码
数据库事务


  • 答应在失败环境下,数据回归到业务之前的状态!
  • 具有原子性(不可切分)、一致性(状态稳定)、隔离性(互不干扰)、长期性(永久性改变)
  • 手动提交
实现目标:实现两个账户之间的安全转账,如果一方余额不足不会出现转账错误(即一方账户增长了另一方没有淘汰)
业务表的创建
  1. public void returnPrimaryKey2() throws ClassNotFoundException, SQLException {
  2.         Class.forName("com.mysql.cj.jdbc.Driver");
  3.         // 1.路径后面添加允许批量操作
  4.         Connection connection= DriverManager.
  5.                 getConnection("jdbc:mysql:///atguigu?rewriteBatchedStatements=true","root","mypassword");
  6.         String sql="Insert into t_user(account,password,nickname) values(?,?,?);";
  7.         PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
  8.         long start=System.currentTimeMillis();
  9.         for (int i = 1; i < 10000; i++) {
  10.             preparedStatement.setObject(1,"dd"+i);
  11.             preparedStatement.setObject(2,"dd"+i);
  12.             preparedStatement.setObject(3,"蛋"+i);
  13.             preparedStatement.addBatch();//2. 不执行,追加到values后面,批量添加addBatch
  14.         }
  15.         preparedStatement.executeBatch();//3. 执行批量操作
  16.         long end = System.currentTimeMillis();
  17.         preparedStatement.close();
  18.         connection.close();
  19.     }
复制代码
BankService.java(实现业务操纵,即转账)
  1. CREATE TABLE t_bank(
  2. id INT PRIMARY KEY AUTO_INCREMENT,
  3. account VARCHAR(20) NOT NULL UNIQUE COMMENT '账户',
  4. money INT UNSIGNED COMMENT '金额,不能为负值'
  5. );
  6. INSERT INTO t_bank(account,money) VALUES
  7. ('ergouz1',1000),('lvdandan',1000);
复制代码
BankDao.java(业务实现细节,即账户钱增长和淘汰)
  1. public class BankService {
  2.     @Test
  3.     public  void start() throws SQLException, ClassNotFoundException {
  4.         transfer("lvdandan","ergouz1",500);
  5.     }
  6.     public void transfer(String addAccount,String subAccount,int money) throws SQLException, ClassNotFoundException {
  7.         Class.forName("com.mysql.cj.jdbc.Driver");
  8.         // 1.路径后面添加允许批量操作
  9.         Connection connection= DriverManager.
  10.                 getConnection("jdbc:mysql:///atguigu","root","mypassword");
  11.         BankDao bankDao=new BankDao();
  12.         try{
  13.             connection.setAutoCommit(false);//关闭自动提交,开启手动提交
  14.             bankDao.add(addAccount,money,connection);
  15.             System.out.println("----");
  16.             bankDao.sub(subAccount,money,connection);
  17.             connection.commit();//事务提交
  18.         }catch (Exception e){
  19.             connection.rollback();
  20.             throw e;
  21.         }finally {
  22.             connection.close();
  23.         }
  24.     }
  25. }
复制代码
连接池


  • 每次获取新的连接消耗很大,为了节约创建和销毁连接的性能消耗
  • javax.sql.DataSource接口,规范了连接池获取连接的方法,规范了连接池回收连接的方法,连接池有多种,但都实现了该接口
  • 硬编码:通过设置参数的方式
  • 软编码:通过读取外部配置文件的方式(读取方法利用了类加载器,补充阐明在末端)
  1. public class BankDao {
  2.     public void add(String account,int money,Connection connection) throws ClassNotFoundException, SQLException {
  3.         String sql="Update t_bank set money=money+? where account=?;";
  4.         PreparedStatement statement = connection.prepareStatement(sql);
  5.         statement.setObject(1,money);
  6.         statement.setObject(2,account);
  7.         statement.executeUpdate();
  8.         statement.close();
  9.     }
  10.     public void sub(String account,int money,Connection connection) throws ClassNotFoundException, SQLException {
  11.         String sql="Update t_bank set money=money-? where account=?;";
  12.         PreparedStatement statement = connection.prepareStatement(sql);
  13.         statement.setObject(1,money);
  14.         statement.setObject(2,account);
  15.         statement.executeUpdate();
  16.         statement.close();
  17.     }
  18. }
复制代码
druid.properties
  1. public class DruidUsePart {
  2.     //直接使用代码设置连接池连接参数等方式
  3.     @Test
  4.     public void testHard() throws SQLException {
  5.         DruidDataSource dataSource=new DruidDataSource();
  6.                 //连接数据库驱动类的全限定符 注册驱动
  7.         dataSource.setUrl("jdbc:mysql:///atguigu");
  8.         dataSource.setUsername("root");
  9.         dataSource.setPassword("mypassword");
  10.         dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
  11.         dataSource.setInitialSize(5);//初始化连接数量
  12.         dataSource.setMaxActive(10);//最大的数量
  13.         DruidPooledConnection connection = dataSource.getConnection();//获取连接
  14.         //数据库操作
  15.         //
  16.         connection.close();
  17.     }
  18.     //读取外部配置文件的方法实例化连接对象
  19.     public void testSoft() throws Exception {
  20.         Properties properties = new Properties();
  21.         InputStream ips = DruidUsePart.class.getClassLoader().getResourceAsStream("druid.properties");
  22.         properties.load(ips);
  23.         DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
  24.         Connection connection = dataSource.getConnection();
  25.         //数据库操作
  26.         //
  27.         connection.close();
  28.     }
  29. }
复制代码
连接工具类封装

通过静态代码块的方式保证连接池只被创建一次,而不是每次调用方法都创建一个新的连接池对象
V1.0
  1. #key = value => java properties读取
  2. #druid的key必须固定命名
  3. driverClassName=com.mysql.cj.jdbc.Driver
  4. username=root
  5. password=123456
  6. url=jdbc:mysql://127.0.0.1:3306/atguigu
复制代码
问题:不同方法调用拿到的是不同对象,思量如何同一个线程不同方法拿到的是同一个连接
V2.0(线程当地量)

利用线程当地变量,存储连接信息   确保一个线程的多个方法可以获取同一个connection

    1. public class JdbcUtils {
    2.     private static DataSource dataSource = null;//连接池对象
    3.     static{
    4.         //初始化连接池对象
    5.         Properties properties = new Properties();
    6.         InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
    7.         try {
    8.             properties.load(is);
    9.         } catch (IOException e) {
    10.             throw new RuntimeException(e);
    11.         }
    12.         try {
    13.             dataSource = DruidDataSourceFactory.createDataSource(properties);
    14.         } catch (Exception e) {
    15.             throw new RuntimeException(e);
    16.         }
    17.     }
    18.     public static Connection getConnection() throws SQLException {
    19.         return dataSource.getConnection();
    20.     }
    21.     public static void freeConnection(Connection connection) throws SQLException {
    22.         connection.close();//连接池的连接执行回收
    23.     }
    24. }
    复制代码
    1. 优势:事务操作的时候server 和 dao 属于同一个线程,不用再传递参数
    复制代码
  1. 大家都可以调用getConnection自动获取的是相同的连接池
复制代码
V2版本代码
  1. 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 JdbcUtilsV2 {    private static DataSource dataSource = null;//连接池对象     大家都可以调用getConnection自动获取的是相同的连接池    static{        //初始化连接池对象        Properties properties = new Properties();        InputStream is = JdbcUtilsV2.class.getClassLoader().getResourceAsStream("druid.properties");        try {            properties.load(is);        } catch (IOException e) {            throw new RuntimeException(e);        }        try {            dataSource = DruidDataSourceFactory.createDataSource(properties);        } catch (Exception e) {            throw new RuntimeException(e);        }    }    public static Connection getConnection() throws SQLException {        //先查看线程当地变量中是否存在        Connection connection = threadLocal.get();        if(connection == null){            //线程当地变量没有,连接池获取            connection = dataSource.getConnection();            threadLocal.set(connection);        }        return dataSource.getConnection();    }    public static void freeConnection() throws SQLException {        Connection connection = threadLocal.get();        if(connection != null){            threadLocal.remove();//清空当地变量数据            connection.setAutoCommit(true);            connection.close();//连接池的连接执行回收        }    }}
复制代码
此时的封装只针对了获取连接部分,还不够美满,可以创建一个更加美满的工具类,包罗数据库的增删改查
完备工具类(修改和查询)

类代码

[code]package utils;import java.lang.reflect.Field;import java.sql.*;import java.util.ArrayList;import java.util.List;/** * Description:封装dao层数据库重复代码 * TODO:封装两个方法 *      一个简化非DQL *      一个简化DQL(查询语句) */public class BaseDao {    /**     * 封装简化非DQL语句     * @param sql  带占位符的SQL语句     * @param params 占位符的值  留意:传入的占位符的值,必须即是SQL语句?位置的值     * @return  执行影响的行数     */    public int executeUpdate(String sql, Object... params) throws SQLException {//Object...可变参数传参数形式,在代码中可以作为数组利用        //获取连接        Connection connection = JdbcUtilsV2.getConnection();        PreparedStatement preparedStatement = connection.prepareStatement(sql);        //可变参数可当作数组利用        for (int i = 1; i  没有开启事物,正常回收连接            JdbcUtilsV2.freeConnection();        }        return rows;    }    /**     * 将查结果封装到一个实体类集合     * @param clazz 要接值的实体类集合的模板对象     * @param sql  查询语句,要求类名或者别名即是实体类的属性名  u_id as  uId  =>  uId     * @param params  占位符的值 要和 ? 位置对象对应     * @return 查询的实体类集合     * @param      声明的结果的泛型     * @throws SQLException     * @throws InstantiationException     * @throws IllegalAccessException     * @throws NoSuchFieldException     */    //第一个是方法泛型,需要调用时确定    // 第三个T是指利用反射技术赋值    public  List executeQuery(Class clazz,String sql,Object... params) throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException {        Connection connection = JdbcUtilsV2.getConnection();        PreparedStatement preparedStatement = connection.prepareStatement(sql);        if(params != null && params.length != 0) {            for (int i = 1; i
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连密封材料

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表