导入jar包(坐标)
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</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.13</version>
<scope>test</scope>
</dependency>
</dependencies>
编写实体类User
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
编写配置类
- 该类是一个配置类,它的作用和bean.xml是一样的
-
Configuration
- 作用:指定当前类是一个配置类
-
ComponentScan
- 作用:用于通过注解指定spring在创建容器时扫描的包
- 属性:
- value:它和beanPackages的作用是一样的,都是用于指定创建容器时要扫描的包。
使用此注解就等于xml中的配置:<context:component-scan base-package=“com.whut”></context:component-scan> - 细节:当配置类作为AnnotationConfigApplicationContext对象创建参数时,该注解可以不写
- value:它和beanPackages的作用是一样的,都是用于指定创建容器时要扫描的包。
-
Bean
- 作用:用于把当前方法的返回值作为bean对象存入spring的IOC容器中
- 属性:
- name:用于指定bean的id。当不写时,默认值是当前方法的名称
- 细节:
- 当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象
- 查找的方式和Autowired注解的作用是一样的
-
Import
- 作用:用于导入其他的配置类
- 属性:
- value:用于指定其他配置类的字节码
- 当我们使用Import的注解之后,有Import注解的类就是父配置类,而导入的就是子配置类
- value:用于指定其他配置类的字节码
-
PropertySource
- 作用:用于指定properties文件的位置
- 属性:
- value:指定文件的名称和路径
- 关键字:classpath,表示类路径下
- value:指定文件的名称和路径
-
- 编写父配置类
//@Configuration
@ComponentScan("com.whut")
@Import(JdbcConfiguration.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {
}
- 编写子配置类
//@Configuration
public class JdbcConfiguration {
@Value("${jdbc.driver}")
private String driverClass;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* 创建一个QueryRunner对象
* <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
* <constructor-arg name="ds" ref="dataSource"></constructor-arg>
* </bean>
* @param dataSource
* @return
*/
@Bean(name = "queryRunner")
@Scope("prototype")
public QueryRunner creatQueryRunner(@Qualifier("dataSource1") DataSource dataSource){
return new QueryRunner(dataSource);
}
/**
* 创建数据源对象
* <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
* <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
* <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/my_db?serverTimezone=UTC"/>
* <property name="user" value="root"/>
* <property name="password" value="fy123"/>
* </bean>
* @return
*/
@Bean(name = "dataSource1")
public DataSource creatDataSource(){
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
}
@Bean(name = "dataSource2")
public DataSource creatDataSource2(){
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
}
}
编写jdbc配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my_db?serverTimezone=UTC
jdbc.username=root
jdbc.password=fy123
业务层
@Service("userService")
public class UserServiceImp implements UserService {
@Autowired
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public List<User> findAllUsers() {
return userDao.findAllUsers();
}
public User findUserById(Integer userId) {
return userDao.findUserById(userId);
}
public void updateUser(User user) {
userDao.updateUser(user);
}
public void addUser(User user) {
userDao.addUser(user);
}
public void delUser(Integer userId) {
userDao.delUser(userId);
}
}
持久层
@Repository("userDao")
public class UserDaoImp implements UserDao {
@Autowired
private QueryRunner queryRunner;
public void setQueryRunner(QueryRunner queryRunner) {
this.queryRunner = queryRunner;
}
public List<User> findAllUsers() {
try {
return queryRunner.query("select * from mybatisuser", new BeanListHandler<User>(User.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
public User findUserById(Integer userId) {
try {
return queryRunner.query("select * from mybatisuser where id = ?", new BeanHandler<User>(User.class),userId);
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void addUser(User user) {
try {
queryRunner.insert("insert into mybatisuser(username,birthday,sex,address) values(?,?,?,?)",new BeanHandler<User>(User.class),user.getUsername(),user.getBirthday(),user.getSex(),user.getAddress());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void updateUser(User user) {
try {
queryRunner.update("update mybatisuser set username=? ,birthday=?,sex=?,address=? where id=?",user.getUsername(),user.getBirthday(),user.getSex(),user.getAddress(),user.getId());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void delUser(Integer userId) {
try {
queryRunner.update("delete from mybatisuser where id=?",userId);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
测试方法
- 使用Junit单元测试:测试我们的配置
- spring整合junit的配置
- 导入spring整合junit的jar(坐标)
- 使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
- 告知spring运行器,spring和ioc创建是基于xml还是注解的,并且说明位置
- @ContextConfiguration
- locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
- classes:指定注解所在位置
- @ContextConfiguration
- 当我们使用spring 5.x版本时,要求junit的jar必须是4.12以及上
- spring整合junit的配置
- 测试方法
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class UserServiceTset {
@Autowired
private UserService userService = null;
@Test
public void testFindAllUsers(){
//1. 获取容器
/**
* 当配置类作为AnnotationConfigApplicationContext对象创建参数时,该注解可以不写,也不用扫描包
* 当使用注解时,同时也需要扫描包
*/
// //1. 获取容器
// AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
// //2. 获取业务层对象
// UserService userService = ac.getBean("userService", UserService.class);
//3. 执行方法
List<User> allUsers = userService.findAllUsers();
for (User user : allUsers){
System.out.println(user);
}
}
@Test
public void testFindUserById(){
//3. 执行方法
User user = userService.findUserById(2);
System.out.println(user);
}
@Test
public void testAddUser(){
User user = new User();
user.setUsername("莫提斯1");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("神话突击者");
//3. 执行方法
userService.addUser(user);
}
@Test
public void testUpdateUser(){
User user = new User();
user.setUsername("柯莱特");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("流彩战士");
user.setId(11);
//3. 执行方法
userService.updateUser(user);
}
@Test
public void testDelUser(){
//3. 执行方法
userService.delUser(11);
}
}