@Configuration @ConditionalOnClass({DataSource.class, JdbcTemplate.class}) @ConditionalOnSingleCandidate(DataSource.class) @AutoConfigureAfter({DataSourceAutoConfiguration.class}) @EnableConfigurationProperties({JdbcProperties.class}) public class JdbcTemplateAutoConfiguration { ...... @Configuration static class JdbcTemplateConfiguration { private final DataSource dataSource; private final JdbcProperties properties;
@Repository public class BookDao { @Autowired private JdbcTemplate jdbcTemplate; //增加 public int addBook(Book book){ String sql = "insert into book(name,author)values(?,?)"; //result为执行结果,也就是受影响的行数 int result = jdbcTemplate.update(sql,book.getName(),book.getAuthor()); return result; } //删除 public int deleteBookById(Integer id){ String sql = "delete from book where id= ?"; //result为执行结果,也就是受影响的行数 int result = jdbcTemplate.update(sql,id); return result; } //修改 public int updateBook(Book book){ String sql = "update book set name=?,author=? where id=?"; //result为执行结果,也就是受影响的行数 int result = jdbcTemplate.update(sql,book.getName(),book.getAuthor(),book.getId()); return result; } //根据id查询 public Book findBookById(Integer id){ String sql = "select * from book where id=?"; List<Book> lists= jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Book.class),id); return lists.get(0); } //全查询 public List<Book> findBook(){ String sql = "select * from book"; List<Book> lists = jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Book.class)); return lists; } }
@Mapper public interface BookMapper { //增加 int addBook(Book book); //删除 int deleteBookById(Integer id); //修改 int updateBook(Book book); //根据id查询 Book findBookById(Integer id); //全查询 List<Book> findBook(); }
@RestController @RequestMapping("/mybatis") public class MybatisBookController { @Autowired private MybatisBookService mybatisBookService; @GetMapping("/bookOps") public void bookOps(){ //演示增加方法 Book book1 = new Book(); book1.setName("三国演义"); book1.setAuthor("罗贯中"); int addResult = mybatisBookService.addBook(book1); System.out.println("addBook>>>>>> "+addResult);
//演示修改方法 Book book2 = new Book(); book2.setId(1); book2.setName("水浒传"); book2.setAuthor("施耐庵"); int updateResult = mybatisBookService.updateBook(book2); System.out.println("updateBook>>>>>> "+updateResult);
//演示根据id查询方法 Book book3 = mybatisBookService.findBookById(3); System.out.println("findBookById>>>>>> "+book3);
//演示删除方法 int deleteResult = mybatisBookService.deleteBookById(3); System.out.println("deleteBookById>>>>>> "+deleteResult);
Spring Data是Spring的一个子项目,致力于简化数据库访问,通过规范的方法来分析开发者的意图,进而减少数据库访问层的代码量。Spring Data不仅支持关系型数据库,也支持非关系型数据库。Spring Data JPA可以有效的简化关系型数据库访问代码。SpringBoot整合Spring Data JPA的步骤如下:
第一步,创建数据库,不创建数据表。请注意使用Spring Data JPA只需要创建数据库,无需创建数据表,使用下述代码来创建一个名为jpa的数据库:
1 2
drop database if exists jpa; create database jpa default character set utf8;
/**里面有两个参数,第一个是数据库的实体类名称,第二个是id的类型**/ public interface BookDao extends JpaRepository<Book,Integer> { List<Book> getBooksByAuthorStartingWith(String author); List<Book> getBooksByPriceGreaterThan(Float price); @Query(value = "select * from t_book where id =(select max(id) from t_book)",nativeQuery = true) Book getMaxIdBook(); @Query(value = "select b from t_book b where b.id>:id and b.author=:author") List<Book> getBookByIdAndAuthor(@Param("author")String author,@Param("id")Integer id); @Query(value = "select b from t_book b where b.id<?2 and b.name like %?1%") List<Book> getBooksByIdAndName(String name,Integer id); }
在Spring Data JPA中,只要方法的定义符合既定的规范,Spring Data就能分析出开发者的意图,从而避免开发者自己定义SQL。所谓的既定规范其实就是一定的方法命名规则。支持的命名规则如下表所示:
关键词
方法名称举例
对应的SQL
And
findByNameAndAge
where name=? and age=?
Or
findByNameOrAge
where name=? or age=?
Is
findByAgeIs
where age = ?
Equals
findByIdEquals
where id = ?
Between
finfByAgeBetween
where age between ? and ?
LessThan
finfByAgeLessThan
where age < ?
LessThanEquals
finfByAgeLessThanEquals
where age <= ?
GreaterThan
finfByAgeGreaterThan
where age > ?
GreaterThanEquals
finfByAgeGreaterThanEquals
where age >= ?
After
findByAgeAfter
where age > ?
Before
findByAgeBefore
where age < ?
IsNull
findByNameIsNull
where name is null
IsNotNull/NotNull
findByNameIsNotNull
where name is not null
Not
findByGenderNot
where gender <> ?
In
findByAgeIn
where age in (?)
NotIn
findByAgeNotIn
where age not in (?)
NotLike
findByNameNotLike
where name not like ?
Like
findByNameLike
where name like ?
StartingWith
findByNameStartingWith
where name like ‘?%’
EndingWith
findByNameEndingWith
where name like ‘%?’
Containing/Contains
findByNameContaining
where name like ‘%?%’
OrderBy
findByAgeGreaterThanOrderByIdDesc
where age >? order by id desc
True
findByEnabledTrue
where enabled = true
False
findByEnabledFalse
where enabled = false
IgnoreCase
findByNameIgnoreCase
where UPPER(name)=UPPER(?)
解释一下上述代码的含义:
上述就是既定的方法命令规则,当然如果不满足开发者需求,Spring Data JPA也是支持自定义JPQL(Java Persistence Query Language)或者原生的SQL。在BookDao接口中,笔者定义了getMaxIdBook方法,并在上面使用@Query注解,并书写了一行sql语句用于查询id最大的书,请注意此处的sql由于是原生SQL,因此后面需要使用nativeQuery = true进行指明。
getBookByIdAndAuthor方法用于根据id和author来查询书籍信息,这里使用了默认的JPQL语句。JPQL是一种面向对象表达式语言,可以将SQL语法和简单查询语义绑定在一起,使用这种语言编写的查询是可以移植的,可以被编译成所有主流数据库服务器上的SQL。JPQL与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性(如果开发者之前用过Hibernate可能觉得这里的JPQL类似于HQL)。在该条JPQL语句中select b from t_book b where b.id>:id and b.author=:author,使用:id和:author这种方式来进行参数绑定。注意这里使用的列名是实体类的属性名,而不是数据库中数据表列的名称。
@GetMapping("/search") public void search(){ List<Book> books1 = bookService.getBookByIdAndAuthor("鲁迅",5); List<Book> books2 = bookService.getBooksByAuthorStartingWith("吴"); List<Book> books3 = bookService.getBooksByIdAndName("水",6); List<Book> books4 = bookService.getBooksByPriceGreaterThan(160F); Book book = bookService.getMaxIdBook(); log.info("【getBookByIdAndAuthor】books1={}",books1); log.info("【getBooksByAuthorStartingWith】books2={}",books2); log.info("【getBooksByIdAndName】books3={}",books3); log.info("【getBooksByPriceGreaterThan】books4={}",books4); log.info("【getMaxIdBook】book={}",book); }
@GetMapping("/save") public void save(){ Book book = new Book(); book.setName("彷徨"); book.setAuthor("鲁迅"); book.setPrice(118F); book.setDescription("一本让人精神抖擞的良书。"); bookService.addBook(book); } }
第八步,运行项目,并新增测试数据。运行项目,并在数据库中新增以下测试数据:
1
insert into t_book(book_name,author,price)values("红楼梦","曹雪芹",188),("西游记","吴承恩",168),("三国演义","罗贯中",158),("水浒传","施耐庵",148),("狂人日记","鲁迅",138),("且介亭文集","鲁迅",128);