1. 使用JdbcTemplate之前的准备
为了能使用JdbcTemplate,添加JDBC starter 依赖。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
对于开发和测试来说,嵌入式的数据库就足够了,Spring Boot提供自动配置的嵌入式数据库有H2、HSQL、Derby,你不需要提供任何连接配置就能使用。比如使用H2嵌入数据库。
<dependency>
<groupId>com.h2databasegroupId>
<artifactId>h2artifactId>
<scope>runtimescope>
dependency>
连接生产数据源,一般用于生产环境,以MySQL为例,先引入MySQl依赖包
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
然后再在 src/main/resources/application.properties 或者src/main/resources/application.yml 路径下配置数据源信息
spring.datasource.url=jdbc:mysql://localhost:3306/数据库名
spring.datasource.username=root
spring.datasource.password=密码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
注意:因为Spring Boot 2.1.x默认使用了MySQL 8.0的驱动,所以这里用com.mysql.cj.jdbc.Driver,而不是com.mysql.jdbc.Driver。
通过举一个例子来介绍吧。看完这个例子,使用JdbcTempla操作数据库对你来说就just so so了
1.首先数据库的准备
ingredients表,
dumping表,主键自动递增
和dumping_ingredients表(将dumping与之相关的配料映射在一起)
外键约束
2.编写领域对象
@Data
@RequiredArgsConstructor
public class Ingredients {
private final String id;
private final String name;
private final String type;
}
@Data
public class Dumping {
private Long id;
private String name;
private String place;
private List<Ingredients> ingredients;
}
3.定义JDBC repository
public interface IngredientsRepository {
// 查询所有的配料信息,将它们放到一个Ingredients对象集合中
List<Ingredients> findAll();
// 根据id查询单个ingredients
Ingredients findOne(String id);
// 保存Ingredients对象
Ingredients save(Ingredients ingredients);
}
@Repository //spring的组件扫描到,并会将其初始化spring应用上下文的bean
public class JdbcIngredientsRepository implements IngredientsRepository{
private JdbcTemplate jdbc;
@Autowired //通过@Autowired标注的构造器将JdbcTemplate注入进来
public JdbcIngredientsRepository(JdbcTemplate jdbc){
this.jdbc = jdbc;
}
}
下面就是实现查找所有和查找id的方法
@Override
public List<Ingredients> findAll() {
return jdbc.query("select * from Ingredients",this::mapRowToIngredients);
}
@Override
public Ingredients findOne(String id) {
Ingredients ingredients = jdbc.queryForObject("select * from Ingredients where id = ?",
this::mapRowToIngredients,id);
return ingredients;
}
private Ingredients mapRowToIngredients(ResultSet rs, int rowNum) throws SQLException {
return new Ingredients(
rs.getString("id"),
rs.getString("name"),
rs.getString("type"));
}
接下来就先讲解一下上面的方法。findAll()方法放回一个对象集合,使用JdbcTemplate的query()方法,接受要执行的SQL语句以及Spring RowMapper的一个实现类(用来将查询的结果集的每行数据映射为一个对象)。:: 是java8的新特性——方法引用。简单介绍一下:当用lambda表达式去创建一个函数式接口对象时,当lambda体已经有实现的方法了,就可以用。方法引用
findOne()使用了queryForObject()方法,返回一个对象,id会替换查询中的“?”
mapRowToIngredients()方法就是将结果集rs中的第rowNum行生成一个Ingredients对象,rowNum会从0开始到结果集的最后一行。
再看看保存(插入)数据的代码
@Override
public Ingredients save(Ingredients ingredients) {
jdbc.update(
"insert into Ingredients(id,name,type) values (?,?,?)",
ingredients.getId(),
ingredients.getName(),
ingredients.getType()
);
return ingredients;
}
JdbcTemplate的update()方法用来执行向数据库中写入或更新数据的查询语句。
它只需要一个包含带执行SQL,和每个查询参数对应的值即可。
@Controller
@RequestMapping("/query")
public class DumpController {
private final IngredientsRepository ingredientsRepo;
@Autowired
private DumpController(IngredientsRepository ingredientsRepo){
this.ingredientsRepo = ingredientsRepo;
}
@GetMapping
@ResponseBody
public Ingredients findOne(@RequestParam("id")String id){
return ingredientsRepo.findOne(id);
}
@CrossOrigin(origins = "*",maxAge = 3600)
@GetMapping("/all")
@ResponseBody
public List<Ingredients> findAll(){
return ingredientsRepo.findAll();
}
}
@GetMapping标注在方法上表示该方法用来处理get请求,@ResponseBody表示该方法的结果直接写入Http响应体中。@RequestParam(“id”)表示请求的参数“id”的数据映射到后面的参数id上。
因为有时前端的应用程序将会运行在与API相互独立的主机或者端口上,web浏览器会阻止消费该API,可以在服务器添加CORS(Cross-Origin Resource Sharing,跨域资源共享)。