admin 管理员组

文章数量: 887007

springboot2原理实战(16)

文章目录

  • 目录:
  • 一、jdbc操作mysql
    • 1.加入数据库驱动
    • 2.加入配置在application.properties
    • 3.测试是否加入数据源
    • 3.测试mysql的新增数据
  • 二、数据源切换:
    • 1.springboot内置的数据源和默认的数据源是什么:
    • 2.springboot切换内置的数据源:
      • 方式1:jar包+配置文件配置实现
      • 方式2:通过排除+jar包
    • 2.配置自己的的数据源 阿里的druid。
      • 1)添加jar包
      • 2)配置方式注入数据源
      • 3)测试
  • 三、事务
    • 1.步骤:
    • 2.特别注意: 默认只会对运行时异常进行事务回滚,非运行时异常不会回滚事务。
    • 3.控制事务回滚策略
    • 4.特别注意2: 只对方法上加@Trancational的方法内的jdbc操作事务有效

目录:

本文主要记录下springboot

一、jdbc操作mysql

使用jdbc的话,前提示导入springboot的jdbc的jar

  <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency>

1.加入数据库驱动

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.45</version><scope>runtime</scope>
</dependency>

2.加入配置在application.properties

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456

3.测试是否加入数据源


@SpringBootApplication
public class Demo16Application {public static void main(String[] args) throws SQLException {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);DataSource dataSource= context.getBean(DataSource.class);System.out.println(dataSource);
//        System.out.println(context.getBean(DataSourceProperties.class));System.out.println(dataSource.getConnection());//打印出数据库名字 springboot装配好的dataSourceSystem.out.println(dataSource.getConnection().getCatalog());
//        System.out.println(dataSource.getDataUsername());}

如下图: 显示已经获取了springboot2默认的数据源和我们自建的mysql的数据库名称为springboot
以上操作,springboot会自动装配好DataSource,JdbcTemplate可以直接使用。

3.测试mysql的新增数据

@Repository
public class ProductDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public void addProduct(String name){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);}public void addProductBatch(String ... names) throws FileNotFoundException {for (String name: names){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);if("MP4".equals(name)){throw new FileNotFoundException();}}add(names);}public void add(String ... names){for (String name: names){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);if("MP4".equals(name)){throw new NullPointerException();}}}
}
@SpringBootApplication
public class Demo16Application {public static void main(String[] args) throws SQLException {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);System.out.println(context.getBean(JdbcTemplate.class));context.getBean(ProductDao.class).addProduct("TV");}}

查询数据库,显示数据已经加入:

二、数据源切换:

1.springboot内置的数据源和默认的数据源是什么:

springboot内置的数据源有5种,在DataSourceAutoConfiguration下:

spring2默认开启的是DataSourceConfiguration.Hikari.class的数据源,我们打印数据源看下:

@SpringBootApplication
public class Demo16Application {public static void main(String[] args) throws SQLException {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);DataSource dataSource= context.getBean(DataSource.class);System.out.println(dataSource);}

打印结果如下图:显示默认的是tomcat数据源:

2.springboot切换内置的数据源:

方式1:jar包+配置文件配置实现

pom中添加:

 <dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jdbc</artifactId></dependency>

我们可以使用:pring.datasource.type切换数据源:
在spring.properties下配置:

spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource

入口函数再次打印:

@SpringBootApplication
public class Demo16Application {public static void main(String[] args) throws SQLException {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);DataSource dataSource= context.getBean(DataSource.class);System.out.println(dataSource);System.out.println(context.getBean(DataSourceProperties.class));}}

如下图:显示数据源已经切换:

方式2:通过排除+jar包

pom中添加:

 <dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jdbc</artifactId></dependency>

同时排除默认的数据源

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId><exclusions><exclusion><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId></exclusion></exclusions>
</dependency>

运行测试:如下图,说明也切换成了tomcat数据源。

2.配置自己的的数据源 阿里的druid。

只要装配一个DataSource到spring容器中即可。

1)添加jar包

在pom中添加druid的jar包

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.20</version>
</dependency>

测试:
application.properties中写个数据库地址:

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456

2)配置方式注入数据源

@SpringBootConfiguration
public class DBConfiguration {@Autowiredprivate Environment env;@Beanpublic DataSource createDataSource(){DruidDataSource  ds = new DruidDataSource();ds.setUrl(env.getProperty("spring.datasource.url"));ds.setUsername(env.getProperty("spring.datasource.username"));ds.setPassword(env.getProperty("spring.datasource.password"));ds.setDriverClassName(env.getProperty("spring.datasource.driverClassName"));return ds;}
}

3)测试

入口函数中:

   public static void main(String[] args) throws SQLException {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);DataSource dataSource = context.getBean(DataSource.class);// 默认的数据源; class com.zaxxer.hikari.HikariDataSourceSystem.out.println(dataSource.getClass());context.close();}

运行结果如下:显示已经成为了我们自定义的数据源。

三、事务

springboot2使用事务的方式很简单:

1.步骤:

  • 1.在启动类上首先使用@@EnableTransactionManagement启用对事务的支持
  • 2.在需要使用事物的方法上面加上@Transactional
    举例说明:
@EnableTransactionManagement
@SpringBootApplication
public class Demo16Application {//测试事务public static void main4(String[] args) throws FileNotFoundException {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);System.out.println(context.getBean(JdbcTemplate.class));context.getBean(ProductDao.class).addProductBatch("TV","MP3","MP4");}}
@Repository
public class ProductDao {@Autowiredprivate JdbcTemplate jdbcTemplate;  @Transactionalpublic void addProductBatch(String ... names) {for (String name: names){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);if("MP4".equals(name)){throw new RuntimeException("异常");}}

可以看到当我们插入MP4应该全部回滚,看下是否能达到预期效果,运行入口函数。
看下数据库,有没有插入:

显示没有插入,说明事务成功。

2.特别注意: 默认只会对运行时异常进行事务回滚,非运行时异常不会回滚事务。

我们可以测试下:

@Repository
public class ProductDao {@Autowiredprivate JdbcTemplate jdbcTemplate;@Transactionalpublic void addProductBatch(String ... names) throws Exception {for (String name: names){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);if("MP4".equals(name)){throw new FileNotFoundException();}}}}
@EnableTransactionManagement
@SpringBootApplication
public class Demo16Application {//测试事务public static void main(String[] args) throws Exception {ConfigurableApplicationContext context = SpringApplication.run(Demo16Application.class, args);System.out.println(context.getBean(JdbcTemplate.class));context.getBean(ProductDao.class).addProductBatch("TV","MP3","MP4");}
}

结果显示插入了,说明配置的事务失效。

3.控制事务回滚策略

上面的注意我们看到了,事务默认值对运行时异常起作用,那么我们怎么让我们的异常都用上事务呢?

我们看下Transactional的源码:

transactionManager 对多数据源下情况下有效
rollbackFor设置那些异常进行回滚,默认是运行时异常
noRollbackFor 设置不对那些异常进行回滚,默认是非运行时异常

刚才的案例如果改成:

  @Transactional(rollbackFor = Exception.class)public void addProductBatch(String ... names) throws Exception {for (String name: names){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);if("MP4".equals(name)){throw new FileNotFoundException();}}}

删除掉数据,再测试下:

显示回滚正常了。

4.特别注意2: 只对方法上加@Trancational的方法内的jdbc操作事务有效

只对方法上加@Trancational的方法内的jdbc操作事务有效,调用子方法,子方法上有这个注释无效。
测试下:

@Repository
public class ProductDao {@Autowiredprivate JdbcTemplate jdbcTemplate;//直接调用的方法没加@Transactional注解,看下效果public void addProductBatch(String ... names) throws Exception {add(names);}@Transactional(rollbackFor = Exception.class)public void add(String ... names){for (String name: names){//注意有sql注入的风险String sql = "insert into product(name) values('"+name+"')";jdbcTemplate.execute(sql);if("MP4".equals(name)){throw new NullPointerException();}}}}

运行入口函数,然后看下数据库:

结果显示:事务失效,说明在直接调用jdbc操作数据库的方法上加@Transactional,事务才有效。


本篇主要围绕springboot2的jdbc展开讲了操作mysql,数据源的默认的5种,如何切换内置的数据源,定义自己的数据源,和事务的相关使用和注意事项。


个人微信公号:
搜索: 怒放de每一天
不定时推送相关文章,期待和大家一起成长!!


本文标签: springboot2原理实战(16)