SpringDataJdbc的使用

命名查询

spring data jdbc最底层的接口是Repository

@Indexed
public interface Repository<T, ID> {
}

其次是CrudRepository,其继承Repository接口

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
//里面有很多定义好的方法
...
}

然后是PagingAndSortingRepository,其继承CrudRepository

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
//比CrudRepository多了分页和排序的方法
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}

第一种使用方法就是自定义Repository接口,继承PagingAndSortingRepository接口,然后可以使用其默认的实现好的方法,只要按照其规定好的方法格式,框架会帮我们生成sql语句,与数据库交互,例如:

@Repository
interface JobRepository extends PagingAndSortingRepository<Job, Long> {
	//根据工作id查询工作
  List<Job> findByJobId(long jobId);
}
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Table("job")
public class Job {
  private long jobId;
  private long name;
}

官网提供了一些其他的形象查询方法:

interface PersonRepository extends Repository<Person, Long> {

List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

// Enables the distinct flag for the query
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

// Enabling ignoring case for an individual property
List<Person> findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

// Enabling static ORDER BY for a query
List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

同时也支持嵌套属性的查询

List<Person> findByAddress_ZipCode(ZipCode zipCode);

同时除了我们传入的实体类的属性,Spring Data Jdbc还识别 Page , Sort 等参数

Page<User> findByLastname(String lastname, Pageable pageable);

Slice<User> findByLastname(String lastname, Pageable pageable);

List<User> findByLastname(String lastname, Sort sort);

List<User> findByLastname(String lastname, Pageable pageable);
Sort sort = Sort.by("firstname").ascending()
.and(Sort.by("lastname").descending());
//当然也可以这样,更加地安全
TypedSort<Person> person = Sort.sort(Person.class);
Sort sort = person.by(Person::getFirstname).ascending()
.and(person.by(Person::getLastname).descending());

Pageable pageable=PageRequest.of(1, 20)

甚至可以限制查询个数

Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);

Slice<User> findTop3ByLastname(String lastname, Pageable pageable);

List<User> findFirst10ByLastname(String lastname, Sort sort);

List<User> findTop10ByLastname(String lastname, Pageable pageable);

返回类型 Streamable Iterable Collections Stream可以自定义

//Streamable和StreamStream的区别在于Stream必须关闭
try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
stream.forEach();
}


Streamable<Person> result = repository.findByFirstnameContaining("av")
.and(repository.findByLastnameContaining("ea"));

空值的指定

import org.springframework.lang.Nullable;

interface UserRepository extends Repository<User, Long> {
//入参和返回值有一个为空,抛出异常IllegalArgumentException 
User getByEmailAddress(EmailAddress emailAddress);    
//入参和返回值均可以是null
@Nullable
User findByEmailAddress(@Nullable EmailAddress emailAdress);
//没有查询到返回Optional.empty(),但是入参为空时抛出异常IllegalArgumentException 
Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress); 
}

异步返回结果

@Async
Future<User> findByFirstname(String firstname);               

@Async
CompletableFuture<User> findOneByFirstname(String firstname); 

@Async
ListenableFuture<User> findOneByLastname(String lastname); 

@Query注解

优先注解查询,没有注解去找命名查询。

interface UserRepository extends CrudRepository<User, Long> {

  @Query("select firstName, lastName from User u where u.emailAddress = :email")
  User findByEmailAddress(@Param("email") String email);
}

//可以使用 @Modifying on 查询方法将查询标记为修改查询,如以下示例所示
@Modifying
@Query("UPDATE DUMMYENTITY SET name = :name WHERE id = :id")
boolean updateName(@Param("id") Long id, @Param("name") String name);

jdbcTempalte

参考文章(https://www.cnblogs.com/wenxuehai/p/14716372.html)

介绍

JdbcTemplate 是 Spring 对 JDBC 的封装,目的是使JDBC更加易于使用,JdbcTemplate是Spring的一部分。JdbcTemplate 处理了资源的建立和释放,它帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果即可。

Spring为了简化数据库访问,主要做了以下几点工作:

  • 提供了简化的访问JDBC的模板类,不必手动释放资源;
  • 提供了一个统一的 DAO 类以实现 Data Access Object 模式;
  • SQLException封装为DataAccessException,这个异常是一个RuntimeException,并且让我们能区分SQL异常的原因,例如,DuplicateKeyException表示违反了一个唯一约束;
  • 能方便地集成Hibernate、JPA和MyBatis这些数据库访问框架。
常用方法

jdbcTemplate主要提供的5类方法及使用:

(1)execute() 方法:可以执行任何SQL语句,一般用于执行DDL语句。

(2)update(sqlStr, 参数列表) 方法:用于执行新增、修改、删除等语句。

(3)batchUpdate() 方法:用于执行批处理相关语句,batchUpdate方法第二参数是一个元素为 Object[] 数组类型的 List 集合。

(4)query() 方法及 queryForXXX() 方法:用于执行查询相关语句,查询结果为基本数据类型或者是单个对象一般使用 queryForObject()

  • queryForInt():查询一行数据并返回 int 型结果。例子:jdbcTemplate.queryForInt(“select count(*) from user”)
  • queryForObject(sqlStr, 指定的数据类型, 参数列表):查询一行任何类型的数据,最后一个参数指定返回结果类型。例子:jdbcTemplate.queryForObject(“selct count(*) from user”, Integer.class)
  • queryForMap(sqlStr, 参数列表):查询一行数据并将该行数据转换为 Map 返回。将会将列名作为key,列值作为 value 封装成 map。当查询出来的行数大于1时会报错。例子:jdbcTemplate.queryForMap(“select * from user where username = ?”, “aaa”);``
  • List<Map<String, Object>> queryForList(sqlStr, 参数列表):将查询结果集封装为 list 集合,该集合的每一条元素都是一个 map。
  • query(sqlStr, RowMapper对象, 参数列表):查询多行数据,并将结果集封装为元素是 JavaBean 的 list。(注意,指定的JavaBean的属性最好不要是基本类型,因为查询出来的结果可能是null,而null赋值为基本数据类型将会报错。比如int最好定义为Integer)

(5)call() 方法:用于执行存储过程、函数相关语句。

具体方法介绍
//单个新增
@Repository
public class UserDaoImpl implements UserDao{
    //注入JdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public void addUser(User user) {
        //创建SQL语句
        String sql = "insert into user values(?, ?, ?)";
        //调用方法执行SQL
        int updateRow = jdbcTemplate.update(sql, user.getId(), user.getName(), user.getPassword());
        
        System.out.println(updateRow);
    }
}

//批量新增
@Repository
public class UserDaoImpl implements UserDao {
    //注入JdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public void addBath(List<Object[]> userList) {
        String sql = "insert into user values(?, ?, ?)";
       /*
        List<Object[]> userList = new ArrayList<>();
        Object[] arr1 = {1, "name1", "password1"};
        Object[] arr2 = {2, "name2", "password2"};
        Object[] arr3 = {3, "name3", "password3"};
        userList.add(arr1);
        userList.add(arr2);
        userList.add(arr3);
       */
        int[] ints = jdbcTemplate.batchUpdate(sql, userList);  //batchUpdate方法第二个参数是集合,该集合元素是数组,数组里面的每个值对应着添加到数据库表里面的字段值。该方法返回影响行数数组
        System.out.println(Arrays.toString(ints));
    }
}

改删
//单个修改 删除
@Repository
public class UserDaoImpl implements UserDao{
    //注入JdbcTemplate
     @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public void updateUser(User user) {
        String sql = "update user set name=?, password=? where id=?";
        int updateRow = jdbcTemplate.update(sql, user.getName(), user.getPassword(), user.getId());
        System.out.println(updateRow);
    }
    @Override
    public void deleteUser(int userId) {
        String sql = "delete from user where id=?";
        int updateRow = jdbcTemplate.update(sql, userId);
        System.out.println(updateRow);
    }
}

//批量修改 删除

@Repository
public class UserDaoImpl implements UserDao {
    //注入JdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //批量修改
    @Override
    public void updateBatch(List<Object[]> listArg) {
        String sql = "update user set name=?, password=? where id=?";
        /*
        List<Object[]> userList = new ArrayList<>();
        Object[] arr1 = {1, "name1", "password1"};
        Object[] arr2 = {2, "name2", "password2"};
        Object[] arr3 = {3, "name3", "password3"};
        userList.add(arr1);
        userList.add(arr2);
        userList.add(arr3);
  */
        int[] ints = jdbcTemplate.batchUpdate(sql, listArg);
        System.out.println(Arrays.toString(ints));
    }
    //批量删除
    @Override
    public void deleteBath(List<Object[]> listArg) {
        String sql = "delete from user where id=?";
        /*
        List<Object[]> userList = new ArrayList<>();
        Object[] arr1 = {6};
        Object[] arr2 = {7};
        userList.add(arr1);
        userList.add(arr2);
        */
        int[] ints = jdbcTemplate.batchUpdate(sql, listArg);
        System.out.println(Arrays.toString(ints));
    }
}

查询

queryForObject (sqlStr, 指定的数据类型, 参数列表):查询一行任何类型的数据,最后一个参数指定返回结果类型。

@Repository
public class UserDaoImpl implements UserDao{
    //注入JdbcTemplate
     @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public int getUserCount() {
        String sql = "select count(*) from user";
        int userCount = jdbcTemplate.queryForObject(sql, int.class);  //第二个参数是返回类型的class
        return userCount;
    }
}

@Repository
public class UserDaoImpl implements UserDao{
    //注入JdbcTemplate
     @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public User getUserInfo(int userId) {
        String sql = "select * from user where id=?";
        // rowMapper 是一个接口,可以使用这个接口里面的实现类完成数据的封装,规定每一行记录和JavaBean的属性如何映射
        User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), userId);
        return user;
    }
}

query (sqlStr, RowMapper对象, 参数列表):查询多行数据,并将结果集封装为元素是 JavaBean 的 list。(注意,指定的 JavaBean 的属性最好不要是基本类型,因为查询出来的结果可能是null,而null赋值为基本数据类型将会报错。比如int最好定义为Integer)

@Repository
public class UserDaoImpl implements UserDao{
    //注入JdbcTemplate
     @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public List<User> getAllUser() {
        String sql = "select * from user";
        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
        return userList;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值