CRUD增删改查,MySql Druid简化代码封装增删改查

认识常用的jar包

connection(Driver接口实现的jar包),druid(数据库池管理包),commons-dbutils(简化jdbc数据库的增删改查操作,并且可以封装查询到的结果,同时简化了事务管理)

认识几个常用的类和接口

Driver接口->提供给数据库厂商使用,把需要用到的数据库驱动程序或者类库加载到项目的classpath(jar)包中

DriverManager类->用于加载JDBC驱动并创建于数据库的连接,创建驱动最常使用的是Class类的静态方法forName()来实现,但是在jdk4.0之后就不需要手动加载了(在配置文件里面写 driverClass=com.mysql.jdbc.Driver),连接数据库最长使用的方法是getConnection建立连接,返回一个Connection对象

Connection接口可以与数据库进行交互,有了这个对象就可以在进行事务的处理,以及对数据库的增删改查

认识配置文件里的几个参数

url->通过url可以选择正确的驱动程序,从而连接到我们需要的数据库。

由四部分组成:协议,子协议,子名称,其他参数,例如修改数据库事务为自动提交

配置文件的好处

配置信息需要修改的时候无须改动代码,并且维护简单,省去了配置信息编译的过程

增删改使用的PreparedStatement 对象调用executeUpdate()

查询使用的是executeQuery()

但是传统的JDBC连接比较麻烦,并且在对数据库进行增删改查的时候也是代码比较繁琐,因此引入了,druid(数据库池管理包),commons-dbutils(简化jdbc数据库的增删改查操作)

引入德鲁伊(Druid)

druid里使用频率最高的是数据源接口DataSource(基于数据库连接池),数据源调用getConnection()方法,可以说这种方式就是使用了连接池技术.DataSource内部封装了一个连接池,当你获取DataSource的时候,它已经悄悄的与数据库建立了多个Connection,并将这些Connection放入了连接池,此时调用DataSource.getConnection()它从连接池里取一个Connection返回,Connection使用完后被close,但这个close并不是真正的与数据库断开连接,而是告诉连接池"我"已经被使用完,"你"可以把我分配给其它"人"使用了.就这样连接池里的Connection被循环利用,避免了每次获取Connection时重新去连接数据库。

暴露数据源的原因

将数据源对象暴露出去的原因可能是为了让使用者能够更灵活地操作数据源,比如可以通过数据源对象获取一些元数据信息,或者使用数据源对象来创建其他类型的连接等。另外,有些情况下可能需要在不同的方法或类之间共享同一个数据源对象,这时候将数据源对象暴露出去就可以方便地实现这种共享。但是,在暴露数据源对象时需要注意安全性和封装性,避免使用者对数据源对象进行不合理的操作或者直接修改数据源对象的状态。

在这里学会到了两个新的反射方法

getGenericSuperclass()获取父类的类型,得到父类类型后。getActualTypeArguments()得到父类的泛型,在这里父类指的是抽象类(是增删改查的逻辑语句)。

先说说数据库的连接:

在配置文件中有必须的四个参数和其他参数,由于配置文件是键值对的方式,所以可以使用Properties来加载这个文件。

可以把数据库的连接操作单独成一个工具类,最主要的工具是数据源,使用DruidDataSourceFactory.createDataSource(pro)这个方法创建数据源,通过数据源连接数据库.

封装CURD

QueryRunner来自commons-dbutils这个jar包,用于简化增删改查的逻辑语句,无论哪个实体调用抽象类都可以,获取到泛型指定的类型就可以把得到的ResultSetHandler集合转成一个Bean实体进行封装。一般来说,增删改都需要用到事务处理,传入数据源,作为参数让QueryRunner对象知道要使用哪个数据库连接来执行查询操作,当使用QueryRunner进行操作的时候,传入数据源,会自动从数据源中获取一个数据库连接,并且在查询结束后,连接会被自动关闭和放回连接池,避免手动创建和管理数据库连接。

数据库连接的最终增删改查版本

package com.sun.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

//创建一个数据源的工具类,此类得到数据源对象
public class JDBCUtils {
    private static DruidDataSource dataSource;

    static {
        try {
            Properties properties = new Properties();
            // 读取 jdbc.properties 属性配置文件
            InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            // 从流中加载数据
            properties.load(inputStream);
            // 创建 数据库连接池
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static Connection getConnection() {

        Connection conn = null;

        try {
            conn = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    //获取数据源方法
    public static DataSource getDataSource() {
        return dataSource;
    }

    //关闭连接,放回数据库连接池
    public static void close(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

package com.sun.utils;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 定义一个用来被继承的对数据库进行基本操作的Dao
 * @param <T> 泛型 -> bean类型
 */
public abstract class BaseDao<T>{
    private QueryRunner queryRunner ;
    // 定义一个变量来接收泛型的类型
    private Class<T> type;

    // 获取T的Class对象,获取泛型的类型,泛型是在被子类继承时才确定
    public BaseDao() {
        queryRunner = new QueryRunner(JDBCUtils.getDataSource());
        // 获取子类的类型
        Class clazz = this.getClass();
        // 获取父类的类型
        // getGenericSuperclass()用来获取当前类的父类的类型<这里的当前类指的是继承这个抽象类的子类>
        // ParameterizedType表示的是带泛型的类型
        ParameterizedType parameterizedType =
                (ParameterizedType) clazz.getGenericSuperclass();
        // 获取具体的泛型类型 getActualTypeArguments获取具体的泛型的类型
        // 这个方法会返回一个Type的数组
        Type[] types = parameterizedType.getActualTypeArguments();
        // 获取具体的泛型的类型·
        this.type = (Class<T>) types[0];
    }


    /**
     * 获取所有对象
     *
     * @param sql
     * @param params
     * @return
     */
    public List<T> getBeanList(Connection conn, String sql, Object... params) {
        List<T> list = null;
        try {
            list = queryRunner.query(conn, sql, new BeanListHandler<T>(type), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取一个对象
     *
     * @param sql
     * @param params
     * @return
     */
    public T getBean(Connection conn,String sql, Object... params) {
        T t = null;
        try {                                              //type == String.class
            t = queryRunner.query(conn, sql, new BeanHandler<T>(type), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return t;
    }

    /**
     * 通用的增删改操作(事务有关)
     *
     * @param sql
     * @param params
     * @return
     */
    public int update(Connection conn, String sql, Object... params) {
        int count = 0;
        try {
            count = queryRunner.update(conn, sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 通用的增删改操作(没有办法使用事务)
     *
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql, Object... params) {
        int count = 0;
        try {
            count = queryRunner.update(sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 添加数据后返回主键id(事务有关)
     * @param sql
     * @param params
     * @return
     */
    public int insert(Connection conn ,String sql, Object... params){
        try {
            return queryRunner.insert(conn,sql , new ScalarHandler<Long>() , params).intValue();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 添加数据后返回主键id(没有办法使用事务)
     * @param sql
     * @param params
     * @return
     */
    public int insert(String sql, Object... params){
        try {
            return queryRunner.insert(sql , new ScalarHandler<Long>() , params).intValue();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取单行单列值得方法,专门用来执行像 select count(*)...这样的sql语句
     *
     * @param sql
     * @param params
     * @return
     */
    public int getValue(Connection conn,String sql, Object... params) {
        int count = 0;
        try {
            // 调用queryRunner的query方法获取一个单一的值
            count = queryRunner.query(conn, sql, new ScalarHandler<Long>(), params).intValue();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 获取所有对象
     *
     * @param sql
     * @param params
     * @return
     */
    public List<T> getBeanList( String sql, Object... params) {
        List<T> list = null;
        try {
            list = queryRunner.query(sql, new BeanListHandler<T>(type), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取一个对象
     *
     * @param sql
     * @param params
     * @return
     */
    public T getBean(String sql, Object... params) {
        T t = null;
        try {                                              //type == String.class
            t = queryRunner.query(sql, new BeanHandler<T>(type), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return t;
    }






    /**
     * 获取单行单列值得方法,专门用来执行像 select count(*)...这样的sql语句
     *
     * @param sql
     * @param params
     * @return
     */
    public int getValue(String sql, Object... params) {
        int count = 0;
        try {
            // 调用queryRunner的query方法获取一个单一的值
            count = queryRunner.query( sql, new ScalarHandler<Long>(), params).intValue();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }
}

总结:

一个javaBean,一个封装好增删改查的逻辑操作(工具类<抽象类>可以供多个JavaBean使用),一个Dao接口,是对应实体类的增删改查,一个实现类,继承工具类,同时实现Dao接口。一套JDBC连接数据库的增删改查就封装好了

使用三个第三方Jar包,其中QueryRunner类简化了代码的书写,使用这个类可以直接调用封装好的增删改查逻辑,传入数据源在查询的时候无须手动管理数据池里的连接,如需要事务处理,可以直接传入Connection数据库连接手动管理。最终版本依赖数据源,数据库连接池,第三方代码简化工具。

但是这个封装仍有不足,比如:QueryRunner没有提供直接的删除方法,要删除数据可以通过update方法来实现,插入方法返回的是受影响的行数,而不是插入的条数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是有关使用Spring Boot实现CRUD操作的增加、删除、修询的一些基本步骤: 1. 配置项目依赖 在您的Maven或Gradle构建文件中添加Spring Boot和相关的数据库依赖。例如,如果您想要使用MySQL数据库,则需要添加以下依赖项: ```xml <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- MySQL database driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- Spring Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 2. 配置数据库连接 在application.properties或application.yml文件中添加数据库连接信息,如下所示: ```yaml spring.datasource.url=jdbc:mysql://localhost:3306/yourdatabase spring.datasource.username=yourusername spring.datasource.password=yourpassword spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update ``` 3. 创建实体类 创建一个实体类来表示您要持久化的数据。例如,如果您要创建一个用户对象,则可以编写以下代码: ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "email") private String email; // getter and setter methods } ``` 4. 创建Repository接口 创建一个Repository接口来定义CRUD操作。例如,如果您要操作用户对象,则可以编写以下代码: ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { } ``` 5. 创建服务类 创建一个服务类来实现您的业务逻辑。例如,如果您要实现用户管理功能,则可以编写以下代码: ```java @Service public class UserService { @Autowired private UserRepository userRepository; public List<User> getAllUsers() { return userRepository.findAll(); } public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } public User addUser(User user) { return userRepository.save(user); } public User updateUser(User user) { return userRepository.save(user); } public void deleteUserById(Long id) { userRepository.deleteById(id); } } ``` 6. 创建控制器类 创建一个控制器类来处理HTTP请求。例如,如果您要处理用户对象的HTTP请求,则可以编写以下代码: ```java @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @GetMapping("") public List<User> getAllUsers() { return userService.getAllUsers(); } @GetMapping("/{id}") public User getUserById(@PathVariable("id") Long id) { return userService.getUserById(id); } @PostMapping("") public User addUser(@RequestBody User user) { return userService.addUser(user); } @PutMapping("") public User updateUser(@RequestBody User user) { return userService.updateUser(user); } @DeleteMapping("/{id}") public void好的,我可以用中文回答您关于 Spring Boot CRUD 的问题。 Spring Boot 是一个基于 Spring 框架的快速开发框架,可以帮助开发者快速构建 Web 应用程序。CRUD 则是指对于一个数据实体,可以进行增加(Create)、询(Retrieve)、更新(Update)、删除(Delete)的操作。 在 Spring Boot 中实现 CRUD 操作,通常需要以下步骤: 1. 定义数据实体类:首先需要定义一个数据实体类,表示要进行 CRUD 操作的数据对象。该类需要使用 JPA 注解来定义实体和属性,并且需要定义一个主键属性。 2. 定义数据访问层接口:接下来需要定义一个数据访问层接口,用于定义数据操作的方法,包括增加、询、更新和删除等操作。 3. 实现数据访问层接口:在实现数据访问层接口时,需要使用 Spring Data JPA 提供的 Repository 接口,该接口提供了许多 CRUD 操作的默认实现,可以大大减少我们的代码量。 4. 定义业务逻辑层接口和实现类:在定义业务逻辑层接口和实现类时,可以将数据访问层接口作为一个成员变量注入进来,并在业务逻辑层方法中调用数据访问层接口中的方法,来完成具体的数据操作。 5. 定义控制器类:最后需要定义一个控制器类,用于接收 HTTP 请求,并将请求参数传递给业务逻辑层进行处理,然后返回相应的结果给客户端。 以上就是实现 Spring Boot CRUD 的基本步骤,具体实现过程可以参考 Spring Boot 官方文档和相关教程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

媪姝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值