1. 程式人生 > >Spring JdbcTemplate + transactionTemplate 簡單示例 (零配置)

Spring JdbcTemplate + transactionTemplate 簡單示例 (零配置)

jdbcTemplate簡介

  Spring對資料庫的操作在jdbc上面做了深層次的封裝,使用spring的注入功能,可以把DataSource註冊到JdbcTemplate之中。

  JdbcTemplate位於中。其全限定命名為org.springframework.jdbc.core.JdbcTemplate。要使用JdbcTemlate還需一個這個包包含了一下事務和異常控制。

JdbcTemplate主要提供以下五類方法:

  • execute方法:可以用於執行任何SQL語句,一般用於執行DDL語句;

  • update方法及batchUpdate方法:update方法用於執行新增、修改、刪除等語句;batchUpdate方法用於執行批處理相關語句;

  • query方法及queryForXXX方法:用於執行查詢相關語句;

  • call方法:用於執行儲存過程、函式相關語句。

 新增依賴 (spring-jdbc ,資料庫驅動,資料庫連線池)

 1         <!--MariaDB 資料庫驅動  -->
 2         <dependency>
 3             <groupId>org.mariadb.jdbc</groupId>
 4             <artifactId>mariadb-java-client</
artifactId> 5 <version>2.3.0</version> 6 </dependency> 7 8 <!--c3p0 資料庫連線池--> 9 <dependency> 10 <groupId>com.mchange</groupId> 11 <artifactId>c3p0</artifactId> 12 <version
>0.9.5.2</version> 13 </dependency> 14 15 <dependency> 16 <groupId>org.springframework</groupId> 17 <artifactId>spring-jdbc</artifactId> 18 <version>5.1.3.RELEASE</version> 19 </dependency>

檔案結構:

entity 包 類 程式碼

 1 package com.oukele.entity;
 2 
 3 public class User {
 4     private String userName;
 5     private String password;
 6 
 7     public User() {
 8     }
 9 
10     public User(String userName, String password) {
11         this.userName = userName;
12         this.password = password;
13     }
14 
15     public String getUserName() {
16         return userName;
17     }
18 
19     public void setUserName(String userName) {
20         this.userName = userName;
21     }
22 
23     public String getPassword() {
24         return password;
25     }
26 
27     public void setPassword(String password) {
28         this.password = password;
29     }
30 
31     @Override
32     public String toString() {
33         return "User{" +
34                 "userName='" + userName + '\'' +
35                 ", password='" + password + '\'' +
36                 '}';
37     }
38 }

jdbcTemplate包 各類 程式碼

JDBCTemplateConfig 類

 1 package com.oukele.jdbcTemplate;
 2 
 3 import com.mchange.v2.c3p0.ComboPooledDataSource;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.ComponentScan;
 6 import org.springframework.context.annotation.Configuration;
 7 import org.springframework.context.annotation.PropertySource;
 8 import org.springframework.core.env.Environment;
 9 import org.springframework.jdbc.core.JdbcTemplate;
10 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
11 import org.springframework.transaction.PlatformTransactionManager;
12 import org.springframework.transaction.support.TransactionTemplate;
13 
14 import javax.sql.DataSource;
15 import java.beans.PropertyVetoException;
16 
17 @Configuration
18 @PropertySource(value = "classpath:jdbc.properties")//載入資源
19 @ComponentScan(basePackages = "com.oukele.jdbcTemplate")//掃描 spring 註解
20 public class JDBCTemplateConfig {
21 
22     //資料來源
23     @Bean
24     DataSource dataSource(Environment env) throws PropertyVetoException {
25         ComboPooledDataSource dataSource = new ComboPooledDataSource();
26         dataSource.setDriverClass(env.getProperty("jdbc.driver"));
27         dataSource.setJdbcUrl(env.getProperty("jdbc.url"));
28         dataSource.setUser(env.getProperty("jdbc.user"));
29         dataSource.setPassword(env.getProperty("jdbc.password"));
30         return dataSource;
31     }
32     //jdbc 模板
33     @Bean
34     JdbcTemplate jdbcTemplate (DataSource dataSource){
35         return new JdbcTemplate(dataSource);
36     }
37     //事務管理器
38     @Bean
39     DataSourceTransactionManager transactionManager(DataSource dataSource){//事務管理
40         return new DataSourceTransactionManager(dataSource);
41     }
42     //事務模板
43     @Bean
44     TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager){
45         return new TransactionTemplate(platformTransactionManager);
46     }
47 
48 
49 
50 
51 
52 }

UserDao類

package com.oukele.jdbcTemplate;

import com.oukele.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;
import java.util.Map;

@Repository
public class UserDao {

    @Autowired
    private JdbcOperations jdbcOperations;
    @Autowired
    private TransactionTemplate transactionTemplate;

  
    public List<Map<String, Object>> getToList () {
        List<Map<String, Object>> maps = jdbcOperations.queryForList("select * from user");
        return maps;
    }

    public Map<String, Object> getToMap () {
        String sql = "select * from user where userName = ?";

        Map<String, Object> ret = jdbcOperations.queryForMap(sql, "oukele1");
        return ret;
    }

    public User getToUser () {
        String sql = "select * from user where userName = 'oukele'";

        User user = jdbcOperations.queryForObject(
                sql,
                (rs, rowNum) -> new User(rs.getString(1),rs.getString(2))
        );
        return user;
    }

    public int create(String userName, String password) {

        transactionTemplate.execute(status ->{
            String sql = "insert into user (userName, password) values (?, ?)";
            String sq2 = "insert into user (userName, passord) values (?, ?)";
            jdbcOperations.update(sq2,userName,password);
            return jdbcOperations.update(sql, userName, password);
        });
        return 0;
    }
}

Main類 (測試類)

 1 package com.oukele.jdbcTemplate;
 2 
 3 import com.oukele.entity.User;
 4 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 5 
 6 public class Main {
 7     public static void main(String[] args) {
 8         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JDBCTemplateConfig.class);
 9         UserDao dao = context.getBean(UserDao.class);
10 
11         System.out.println("------------------------- List -------------------------");
12         System.out.println(dao.getToList());
13         System.out.println("-------------------------鍵值對應-------------------------");
14         System.out.println(dao.getToMap());
15         System.out.println();
16         User user = dao.getToUser();
17         System.out.println(user);
18         System.out.println("-------------------------新增-------------------------");
19         System.out.println(dao.create("JAVA", "123"));
20 
21     }
22 }

jdbc.properties 資原始檔

1 jdbc.driver=org.mariadb.jdbc.Driver
2 jdbc.url=jdbc:mariadb://localhost:3306/test
3 jdbc.user=oukele
4 jdbc.password=oukele

測試結果:

------------------------- List -------------------------
[{userName=oukele, password=oukele}, {userName=oukele1, password=oukele}, {userName=JAVA, password=123}]
------------------------- 鍵值對應 -------------------------
{userName=oukele1, password=oukele}
------------------------ 物件資料 ------------------------------
User{userName='oukele', password='oukele'}

新增的時候,新增事務管理

資料庫資料:

執行效果:

-------------------------新增-------------------------
十二月 21, 2018 10:42:58 上午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
資訊: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hge1v29z1lc434s1wp62cl|77167fb7, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.mariadb.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hge1v29z1lc434s1wp62cl|77167fb7, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mariadb://localhost:3306/test, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into user (userName, passord) values ('JavaScript', '2134')]; SQL state [null]; error code [0]; Could not set parameter at position 1 (values was 'JAVA1')
Query - conn:124(M)  - "insert into user (userName, passord) values ('JavaScript', '2134')"; nested exception is java.sql.SQLException: Could not set parameter at position 1 (values was 'JAVA1')
Query - conn:124(M)  - "insert into user (userName, passord) values ('JavaScript', '2134')"
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:89)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1444)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:862)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:917)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:927)
	at com.oukele.jdbcTemplate.UserDao.lambda$create$1(UserDao.java:47)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
	at com.oukele.jdbcTemplate.UserDao.create(UserDao.java:44)
	at com.oukele.jdbcTemplate.Main.main(Main.java:19)
Caused by: java.sql.SQLException: Could not set parameter at position 1 (values was 'JAVA1')
Query - conn:124(M)  - "insert into user (userName, passord) values ('JavaScript', '2134')"
	at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getSqlException(ExceptionMapper.java:271)
	at org.mariadb.jdbc.MariaDbPreparedStatementClient.setParameter(MariaDbPreparedStatementClient.java:480)
	at org.mariadb.jdbc.BasePrepareStatement.setString(BasePrepareStatement.java:1533)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setString(NewProxyPreparedStatement.java:540)
	at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:400)
	at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:232)
	at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:163)
	at org.springframework.jdbc.core.ArgumentPreparedStatementSetter.doSetValue(ArgumentPreparedStatementSetter.java:69)
	at org.springframework.jdbc.core.ArgumentPreparedStatementSetter.setValues(ArgumentPreparedStatementSetter.java:50)
	at org.springframework.jdbc.core.JdbcTemplate.lambda$update$0(JdbcTemplate.java:865)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
	... 7 more

  資料庫資料顯示:

其中有一條sql語法出錯 之前的操作全部回滾。

示例原始碼下載:https://github.com/oukele/Spring-JdbcTemplate-transactionTemplate