大家好,欢迎来到IT知识分享网。
从今天起我们将开始学习SpringBoot数据篇,本篇将讲解整合MySQL、整合JDBCTemplate、整合Durid方面的内容。
整合MySQL
在整合MySQL之前,我们首先要清楚两个问题:
什么是JDBC?
JDBC(JavaDataBaseConnectivity),用于执行SQL语句的JavaApi。我们本文主要讲的是SpringJDBC,它是对于JDBC的封装,让我们使用JDBC时更加简单方便快捷。
什么是持久层?
持久层(PersistenceLayer),对数据进行持久化操作(例:将数据保存到数据库的操作),把数据保存起来或者把持久状态的数据查询出来。(有关于以上操作的代码都是持久层代码)
SpringJDBC集成
首先我们在pom.xml文件中导入maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>复制代码类型:[java]
之后我们在application.yml中添加数据源配置:
datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/Family?serverTimezone=GMT%2b8&characterEncoding=utf-8 username: root password: 复制代码类型:[java]
在数据库中创建pets表:
/* Navicat Premium Data Transfer Source Server : javafamily Source Server Type : MySQL Source Server Version : 50729 Source Host : localhost:3306 Source Schema : Family Target Server Type : MySQL Target Server Version : 50729 File Encoding : 65001 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for pets -- ---------------------------- DROP TABLE IF EXISTS `pets`; CREATE TABLE `pets` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, `varieties` varchar(32) NOT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='宠物'; SET FOREIGN_KEY_CHECKS = 1;复制代码类型:[java]
我们在javafamily.familydemo文件下创建文件夹dao并在其中创建PetsDAO.class:
package com.javafamily.familydemo.dao; import com.javafamily.familydemo.model.Pets; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import javax.annotation.Resource; import java.util.List; // 表示当前类是持久层依赖注入的对象 @Repository public class PetsDAO { @Resource // 进行JDBC操作的模版类(由Spring JDBC提供) private JdbcTemplate jdbcTemplate; // 增加一只宠物的信息 public void save(Pets pets) { // jdbcTemplate.update适合于insert 、update和delete操作,不适合查询操作。 jdbcTemplate.update("INSERT INTO pets(name,varieties,create_time) values(?, ?, ?)", pets.getName(), pets.getVarieties(), pets.getCreateTime()); } // 删除一只宠物的信息 public void deleteById(Long id) { jdbcTemplate.update("DELETE FROM pets WHERE id = ?", id); } // 修改一只宠物信息 public void updateById(Pets pets) { jdbcTemplate.update("UPDATE pets SET name = ?,varieties = ?,create_time = ? WHERE id = ?", pets.getName(), pets.getVarieties(), pets.getCreateTime(), pets.getId()); } // 查找宠物信息,queryForObject:用于查询单条记录返回结果 public Pets searchById(Long id) { return (Pets) jdbcTemplate.queryForObject("SELECT * FROM pets WHERE id=?", new Object[]{id}, new BeanPropertyRowMapper<>(Pets.class)); } // 查询宠物信息,query:用于查询结果列表 public List<Pets> findAll() { return (List<Pets>) jdbcTemplate.query("SELECT * FROM pets ", new BeanPropertyRowMapper<>(Pets.class)); } }复制代码类型:[java]
在编写完Dao层的代码后,我们要思考一个问题,为什么服务端后端要采用分层开发?(controller:参数的接收和相应结果的返回。service:业务处理。repository:数据持久化以及查询相关的操作)
在比较简单的开发中,controller层是可以直接调用持久层(dao)的。但是这种方法不推荐使用,因为我们需要在service层控制事务。所以还是使用正常的调用顺序(controller->service->dao),进行分层开发。
所以下面我们来编写service层代码,我们对之前创建好的PetsService进行改造:
package com.javafamily.familydemo.service; import com.javafamily.familydemo.model.Pets; import java.util.List; public interface PetsService { String savePets(Pets pets); void deletePets(long id); void updatePets(Pets pets); Pets getPets(Long id); List<Pets> getAll(); }617复制代码类型:[java]
再修改一下之前的PetsServiceImpl:
package com.javafamily.familydemo.service; import com.javafamily.familydemo.dao.PetsDAO; import com.javafamily.familydemo.model.Pets; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class PetsServiceImpl implements PetsService { @Resource private PetsDAO petsDAO; @Override public void savePets(Pets pets) { petsDAO.save(pets); } @Override public void deletePets(long id) { petsDAO.deleteById(id); } @Override public void updatePets(Pets pets) { petsDAO.updateById(pets); } @Override public Pets getPets(Long id) { return petsDAO.searchById(id); } @Override public List<Pets> getAll() { return petsDAO.findAll(); }839复制代码类型:[java]
回到PetsController中进行修改:
package com.javafamily.familydemo.controller; import com.javafamily.familydemo.model.Customer; import com.javafamily.familydemo.model.Pets; import com.javafamily.familydemo.model.Response; import com.javafamily.familydemo.service.PetsService; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Date; import java.util.List; @Slf4j @RestController public class PetsController { @Resource PetsService petsService; // 根据id,查询一只宠物信息 @RequestMapping(value = "/pets/{id}", method = RequestMethod.GET) public Response getPets(@PathVariable("id") long id) { Pets pets = petsService.getPets(id); log.info("pets" + pets); return Response.success(pets); } @RequestMapping(value = "/pets", method = RequestMethod.POST) public Response savePets(@RequestBody Pets pets) { petsService.savePets(pets); log.info("savePets" + pets); return Response.success(); } // 修改一只宠物信息 @RequestMapping(value = "/pets", method = RequestMethod.PUT) public Response updatePets(@RequestBody Pets pets) { petsService.updatePets(pets); log.info("updatePets" + pets); return Response.success(pets); } // 根据id,删除一只宠物信息 @RequestMapping(value = "/pets/{id}", method = RequestMethod.DELETE) public Response deletePets(@PathVariable("id") Long id) { petsService.deletePets(id); log.info("deletePets" + id); return Response.success(); } // 查询所有宠物信息 @RequestMapping(value = "/pets", method = RequestMethod.GET) public Response getPets() { List<Pets> pets = petsService.getAll(); log.info("pets" + pets); return Response.success(pets); } }0复制代码类型:[java]
由于我们在创建数据库后没有在里面添加数据,所以在使用postman测试时data暂时显示为空。
这时向数据库中添加一条我们曾经测试过的数据:
最后删掉id为1的这条数据: 最后删掉id为1的这条数据:
数据被成功删除。
之后我们来看@Trasactional注解:它能够进行事务管理,保证方法一旦有异常,所有的数据库操作进行回滚(比如@Trasactional注解作用在修改方法上,当出现异常修改操作将不会进行,数据库中的数据不会发生任何改变)。
以上我们介绍的是单一数据源的配置与实现,随着数据的增多,我们会逐渐使用数据分库存储的方案,那么在持久层中一个服务要操作多个数据库,那么该如何实现呢?下面我们来介绍多数据源的实现。
JDBCTemplate实现多数据源
spring: datasource: family: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/Family?serverTimezone=GMT%2b8&characterEncoding=utf-8 username: root password: family2: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/Family2?serverTimezone=GMT%2b8&characterEncoding=utf-8 username: root password: 复制代码类型:[java]
之后在config文件中创建DataSourceConfig.java:
package com.javafamily.familydemo.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceConfig { // 当一个接口有多个时候实现类的时候,如果Spring只能选一个实现进行依赖注入时,就选这个数据源(默认数据源) @Primary @Bean(name = "familyDataSource") @ConfigurationProperties(prefix = "spring.datasource.family") public DataSource familyDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "family2DataSource") @ConfigurationProperties(prefix = "spring.datasource.family2") public DataSource family2DataSource() { return DataSourceBuilder.create().build(); } } 72829复制代码类型:[java]
JDBCTemplate实现多数据源
在完成了图-多数据源配置的前两个步骤,我们要开始实现JDBCTemplate部分!
首先将petsDAO.class进行修改:
package com.javafamily.familydemo.dao; import com.javafamily.familydemo.model.Pets; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import javax.annotation.Resource; import java.util.List; // 表示当前类是持久层依赖注入的对象 @Repository public class PetsDAO { @Resource // 进行JDBC操作的模版类(由Spring JDBC提供) private JdbcTemplate familyJdbcTemplate; // 增加一只宠物的信息 public void save(Pets pets, JdbcTemplate jdbcTemplate) { if (jdbcTemplate == familyJdbcTemplate){ jdbcTemplate = familyJdbcTemplate; } // jdbcTemplate.update适合于insert 、update和delete操作,不适合查询操作。 jdbcTemplate.update("INSERT INTO pets(name,varieties,create_time) values(?, ?, ?)", pets.getName(), pets.getVarieties(), pets.getCreateTime()); } // 删除一只宠物的信息 public void deleteById(Long id,JdbcTemplate jdbcTemplate) { jdbcTemplate.update("DELETE FROM pets WHERE id = ?", id); } // 修改一只宠物信息 public void updateById(Pets pets, JdbcTemplate jdbcTemplate) { jdbcTemplate.update("UPDATE pets SET name = ?,varieties = ?,create_time = ? WHERE id = ?", pets.getName(), pets.getVarieties(), pets.getCreateTime(), pets.getId()); } // 查找宠物信息,queryForObject:用于查询单条记录返回结果 public Pets searchById(Long id,JdbcTemplate jdbcTemplate) { return (Pets) jdbcTemplate.queryForObject("SELECT * FROM pets WHERE id=?", new Object[]{id}, new BeanPropertyRowMapper<>(Pets.class)); } // 查询宠物信息,query:用于查询结果列表 public List<Pets> findAll(JdbcTemplate jdbcTemplate) { return (List<Pets>) jdbcTemplate.query("SELECT * FROM pets ", new BeanPropertyRowMapper<>(Pets.class)); } }55复制代码类型:[java]
familyJdbcTemplate使用familyDataSource数据源操作数据库Family。
family2JdbcTemplate使用family2DataSource数据源操作数据库Family2。
再对PetsServiceImpl.java进行完善:
package com.javafamily.familydemo.service; import com.javafamily.familydemo.dao.PetsDAO; import com.javafamily.familydemo.model.Pets; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class PetsServiceImpl implements PetsService { @Resource private PetsDAO petsDAO; @Resource private JdbcTemplate familyJdbcTemplate; @Resource private JdbcTemplate family2JdbcTemplate; @Override public void savePets(Pets pets) { petsDAO.save(pets, familyJdbcTemplate); petsDAO.save(pets, family2JdbcTemplate); } @Override public void deletePets(long id) { petsDAO.deleteById(id, null); } @Override public void updatePets(Pets pets) { petsDAO.updateById(pets, null); } @Override public Pets getPets(Long id) { return petsDAO.searchById(id, null); } @Override public List<Pets> getAll() { return petsDAO.findAll(null); } }复制代码类型:[java]
这时我们在数据库Family2中建立一个跟数据库Family中的一样的pets表,之后在postman中添加数据:
数据库Family和Family2中都会出现这条数据:
2中都会出现这条数据:
双数据源的配置和插入动作就完成了!
「链接」
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/48005.html