目录:
本文主要记录下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装配好的dataSource System.out.println(dataSource.getConnection().getCatalog()); // System.out.println(dataSource.getDataUsername()); }
如下图: 显示已经获取了springboot2默认的数据源和我们自建的mysql的数据库名称为springboot
以上操作,springboot会自动装配好DataSource,JdbcTemplate可以直接使用。
3.测试mysql的新增数据
@Repository public class ProductDao { @Autowired private 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> 1
同时排除默认的数据源
<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 { @Autowired private Environment env; @Bean public 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.HikariDataSource System.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 { @Autowired private JdbcTemplate jdbcTemplate; @Transactional public 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 { @Autowired private JdbcTemplate jdbcTemplate; @Transactional 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(); } } } }
@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 { @Autowired private 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种,如何切换内置的数据源,定义自己的数据源,和事务的相关使用和注意事项。