SpringBoot整合持久层技术
整合jdbcTemplate
jdbctemplate是Spring提供的JDBC框架,利用AOP技术来解决直接使用jdbc带来的大量代码的繁杂问题
SpringBoot对JdbcTemplate的使用提供了一套自动化配置类:JdbcTemplateAutoConfiguration类,所以想要使用只需要提供JdbcTemplate的依赖和dataSource依赖即可
案例
1.pom.xml配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
2.配置数据库连接信息applicaion.properties
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql:///chapter05?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
3.创建JavaBean
public class Book {
private int id;
private String name;
private Double price;
//省略getter setter
}
4.创建持久层接口dao
jdbcTemplate 对于增删改都使用update方法
@Repository
public class BookDao {
//加入jdbc依赖后就可以直接注入使用
@Autowired
JdbcTemplate jdbcTemplate;
public int addBook(Book book){
return jdbcTemplate.update("insert into book(name,price) values(?,?)",book.getName(),book.getPrice());
}
public int updateBook(Book book){
return jdbcTemplate.update("update book set name = ? , price = ? where id = ?" , book.getName(),book.getPrice(),book.getId());
}
public int deleteBookByid(Integer id){
return jdbcTemplate.update("delete from book where id = ?",id);
}
public Book getBook(Integer id){
return jdbcTemplate.queryForObject("select * from book where id = ?" , new BeanPropertyRowMapper<>(Book.class) , id);
}
public List<Book> getAllBooks(){
return jdbcTemplate.query("select * from book",new BeanPropertyRowMapper<>(Book.class));
}
}
6.测试
@SpringBootTest
class JdbctemplateApplicationTests {
//注入service层
@Autowired
BookService bookService;
@Test
void contextLoads() {
Book book = new Book();
book.setId(1);
Book book1 = bookService.getBook(1);
System.out.println(book1.toString());
}
}
整合Mybaits
SpringBoot同样为Mybatis提供了自动化配置
案例
1.导入Mybatis依赖、数据库依赖、数据库连接池的依赖
2.配置数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
3.创建DAO接口
public interface BuserMapper {
List<Buser> getAllBuser();
}
4.创建对应mapper.xml文件
<mapper namespace="pljandsyx.top.mybatisdatasource.mapper.BuserMapper">
<select id="getAllBuser" resultType="pljandsyx.top.mybatisdatasource.Buser">
select * from t_buser
</select>
</mapper>
5.扫描mapper.xml文件
两种方法:
第一种:在每个mapper.xml文件里添加@Mapper注解
第二种:在启动类添加包扫描注解@MapperScan(basePackages=“pljandsyx.top.mybatisdatasource.mapper”)
6.测试
//注入依赖
@Autowired
BuserMapper buserMapper;
@Test
void contextLoads() {
List<Buser> allBuser = buserMapper.getAllBuser();
System.out.println(allBuser);
}
关于mapper.xml文件的位置:
1.如果放在java目录下,编译时是不会被扫描到的,尽管添加了@Mapper注解或者扫描注解
2.可以在resources目录创建与java目录相同的文件路径
3.如果硬要放在java目录,在pom.xml添加配置resource路径,如下
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!-- 当然也要告诉服务器resources也是我们的资源路径-->
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
4.如果要放在resources目录下的mapper目,在application.properties:
mybatis.mapper-locations=classpath:/mybatis/
整合SpringDataJPA
SpringDataJPA可以有效减少访问数据库的代码
案例
多数据源
多数据源就是在一个javaEE项目中才用了不同数据库实例中的多个库,或者说同一个数据库实例中多个不同的库,中间件可以完成,当然SpringBooot也可以完成
下面是三种配置方式
JDBCTemplate多数据源
1.导入相同依赖(jdbc依赖,mysql连接依赖,druid连接池依赖),创建两个数据库实例test1&test2
2.配置两个不同的数据源
#数据源1
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.url=jdbc:mysql:///localhost:3360/test1
spring.datasource.one.username=root
spring.datasource.one.password=root
#数据源2
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.url=jdbc:mysql:///localhost:3360/test2
spring.datasource.two.username=root
spring.datasource.two.password=root
因为提供了不同的数据源,所以就要自定义加载数据源配置以及提供两个不同的JdbcTemplate实例
3.配置datasource & jdbcTemplate
DataSourceConfig.class:
@Configuration
public class DataSourceConfig {
//因为在配置数据源的时候用了不同的前缀,所以要用类型安全的属性注入
//返回的Bean名称就是方法名
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
DataSource ds1(){
return DruidDataSourceBuilder.create().build();
}
//因为在配置数据源的时候用了不同的前缀,所以要用类型安全的属性注入
//返回的Bean名称就是方法名
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource ds2(){
return DruidDataSourceBuilder.create().build();
}
}
TemplateConfig.class:
@Configuration
public class TemplateConfig
{
//这里同样需要指定不用的数据源使用@Qualifier注解,指定对应的Bean,直接New返回一个加入dataSource为参数的JdbcTemplate
@Bean
JdbcTemplate jdbcTemplate1(@Qualifier(value = "ds1") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
//这里同样需要指定不用的数据源使用@Qualifier注解,指定对应的Bean,直接New返回一个加入dataSource为参数的JdbcTemplate
@Bean
JdbcTemplate jdbcTemplate2(@Qualifier(value = "ds2") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
4.测试
//这里要指定注入的不用JdbcTemplate,使用@Resource或者可以使用@AutoWired和@Qualfier组合
@Resource(name = "jdbcTemplate1")
JdbcTemplate jdbcTemplate1;
@Resource(name = "jdbcTemplate2")
JdbcTemplate jdbcTemplate2;
@Test
void contextLoads() {
Buser buser1 = jdbcTemplate1.queryForObject("select * from t_buser where id = 1", new BeanPropertyRowMapper<>(Buser.class));
System.out.println(buser1.toString());
Buser buser2 = jdbcTemplate2.queryForObject("select * from t_buser where id = 1", new BeanPropertyRowMapper<>(Buser.class));
System.out.println(buser2.toString());
}
Mybatis多数据源
1.导入依赖
2.配置数据源
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC
spring.datasource.one.username=root
spring.datasource.one.password=root
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC
spring.datasource.two.username=root
spring.datasource.two.password=root
@Configuration
public class DadaSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
DataSource dsone(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource dstwo(){
return DruidDataSourceBuilder.create().build();
}
}
3.配置SqlSessionFactory&SqlSessionTemplate
@Configuration
@MapperScan(basePackages = "pljandsyx.top.mybatisdatasource.mapper1", sqlSessionFactoryRef ="sqlSessionFactory1" , sqlSessionTemplateRef = "sqlSessionTemplate1")
public class MybatisConfigOne {
@Resource(name = "dsone")
DataSource dsone;
@Bean
SqlSessionFactory sqlSessionFactory1(){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
try{
sqlSessionFactoryBean.setDataSource(dsone);
return sqlSessionFactoryBean.getObject();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Bean
SqlSessionTemplate sqlSessionTemplate1(){
return new SqlSessionTemplate(sqlSessionFactory1());
}
}
@Configuration
@MapperScan(basePackages = "pljandsyx.top.mybatisdatasource.mapper2" ,sqlSessionTemplateRef = "sqlSessionTemplate2" ,sqlSessionFactoryRef ="sqlSessionFactory2")
public class MybatisConfigTwo {
@Resource(name = "dstwo")
DataSource dstwo;
@Bean
SqlSessionFactory sqlSessionFactory2(){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
try{
sqlSessionFactoryBean.setDataSource(dstwo);
return sqlSessionFactoryBean.getObject();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Bean
SqlSessionTemplate sqlSessionTemplate2(){
return new SqlSessionTemplate(sqlSessionFactory2());
}
}
4.创建接口以及对应xml文件
第一个
@Repository
public interface BuserMapper1 {
List<Buser> getAllBuser1();
}
<mapper namespace="pljandsyx.top.mybatisdatasource.mapper1.BuserMapper1">
<select id="getAllBuser1" resultType="pljandsyx.top.mybatisdatasource.Buser">
select * from t_buser
</select>
</mapper>
第二个
@Repository
public interface BuserMapper2 {
List<Buser> getAllBuser2();
}
<mapper namespace="pljandsyx.top.mybatisdatasource.mapper2.BuserMapper2">
<select id="getAllBuser2" resultType="pljandsyx.top.mybatisdatasource.Buser">
select * from t_buser
</select>
</mapper>
5.测试
@SpringBootTest
class MybatisdatasourceApplicationTests {
@Autowired
BuserMapper1 buserMapper1;
@Autowired
BuserMapper2 buserMapper2;
@Test
void contextLoads() {
List<Buser> allBuser1 = buserMapper1.getAllBuser1();
System.out.println(allBuser1);
List<Buser> allBuser2 = buserMapper2.getAllBuser2();
System.out.println(allBuser2);
}
}
最后这里有个疑问:
接口名称一定要跟xml文件名称一样吗?
当不一样时,找不到对应的方法,尽管xml文件里的namespace等都一一对应了;