The second day of spring study
Using spring's IoC to implement user's crud (based on xml)
Note that three techniques are used in this case
: 1,c3p0
2,dbassit
3. Implementing ioc management with spring
Environment construction
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>springTest2</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.7.RELEASE</version> </dependency> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.4.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
There may be a conflict between the mysql version and c3p0 data pool technology. Please lower the mysql version appropriately
Creating databases and writing entity classes
package doMain; import java.util.Date; public class User { int id; String username; Date birthday; String sex; String address; @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
Writing persistence layer code
package dao; import doMain.User; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import java.sql.SQLException; import java.util.List; public class UserDaoImpl implements IUserDao{ QueryRunner queryRunner; public QueryRunner getQueryRunner() { return queryRunner; } public void setQueryRunner(QueryRunner queryRunner) { this.queryRunner = queryRunner; } public List<User> findAll() throws SQLException { String sql="select * from user"; List<User> users= queryRunner.query(sql,new BeanListHandler<User>(User.class)); return users; } public User findById(int i) { String sql="select * from user where id=?"; User user = null; try { user = queryRunner.query(sql, new BeanHandler<User>(User.class), i); } catch (SQLException throwables) { throwables.printStackTrace(); } return user; } public boolean saveUser(User user) { String sql="insert into user (username,birthday,sex,address) values (?,?,?,?)"; try { queryRunner.update(sql,user.getUsername(),user.getBirthday(),user.getSex(),user.getAddress()); return true; } catch (SQLException throwables) { throwables.printStackTrace(); return false; } } public boolean deleteUser(int i) { String sql="delete from user where id=?"; try { queryRunner.update(sql,i); return true; } catch (SQLException throwables) { throwables.printStackTrace(); return false; } } }
package service; import dao.IUserDao; import doMain.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.sql.SQLException; import java.util.List; public class UserServiceImpl implements IUserService { IUserDao dao; public IUserDao getDao() { return dao; } public void setDao(IUserDao dao) { this.dao = dao; } public List<User> findAll() throws SQLException { List<User> all = dao.findAll(); return all; } public User findById(int i) { return dao.findById(i); } public boolean saveUser(User user) { return dao.saveUser(user); } public boolean deleteUser(int i) { return dao.deleteUser(i); } }
Create and write configuration files
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userDao" class="dao.UserDaoImpl"> <property name="queryRunner" ref="queryRunner"></property> </bean> <bean id="userService" class="service.UserServiceImpl"> <property name="dao" ref="userDao"></property> </bean> <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <!-- Configure data source --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean> </beans>
Test class code
import com.sun.xml.internal.txw2.output.DumpSerializer; import doMain.User; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.support.ClassPathXmlApplicationContext; import service.IUserService; import java.sql.SQLException; import java.util.Date; import java.util.List; public class test { private ApplicationContext context; private IUserService service; @Before public void init(){ context = new ClassPathXmlApplicationContext("bean.xml"); service = (IUserService) context.getBean("userService"); } @Test public void findAll() throws SQLException { List<User> all = service.findAll(); for (User u : all) { System.out.println(u); } } @Test public void findById() throws SQLException { User user = service.findById(53); System.out.println(user); } @Test public void saveUser() throws SQLException { User user=new User(); user.setUsername("spring"); user.setAddress("jinhua"); user.setBirthday(new Date()); user.setSex("male"); boolean b = service.saveUser(user); System.out.println(b); } @Test public void deleteUser() throws SQLException { boolean b = service.deleteUser(55); System.out.println(b); } }
Using spring's IoC to implement user's crud (annotation based)
Add dependency
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>springTest3</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
If this error is reported, it indicates that the dependent version is incompatible. Reduce the version appropriately
java.lang.NoClassDefFoundError: org/springframework/core/metrics/ApplicationStartup
Dao
package dao; import doMain.User; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.sql.SQLException; import java.util.List; @Component("userDao") public class UserDaoImpl implements IUserDao{ @Autowired QueryRunner queryRunner; public List<User> findAll() throws SQLException { String sql="select * from user"; List<User> users= queryRunner.query(sql,new BeanListHandler<User>(User.class)); return users; } public User findById(int i) { String sql="select * from user where id=?"; User user = null; try { user = queryRunner.query(sql, new BeanHandler<User>(User.class), i); } catch (SQLException throwables) { throwables.printStackTrace(); } return user; } public boolean saveUser(User user) { String sql="insert into user (username,birthday,sex,address) values (?,?,?,?)"; try { queryRunner.update(sql,user.getUsername(),user.getBirthday(),user.getSex(),user.getAddress()); return true; } catch (SQLException throwables) { throwables.printStackTrace(); return false; } } public boolean deleteUser(int i) { String sql="delete from user where id=?"; try { queryRunner.update(sql,i); return true; } catch (SQLException throwables) { throwables.printStackTrace(); return false; } } }
The annotation @ Component is used here
service
package service; import dao.IUserDao; import doMain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; import java.sql.SQLException; import java.util.List; @Component("userService") public class UserServiceImpl implements IUserService { @Autowired IUserDao dao; public List<User> findAll() throws SQLException { List<User> all = dao.findAll(); return all; } public User findById(int i) { return dao.findById(i); } public boolean saveUser(User user) { return dao.saveUser(user); } public boolean deleteUser(int i) { return dao.deleteUser(i); } }
Use @ AutoWired here
It means to search from the container. If it is found, it will be assigned. If there are multiple same types, it will be searched according to the name. If it is not found again, it will report an error.
@ Qualifier is also commonly used
@resource
@Value
@Scope
@PostConstruct
@PreDestroy
configuration file
Note that at this time, queryRunner still needs to be configured in the xml file. In addition, when using context: component to set the scanned package, if the directory is directly placed in the java directory and then configured with java, it is not feasible. It is best to put the code under a unified package path or configure the scanning path separately
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="dao"></context:component-scan> <context:component-scan base-package="service"></context:component-scan> <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <!-- Configure data source --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean> </beans>
Test code
Note that the first service object still needs to be obtained from the configuration file, because junit used at this time does not want to be combined with spring. junit does not know whether you use spring, so it is impossible to obtain the container automatically. You need to obtain the container manually and then obtain the service object from the container, If you want to completely remove the xml configuration, you need to use the @ ContextConfiguration and @ RunWith annotations mentioned later.
import com.sun.xml.internal.txw2.output.DumpSerializer; import doMain.User; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.support.ClassPathXmlApplicationContext; import service.IUserService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import java.sql.SQLException; import java.util.Date; import java.util.List; public class test { private ApplicationContext context; private IUserService service; @Before public void init(){ context = new ClassPathXmlApplicationContext("bean.xml"); service = context.getBean("userService",IUserService.class); } @Test public void findAll() throws SQLException { List<User> all = service.findAll(); for (User u : all) { System.out.println(u); } } @Test public void findById() throws SQLException { User user = service.findById(53); System.out.println(user); } @Test public void saveUser() throws SQLException { User user=new User(); user.setUsername("spring"); user.setAddress("jinhua"); user.setBirthday(new Date()); user.setSex("male"); boolean b = service.saveUser(user); System.out.println(b); } @Test public void deleteUser() throws SQLException { boolean b = service.deleteUser(55); System.out.println(b); } }
Pure annotation configuration of spring
New annotations used
@Configuration
Get container usage:
Here, the xml configuration is replaced by the configuration class
Example code:
You can see that adding this annotation to a class indicates that the class is a Configuration class. Later, you can use the AnnotationConfigApplicationContext() method to load and obtain the container. However, the name of the Configuration class can not be written here because it has been annotated with @ Configuration annotation, However, if you do not write this annotation, you must pass in the class file of the Configuration class in AnnotationConfigApplicationContext().
@ComponentScan
Write this annotation on the configuration class to specify the package scanned during initialization. You can also use ComponentScans to add multiple Componentscan annotations as follows:
@Bean
Example notes:
@PropertySource
Example code:
@Configuration @ComponentScans( {@ComponentScan("dao"),@ComponentScan("service")}) @PropertySource("jdbc.properties") public class Config { @Value("${driver}") private String driver; @Value("${url}") private String url; @Value("${user}") private String user; @Value("${password}") private String password; @Bean("queryRunner") @Scope("prototype") public QueryRunner getQueryRunner(javax.sql.DataSource dataSource){ return new QueryRunner(dataSource); } @Bean("dataSource") public DataSource getDataSource(){ ComboPooledDataSource dataSource=new ComboPooledDataSource(); try { dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setPassword(user); dataSource.setUser(password); } catch (PropertyVetoException e) { e.printStackTrace(); } return dataSource; } }
I write it in the resource directory here, so I can write the file name directly. After importing, you can use spring's er expression when transferring values to variables. Use ${} to reference resources and pass in the key value to get the values we want,
@Import
If we have multiple configuration classes but do not want to read them separately, but read them at one time, use the import annotation, so that the slave configuration file written in import will also be configured when reading the master configuration file.
spring integrates junit
junit can't be used to automatically create the container without junit, so we don't know that junit can be used to automatically replace it when spring is running.
Step 1: import dependent jar packages
Here are some details to know:
When we use spring 5 In the X version, the jar of junit must be 4.12 or above
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency>
Step 2: replace the original runner with @ RunWith annotation
The replacement here is springjunit4classrunner class
Step 3: use @ ContextConfiguration to specify the location of the spring configuration file
After changing the runner, you should also tell where to get the container. Here you can get the xml configuration or use the annotation class
Reading xml is preceded by locations
Using annotated classes is to add classes in front of them
Step 4: use @ Autowired to inject data into the variables in the test class
At this time, the variables in our test class can get the value from the container