74、SpringBoot 整合 Spring Data JDBC

74、SpringBoot 整合 Spring Data JDBC

目录SpringBoot 整合 Spring Data JDBC 总结:用起来跟 Spring Data JPA 差不多

什么是 JdbcTemplate?(Template译为模板) Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作

Spring Data JDBC既不需要JPA、Hibernate这种ORM框架,但Spring Data还是提供了面向对象的封装。

——它相当于是一种轻量化的持久化技术,用起来比Spring JDBC更方便,但又不像Spring Data JPA那么需要大量注解、复杂

它相当于是一个折中。

Spring Data JDBC的功能 大致包括如下几方面功能:- DAO接口只需继承CrudRepository或PagingAndSortingRepository, Spring Data JDBC能为DAO组件生成实现类、类似于Spring Data JPA。 - Spring Data JDBC支持方法名关键字查询、类似于Spring Data JPA - - Spring Data JDBC支持用@Query定义查询语句。 - - Spring Data JDBC同样支持DAO组件添加自定义的查询方法 ——————通过添加额外的父接口,并为额外的该接口提供实现类, Spring Data JDBC就能该实现类中的方法“移植”到DAO组件中。 - 一般不支持样本查询;也不支持Specification查询。

Spring Data JDBC VS Spring Data JPASpring Data JDBC相当于“轻量化”的Spring Data JPA。

Spring Data JDBC的功能不如Spring Data JPA强大(毕竟它底层没有ORM框架的加持)。

Spring Data JDBC也不需要处理复杂的ORM映射、实体对象的生命周期管理等,因此Spring Data JDBC用起来更简单。 ——Spring Data JDBC有点类似MyBatis

Spring Data JDBC映射规则Spring Data JDBC默认的处理方式是“约定优于配置”的同名映射:

程序操作User对象,Spring Data JDBC对应于操作user表。

对于id数据列,自动被映射到对象的id属性。

Spring Data JDBC的注解: @Table:映射自定义的表名。非JPA注解 @Column:映射自定义的列名,非JPA注解 @Id:修饰标识属性,非JPA注解 @PersistenceConstructor:修饰主构造器。当你的映射类中有多个构造器时, 你希望Spring Data JDBC用哪个构造器来创建对象, 就用该注解来修饰该构造器。

Spring Data JDBC操作数据库方法:1、全自动:方法名关键字查询。

2、半自动:@Query指定查询语句。

3、全手动:自己定义查询方法,即可用DataSource,也用JdbcTemplate。

Spring Data JDBC的编程步骤:1、定义映射类,为Java类添加@Table、@Column、@Id和 @PersistenceConstructor

2、让DAO接口继承CrudRepository或PagingAndSortingRepository。

3、在DAO接口中定义方法名关键字查询、@Query查询、完全自定义查询(需要额外的接口和实现类)

代码演示其实跟 JPA 差不多

User 类UserDao接口,根据方法名关键字查询---------全自动,不用自己写sql的 也有通过注解 @Query 进行查询的 —>自己定义查询语句-----半自动,可以自己写sql语句

也可以自定义Dao接口,用来自己写sql和封装数据

自定义接口和实现类,来实现数据的查询, 一个基于 DataSource , 一个基于 jdbcTemplate

UserDaoTest 测试测试类

application.propertiespom.xml一个是 spring data jdbc 的依赖 , 一个是 mysql 的依赖, 创建项目的时候这个 mysql 的依赖老是不完整,所以要记录下

完整代码Userpackage cn.ljh.app.domain; import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.Table; /** * author JH */ @Data //此处不能添加JPA注解,因为此项目没有用到 JPA @Table("user_inf") public class User { @Column(value = "user_id") @Id private Integer id; private String name; private String password; private int age; /** * @PersistenceConstructor * 修饰主构造器。当你的映射类中有多个构造器时, * 你希望Spring Data JDBC用哪个构造器来创建对象,就用该注解来修饰该构造器 */ @PersistenceConstructor public User() { } public User(Integer id, String name, String password, int age) { this.id = id; this.name = name; this.password = password; this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", password='" + password + '\'' + ", age=" + age + '}'; } } UserDaopackage cn.ljh.app.dao; import cn.ljh.app.domain.User; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.CrudRepository; import java.util.List; public interface UserDao extends CrudRepository,CustomUserDao { // 继承 CrudRepository 接口后,就已经有通用的 CRUD 操作,无需自己来书写这些方法 //方法名关键字查询---------全自动 //根据名字模糊查询 List findByNameLike(String namePattern); //根据年龄大小进行范围查询 List findByAgeGreaterThan(int startAge); List findByAgeLessThan(int age); //根据年龄区间进行范围查询 List findByAgeBetween(int startAge , int endAge); //@Query 查询 --->自己定义查询语句-----半自动 //rowMapperClass 或 rowMapperRef 是用来做自定义映射,查询出来的User对象的数据,映射到Student对象的属性上面去都可以,因为是自定义的。 //根据密码模糊查询 @Query("select * from user_inf where password like :passwordPattern") List findBySql(String passwordPattern); //根据年龄范围修改名字 @Query("update user_inf set name = :name where age between :startAge and :endAge") @Modifying //更改数据库数据需要用到这个注解 int updateNameByAge(String name , int startAge , int endAge); } CustomUserDaopackage cn.ljh.app.dao; import cn.ljh.app.domain.User; import java.util.List; /** * author JH */ //自己定义的接口,用来实现全手动的查询 public interface CustomUserDao { //通过名字进行模糊查询,使用 dataSource List customQueryUsingConnection(String namePattern); //通过名字进行模糊查询,使用 jdbcTemplate List customQueryUsingTemplate(String namePattern); } CustomUserDaoImplpackage cn.ljh.app.dao.impl; import cn.ljh.app.dao.CustomUserDao; import cn.ljh.app.domain.User; import lombok.SneakyThrows; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import java.sql.Array; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; /** * author JH */ public class CustomUserDaoImpl implements CustomUserDao { private DataSource dataSource; private JdbcTemplate jdbcTemplate; //通过有参构造器进行依赖注入 public CustomUserDaoImpl(DataSource dataSource, JdbcTemplate jdbcTemplate) { this.dataSource = dataSource; this.jdbcTemplate = jdbcTemplate; } @SneakyThrows @Override public List customQueryUsingConnection(String namePattern) { //创建数据库连接 Connection connection = this.dataSource.getConnection(); //创建 PreparedStatement 预处理语句 PreparedStatement pstmt = connection.prepareStatement("select * from user_inf where name like ?"); pstmt.setString(1, namePattern); //执行查询 ResultSet rs = pstmt.executeQuery(); List userList = new ArrayList<>(); //遍历结果集,封装对象 while (rs.next()) { userList.add(new User( rs.getInt("user_id"), rs.getString("name"), rs.getString("password"), rs.getInt("age") )); } return userList; } @Override public List customQueryUsingTemplate(String namePattern) { //直接执行查询 List userList = this.jdbcTemplate.query( "select user_id as id,name ,password,age from user_inf where name like ?", //把查询的结果封装起来 new BeanPropertyRowMapper<>(User.class), namePattern ); return userList; } } UserDaoTestpackage cn.ljh.app; import cn.ljh.app.dao.UserDao; import cn.ljh.app.domain.User; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.test.annotation.Rollback; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; /** * author JH */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) public class UserDaoTest { @Autowired private UserDao userDao; // 继承 CrudRepository 接口后,就已经有通用的 CRUD 操作,无需自己来书写这些方法============== //添加user对象 @ParameterizedTest @CsvSource({"aa,xxx,2", "bb,xxx,3"}) public void testSave(String name, String password, int age) { //没有id,save就是添加 User user = userDao.save(new User(null, name, password, age)); System.err.println(user); } //根据id修改对象 @ParameterizedTest @CsvSource({"13,aaa,xxxx,22"}) public void testUpdate(Integer id, String name, String password, int age) { //有id,save就是修改 User user = userDao.save(new User(id, name, password, age)); System.err.println(user); } //根据id删除用户对象 @ParameterizedTest @ValueSource(ints = {14}) public void testDelete(Integer id) { userDao.deleteById(id); } //根据id查询对象 @ParameterizedTest @ValueSource(ints = {1}) public void testFindById(Integer id) { Optional user = userDao.findById(id); } //方法名关键字查询---------全自动===================================================== //根据名字模糊查询 @ParameterizedTest @ValueSource(strings = {"孙%", "%精"}) public void testFindByNameLike(String namePattern) { List users = userDao.findByNameLike(namePattern); users.forEach(System.err::println); } //根据年龄大小进行范围查询 @ParameterizedTest @ValueSource(ints = {500, 10}) public void testFindByAgeGreaterThan(int startAge) { List users = userDao.findByAgeGreaterThan(startAge); users.forEach(System.err::println); } //根据年龄大小进行范围查询 @ParameterizedTest @ValueSource(ints = {20}) public void testFindByAgeLessThan(int age) { List users = userDao.findByAgeLessThan(age); users.forEach(System.err::println); } //根据年龄区间进行范围查询 @ParameterizedTest @CsvSource({"15,20", "500,1000"}) public void testFindByAgeBetween(int startAge, int endAge) { List users = userDao.findByAgeBetween(startAge, endAge); users.forEach(System.err::println); } //@Query 查询 --->自己定义查询语句-----半自动===================================================================== //rowMapperClass 或 rowMapperRef 是用来做自定义映射,查询出来的User对象的数据,映射到Student对象的属性上面去都可以,因为是自定义的。 //根据密码模糊查询 @ParameterizedTest @ValueSource(strings = {"niu%", "%3"}) public void testFindBySql(String passwordPattern) { List users = userDao.findBySql(passwordPattern); users.forEach(System.err::println); } //根据年龄范围修改名字 @ParameterizedTest @CsvSource({"牛魔王aa,800,1000"}) @Transactional @Rollback(false) public void testUpdateNameByAge(String name, int startAge, int endAge) { int i = userDao.updateNameByAge(name, startAge, endAge); } //自己定义的接口,用来实现全手动的查询=================================================================================== //通过名字进行模糊查询,使用 dataSource @ParameterizedTest @ValueSource(strings = {"孙%"}) public void testCustomQueryUsingConnection(String namePattern) { List users = userDao.customQueryUsingConnection(namePattern); users.forEach(System.err::println); } //通过名字进行模糊查询,使用 jdbcTemplate @ParameterizedTest @ValueSource(strings = {"孙%"}) public void testCustomQueryUsingTemplate(String namePattern) { List users = userDao.customQueryUsingTemplate(namePattern); users.forEach(System.err::println); } } application.propertiesspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 pom.xml 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.5 cn.ljh Spring_Data_JDBC 1.0.0 Spring_Data_JDBC 11 org.springframework.boot spring-boot-starter-data-jdbc org.springframework.boot spring-boot-devtools runtime true mysql mysql-connector-java runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok

🎈 相关推荐

用手机号就可以借钱的平台有哪些?无电话审核、无人脸识别、无视频验证
365体育投注软件下载

用手机号就可以借钱的平台有哪些?无电话审核、无人脸识别、无视频验证

📅 10-21 👀 2721
天龙八部唐门1体力等于多少血,天龙八部唐门一体力多少血
英国365网站正规吗

天龙八部唐门1体力等于多少血,天龙八部唐门一体力多少血

📅 10-08 👀 6948
身份证件类型怎么填写?正确填写身份证件类型的方法
英国365网站正规吗

身份证件类型怎么填写?正确填写身份证件类型的方法

📅 07-13 👀 3732