一. JdbcTemplate
-
JdbcTemplate简介
Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。 -
JdbcTemplate 的引入
在pom.xml文件中引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
连接mysql数据
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
在src/main/resources/application.properties中配置数据源信息
datasource:
url: jdbc:mysql://localhost:3306/spring_boot_student
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
- 使用JdbcTemplate操作数据库
通过JdbcTemplate实现UserService中定义的数据访问操作
package com.springboot.student.service.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class UserJdbcService {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 新增一个用户
* @param name
* @param age
*/
public void create(String name, Integer age) {
jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age);
}
/**
* 根据姓名删除用户
* @param name
*/
public void deleteByName(String name) {
jdbcTemplate.update("delete from USER where NAME = ?", name);
}
/**
* 查询用户数量
* @return
*/
public Integer getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class);
}
/**
* 删除所有用户
*/
public void deleteAllUsers() {
jdbcTemplate.update("delete from USER");
}
}
创建对UserService的单元测试用例,通过创建、删除和查询来验证数据库操作的正确性。
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTests {
@Autowired
private UserService userSerivce;
@Before
public void setUp() {
// 准备,清空user表
userSerivce.deleteAllUsers();
}
@Test
public void test() throws Exception {
// 插入5个用户
userSerivce.create("a", 1);
userSerivce.create("b", 2);
userSerivce.create("c", 3);
userSerivce.create("d", 4);
userSerivce.create("e", 5);
// 查数据库,应该有5个用户
Assert.assertEquals(5, userSerivce.getAllUsers().intValue());
// 删除两个用户
userSerivce.deleteByName("a");
userSerivce.deleteByName("e");
// 查数据库,应该有5个用户
Assert.assertEquals(3, userSerivce.getAllUsers().intValue());
}
}
二.spring-boot-starter-data-jpa
- 首先了解JPA是什么?
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。从目前的开发社区的反应上看,JPA受到了极大的支持和赞扬,其中就包括了Spring与EJB3.0的开发团队。
注意:JPA是一套规范,不是一套产品,那么像Hibernate,TopLink,JDO他们是一套产品,
如果说这些产品实现了这个JPA规范,那么我们就可以叫他们为JPA的实现产品。
- spring data jpa
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!
spring data jpa让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现
-
基本查询
基本查询也分为两种,一种是spring data默认已经实现,一种是根据查询的方法来自动解析成SQL。
预先生成方法
spring data jpa 默认预先生成了一些基本的CURD的方法,例如:增、删、改等等1 继承JpaRepository
public interface UserRepository extends JpaRepository<User, Long> { }
使用JpaRepository 默认实现的 方法
@Test public void testBaseQuery() throws Exception { User user=new User(); userRepository.findAll(); userRepository.findOne(1l); //有的小伙伴用这个方法 会报错 noSession 下面会说到 userRepository.save(user); userRepository.delete(user); userRepository.count(); userRepository.exists(1l); // ... }
用findOne(Long long) 方法报错的小伙伴 看这里:
JpaRepository 部分底层 使用 hibernate 来实现 而hibernate 默认懒加载
需要在application.yml 中 配置 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true -
自定义简单查询
自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy 后面跟属性名称:
下面是一些我的实例:JpaRepository
package com.springboot.student.domain.user.dao; import com.springboot.student.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Component; import java.util.List; @Component public interface UserRepository extends JpaRepository<User, Long> { //通过ID查询 public User findUsrById(Long id); //通过姓名like查询 像的 public List<User> findAllByNameLike(String name); //通过姓名like查询 不像的 public List<User> findAllByNameNotLike(String name); //通过姓名like查询 name开头的 public List<User> findAllByNameStartingWith(String name); //通过姓名like查询 name结尾 public List<User> findAllByNameEndingWith(String name); //查询年龄 小于等于 age的 public List<User> findAllByAgeLessThanEqual(Integer age); //查询年龄 大于等于 age的 public List<User> findAllByAgeGreaterThanEqual(Integer age); //查询年龄在 max和min之间的 public List<User> findAllByAgeBetween(Integer min,Integer max); //查年龄小于 age 岁 姓名 like name 的 并且money大于money public List<User> findAllByAgeLessThanAndNameLikeAndMoneyGreaterThan(Integer age,String name,Double money); /* @Query("SELECT SUM(u.money) FROM user u") public Object sumMoney();*/ }
UserApplicationTests
package com.springboot.student; import com.springboot.student.domain.user.dao.UserRepository; import com.springboot.student.domain.user.entity.User; import com.springboot.student.service.user.UserJdbcService; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Optional; @SpringBootTest @RunWith(SpringRunner.class) public class UserApplicationTests { @Autowired private UserRepository userRepository; @Test public void findAllByAgeLessThanAndNameLikeAndMoneyGreaterThan(){ userRepository.findAllByAgeLessThanAndNameLikeAndMoneyGreaterThan(50,"%F%",500.0) .forEach(user -> System.out.println("满足条件的人的姓名-------------"+user.getName())); } @Test public void update(){ User u = new User("小杨同学..",20,"男",9999.9); u.setId(50L); userRepository.save(u); } @Test public void addUser(){ User u = new User("小杨同学..",20,"男",9999.9); userRepository.save(u); } @Test public void deleteUser(){ userRepository.deleteById(53L); } @Test public void getUserByAge(){ { userRepository.findAllByAgeLessThanEqual(50).forEach(user -> System.out.println("小于等于 50 的年纪"+user.getAge())); userRepository.findAllByAgeGreaterThanEqual(50).forEach(user -> System.out.println("大于等于 50 的年纪"+user.getAge())); } { userRepository.findAllByAgeBetween(50,100).forEach(user -> System.out.println("年龄 age 在两个年龄之间的年龄"+user.getAge())); } } @Test public void getUserByNameLike(){ // 2.通过姓名like查询 { userRepository.findAllByNameNotLike("%F%").forEach(user -> System.out.println("不像%F%的名字---"+user.getName())); userRepository.findAllByNameLike("%F%").forEach(user -> System.out.println("像%F%的名字---"+user.getName())); userRepository.findAllByNameNotLike("F").forEach(user -> System.out.println("不像F的名字---"+user.getName())); userRepository.findAllByNameLike("F").forEach(user -> System.out.println("像F的名字---"+user.getName())); } { /** * 即使申明了 StartingWith 当参数是 %value%时 还是变成了 全模糊匹配 * 如下 userRepository.findByNameStartingWith("%B%") 就查询出了 FBFF */ userRepository.findAllByNameStartingWith("%B%").forEach(user -> System.out.println("开头的"+user.getName())); userRepository.findAllByNameEndingWith("C").forEach(user -> System.out.println("结尾的--"+user.getName())); } } @Test public void getUserById() {// 1.通过ID查询 { System.out.println(userRepository.getOne(50L).getName()); } { System.out.println(userRepository.findUsrById(500L)); } { Optional<User> optionalUser = userRepository.findById(500L); if(optionalUser.isPresent()){//返回true代表值 User user = optionalUser.get(); System.out.println("查到用户的姓名是!!!"+user.getName()); }else{//返回false表示没有值 System.out.println("没查到用户相关信息!"); } } } }
这里值得注意的是: Like查询 匹配前半部分 或者 匹配后半部分 或者是 全匹配 运行通过传入的参数 前后加%来决定
即使声明了 StartingWith EndingWith 如果传入的参数带有 %% 也会以%为准最后
希望有熟悉spring-boot-starter-data-jpa的大佬 提供一下 对 聚合函数的支持和用法 还有一些动态查询的用法实例.感激不尽