Spring’s JdbcTemplate
What is the JdbcTemplate?
The JdbcTemplate is a template object provided in the Spring framework that is a simple wrapper around the original tedious Jdbc API objects.
Core object
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSource dataSource);
Copy the code
Core method
int update(a); Execute add, delete, and modify statementsList<T> query(a); Query multipleT queryForObject(a); Query anewBeanPropertyRowMapper<>(); Implement ORM mapping encapsulationCopy the code
Take a chestnut
Example Query information about all accounts in the database to the Account entity
public class JdbcTemplateTest {
@Test
public void testFindAll(a) throws Exception {
// Create a core object
JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
/ / write SQL
String sql = "select * from account";
/ / SQL execution
List<Account> list = jdbcTemplate.query(sql, newBeanPropertyRowMapper<>(Account.class)); }}Copy the code
Spring integration JdbcTemplate
- demand
Implement CRUD cases for accounts based on Spring’s XML configuration
- Step analysis
1. Create a Java project, import coordinates 2. Write the AccountDao interface and implementation class 4. Write the AccountService interface and implementation class 5. Write the Spring core configuration file. 6. Write test codeCopy the code
1) Create a Java project and import coordinates
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.15</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
</dependencies>
Copy the code
2) Write the Account entity class
public class Account {
private Integer id;
private String name;
private Double money;
}
Copy the code
3) Write the AccountDao interface and implementation class
public interface AccountDao {
public List<Account> findAll(a);
public Account findById(Integer id);
public void save(Account account);
public void update(Account account);
public void delete(Integer id);
}
Copy the code
@Repository
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Account> findAll(a) {
/ / write SQL
String sql = "select * from account";
/ / SQL execution
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Account.class));
}
@Override
public Account findById(Integer id) {
/ / write SQL
String sql = "select * from account where id = ?";
/ / SQL execution
return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Account.class),id);
}
@Override
public void save(Account account) {
/ / write SQL
String sql = "insert into account values(null,? ,?) ";
/ / SQL execution
jdbcTemplate.update(sql, account.getName(), account.getMoney());
}
@Override
public void update(Account account) {
/ / write SQL
String sql = "update account set name = ? ,money = ? where id = ?";
/ / SQL execution
jdbcTemplate.update(sql, account.getName(),
account.getMoney(),account.getId());
}
@Override
public void delete(Integer id) {
/ / write SQL
String sql = "delete from account where id = ?";
/ / SQL executionjdbcTemplate.update(sql, id); }}Copy the code
4) Write the AccountService interface and implementation class
public interface AccountService {
public List<Account> findAll(a);
public Account findById(Integer id);
public void save(Account account);
public void update(Account account);
public void delete(Integer id);
}
Copy the code
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public List<Account> findAll(a) {
return accountDao.findAll();
}
@Override
public Account findById(Integer id) {
return accountDao.findById(id);
}
@Override
public void save(Account account) {
accountDao.save(account);
}
@Override
public void update(Account account) {
accountDao.update(account);
}
@Override
public void delete(Integer id) { accountDao.delete(id); }}Copy the code
5) Write the Spring core configuration file
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.lagou"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
</beans>
Copy the code
6) Write test code
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountServiceTest {
@Autowired
private AccountService accountService;
// Test save
@Test
public void testSave(a) {
Account account = new Account();
account.setName("lucy");
account.setMoney(100d);
accountService.save(account);
}
// Test the query
@Test
public void testFindById(a) {
Account account = accountService.findById(3);
System.out.println(account);
}
// Test query all
@Test
public void testFindAll(a) {
List<Account> accountList = accountService.findAll();
for(Account account : accountList) { System.out.println(account); }}// Test the modification
@Test
public void testUpdate(a) {
Account account = new Account();
account.setId(3);
account.setName("rose");
account.setMoney(2000d);
accountService.update(account);
}
// Test delete
@Test
public void testDelete(a) {
accountService.delete(3); }}Copy the code
Transfer Case
- Step analysis
1. Create a Java project, import coordinates 2. Write the AccountDao interface and implementation class 4. Write the AccountService interface and implementation class 5. Write the Spring core configuration file. 6. Write test codeCopy the code
1) Create a Java project and import coordinates
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.15</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
</dependencies>
Copy the code
2) Write the Account entity class
public class Account {
private Integer id;
private String name;
private Double money;
// setter getter....
}
Copy the code
3) Write the AccountDao interface and implementation class
public interface AccountDao {
public void out(String outUser, Double money);
public void in(String inUser, Double money);
}
Copy the code
@Repository
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void out(String outUser, Double money) {
jdbcTemplate.update("update account set money = money - ? where name = ?", money, outUser);
}
@Override
public void in(String inUser, Double money) {
jdbcTemplate.update("update account set money = money + ? where name = ?", money, inUser); }}Copy the code
4) Write the AccountService interface and implementation class
public interface AccountService {
public void transfer(String outUser, String inUser, Double money);
}
Copy the code
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public void transfer(String outUser, String inUser, Double money) { accountDao.out(outUser, money); accountDao.in(inUser, money); }}Copy the code
5) Write the Spring core configuration file
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<! --IOC annotation scan -->
<context:component-scan base-package="com.lagou"/>
<! Load the JDBC configuration file -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<! Give the database connection pool to the IOC container
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<! Pass the JdbcTemplate to the IOC container -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
</beans>
Copy the code
6) Write test code
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(a) throws Exception {
accountService.transfer("tom"."jerry".100d); }}Copy the code
Spring’s transaction
Transaction control in Spring
Spring’s transaction control can be divided into programmatic and declarative transaction control.
- programmatic
The developer couples the transactional code directly with the business code and does not use it in real development.
- declarative
Developers use the configuration of the way to achieve transaction control, business code and transaction code implementation decouple, using AOP ideas.
Programmatic transactions control related objects
PlatformTransactionManager
PlatformTransactionManager interface, it is spring’s transaction manager, provided we commonly used method of operation affairs.
methods | instructions |
---|---|
TransactionStatus getTransaction(TransactionDefinition definition); | Get the status information for the transaction |
Void commit (TransactionStatus status); | Commit the transaction |
Void the rollback (TransactionStatus status); | Roll back the transaction |
- Note:
* PlatformTransactionManager is the interface type, different Dao layer technology has different implementation classes. * Dao layer technology is jdbcTemplate or mybatis: DataSourceTransactionManager * Dao layer technology is hibernate when: HibernateTransactionManager * Dao layer technology is: when the JPA JpaTransactionManagerCopy the code
TransactionDefinition
The TransactionDefinition interface provides the TransactionDefinition information (transaction isolation level, transaction propagation behavior, and so on)
methods | instructions |
---|---|
int getIsolationLevel() | Get the isolation level of the transaction |
int getPropogationBehavior() | Get the propagation behavior of the transaction |
int getTimeout() | Get timeout |
boolean isReadOnly() | Whether the read-only |
- 1) Transaction isolation level
The isolation level can be set to solve problems caused by concurrent transactions, such as dirty reads, unrepeatable reads, and virtual reads (phantom reads).
* ISOLATION_DEFAULT Uses the database default level * ISOLATION_READ_UNCOMMITTED Read uncommitted * ISOLATION_READ_COMMITTED Read committed * ISOLATION_REPEATABLE_READ * ISOLATION_SERIALIZABLE serializationCopy the code
- 2) Transaction propagation behavior
Transaction propagation behavior refers to how transaction control should occur when a business method is called by another business method.
parameter | instructions |
---|---|
REQUIRED | If there is no transaction, create a new one. If there is already one, join it. General selection (default) |
SUPPORTS | Support for current transactions, non-transactionally if there is no transaction currently (no transaction) |
MANDATORY | Use the current transaction and throw an exception if there is no transaction currently |
REQUERS_NEW | Create a new transaction and suspend the current transaction if it is currently in one |
NOT_SUPPORTED | Performs the operation nontransactionally, suspending the current transaction if one exists |
NEVER | Runs nontransactionally and throws an exception if a transaction currently exists |
NESTED | If a transaction currently exists, it is executed within a nested transaction. If there are no transactions currently, something like REQUIRED is performed |
* Read-only: You are advised to set this parameter to read-only. * timeout: The default value is -1. There is no timeout limit. If yes, set the parameter in secondsCopy the code
TransactionStatus
The TransactionStatus interface provides a detailed running state of the transaction.
methods | instructions |
---|---|
boolean isNewTransaction() | Is it a new transaction |
boolean hasSavepoint() | Is the rollback point |
boolean isRollbackOnly() | Whether the transaction is rolled back |
boolean isCompleted() | Transaction complete |
The relationship can be understood simply: the transaction manager manages transactions by reading transaction definition parameters and then generates a series of transaction states.
The implementation code
1) Configuration files
<! -- Transaction manager to IOC-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Copy the code
2) Business layer code
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Autowired
private PlatformTransactionManager transactionManager;
@Override
public void transfer(String outUser, String inUser, Double money) {
// Create a transaction definition object
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// Set whether to read-only. False Supports transactions
def.setReadOnly(false);
// Set the transaction isolation level, which can repeat the mysql default level
def.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
// Set transaction propagation behavior, there must be a transaction
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// Configure the transaction manager
TransactionStatus status = transactionManager.getTransaction(def);
try {
/ / transfer
accountDao.out(outUser, money);
accountDao.in(inUser, money);
// Commit the transaction
transactionManager.commit(status);
} catch (Exception e) {
e.printStackTrace();
// Rollback the transactiontransactionManager.rollback(status); }}}Copy the code
Knowledge summary
Transaction control in Spring is primarily implemented through these three apis
* PlatformTransactionManager responsible for transaction management, it is an interface, Subclasses are responsible for the work * TransactionDefinition defines the parameters of a transaction * TransactionStatus represents a real-time state in which the transaction is runningCopy the code
Understand the relationship between the three: the transaction manager manages the transaction by reading transaction definition parameters and then generates a series of transaction states.
Declarative transaction control based on XML
Handle transactions declaratively instead of code in the Spring configuration file. The bottom layer uses AOP thought to achieve.
Declarative transaction control specifies matters:
- Core business code (target object) (Who is the pointcut?)
- Transaction enhancement code (Spring already provides a transaction manager) (Who is the notification?)
- Section configuration (how to configure the section?)
Quick start
- demand
Use Spring declarative transactions to control transfer transactions.
- Step analysis
Introduction of tx namespace 2. Transaction manager notification configuration 3. Transaction manager AOP configuration 4. Test transaction control transfer business codeCopy the code
1) Introduce the TX namespace
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w2.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/s chema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
Copy the code
2) Transaction manager notification configuration
<! -- Transaction manager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<! -- Notification enhancement -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<! Define transaction attributes -->
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
Copy the code
3) Transaction manager AOP configuration
<! - aop configuration - >
<aop:config>
<! -- Section Configuration -->
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.lagou.serivce.. *. * (..) )">
</aop:advisor>
</aop:config>
Copy the code
4) Test transaction control transfer business code
@Override
public void transfer(String outUser, String inUser, Double money) {
accountDao.out(outUser, money);
// create an exception
int i = 1 / 0;
accountDao.in(inUser, money);
}
Copy the code
Transaction parameter configuration details
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="1" read-only="false"/>* name: name of the pointcut method * Isolation: isolation level of the transaction * propogation: propagation behavior of the transaction * timeout: timeout period * read-only: whether the transaction is read-onlyCopy the code
- CRUD common configuration
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
Copy the code
Knowledge summary
* Platform transaction manager configuration * transaction notification configuration * transaction AOP woven into the configurationCopy the code
Annotation-based declarative transaction control
Commonly used annotations
Step analysis
1. Modify the Service layer to add transaction annotations 2. Modify the Spring core configuration file to enable transaction annotationsCopy the code
Step analysis
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, timeout = -1, readOnly = false)
@Override
public void transfer(String outUser, String inUser, Double money) {
accountDao.out(outUser, money);
int i = 1 / 0; accountDao.in(inUser, money); }}Copy the code
2) Modify the Spring core configuration file to enable transaction annotation support
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w2.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<! -- Omitted datsSource, jdbcTemplate, component scan configuration -->
<! -- Transaction manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<! Transaction annotation support -->
<tx:annotation-driven/>
</beans>
Copy the code
Pure annotations
Core configuration class
@Configuration // Declare the configuration class for Spring
@ComponentScan("com.lagou") / / scan packages
@Import(DataSourceConfig.class) // Import other configuration classes
@EnableTransactionManagement // Transaction annotation driven
public class SpringConfig {
@Bean
public JdbcTemplate getJdbcTemplate(@Autowired DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean("transactionManager")
public PlatformTransactionManager getPlatformTransactionManager(@Autowired DataSource dataSource) {
return newDataSourceTransactionManager(dataSource); }}Copy the code
Data source configuration class
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource getDataSource(a) {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
returndataSource; }}Copy the code
Knowledge summary
* the platform transaction manager configuration (XML, annotations) * transaction notification configuration (@ Transactional annotation configuration) * transaction annotation driven configuration - driven / > < tx: an annotation, @ EnableTransactionManagementCopy the code
Spring integrated Web environment
ApplicationContext indicates how to obtain the ApplicationContext
Application context object is through a new ClasspathXmlApplicationContext (spring configuration file) way to get, But every beans from the container to write new ClasspathXmlApplicationContext (spring configuration file), the disadvantages of this configuration file is loaded multiple times, to create multiple application context object. Version:0.9 StartHTML:0000000105 EndHTML:0000002684 StartFragment:0000000141 EndFragment:0000002644
Solution analysis: In a Web project, you can use ServletContextListener to listen to the start of the Web application. When the Web application starts, you can load the Spring configuration file and create the ApplicationContext object ApplicationContext. Store it in the largest domain, the servletContext domain, so that the ApplicationContext ApplicationContext object can be retrieved from the domain anywhere.
Spring provides tools for obtaining application context
Spring provides a ContextLoaderListener that encapsulates the above functionality. This listener loads the Spring configuration file internally, creates the application context object, and stores it in the ServletContext domain. Provides a client tool WebApplicationContextUtils for users get application context object.
So there are only two things we need to do:
- Configure ContextLoaderListener in web.xml (import Spring-Web coordinates)
- Use application context object WebApplicationContextUtils ApplicationContext
implementation
1) Import the coordinates of Spring integrated Web
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.5. RELEASE</version>
</dependency>
Copy the code
2) Configure the ContextLoaderListener
<! -- Global parameters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>•
</context-param>
<! --Spring listener -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Copy the code
3) Obtain the application context object through the tool
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object obj = applicationContext.getBean("id");
Copy the code