一、新注解的说明
1、@Configuration
作用:指定当前类是一个配置类,作用和bean.xml是一样的。
注意:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。
2、@ComponentScan
作用:用于通过注解指定spring在创建容器时要扫描的包;
属性:value用于指定创建容器时要扫描的包(basePackages属性同value)。等同于在xml中配置:<context:component-scan base-package="com.wedu.spring"/>
3、@Bean
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中。
属性:name用于指定bean的id,默认值是当前方法的名称。
注意:当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。查找的方式和Autowired注解的作用是一样的
4、@Import
作用:用于导入其他的配置类。
属性:value用于指定其他配置类的字节码(当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类)。
5、@PropertySource
作用:用于指定properties文件的位置。
属性:value指定文件的名称和路径(classpath:表示类路径下)。
6、@RunWith
作用:将Junit的注解替换main方法替换
7、@ContextConfiguration
作用:告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置。
属性:locations,用于指定配置文件的位置。如果是类路径下,需要用classpath:表明;classes,用于指定注解的类。当不使用xml配置时,需要用此属性指定注解类的位置。
二、纯注解实现spring ioc的CRUD
1、创建maven项目并导入jar包的坐标
2、在domain包中创建实体类UserInfo
package com.wedu.spring06.domain;
import java.io.Serializable;
import java.util.Date;
/**
* 用户实体
*/
public class UserInfo implements Serializable {
private Integer id;
private String username;
private String password;
private Integer age;
private Date regtime;
private String siteaddress;
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getRegtime() {
return regtime;
}
public void setRegtime(Date regtime) {
this.regtime = regtime;
}
public String getSiteaddress() {
return siteaddress;
}
public void setSiteaddress(String siteaddress) {
this.siteaddress = siteaddress;
}
@Override
public String toString() {
return "UserInfo{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", regtime=" + regtime +
", siteaddress='" + siteaddress + '\'' +
'}';
}
}
3、创建持久层接口和实现类
在dao包中创建持久层接口
package com.wedu.spring06.dao;
import com.wedu.spring06.domain.UserInfo;
import java.util.List;
/**
* 用户持久层接口
*/
public interface IUserInfoDao {
/**
* 查询所有用户
* @return
*/
List<UserInfo> findAllUserInfo();
/**
* 根据id查询用户
* @param id
* @return
*/
UserInfo findUserInfoById(Integer id);
/**
* 增加用户
* @param userInfo
*/
void saveUserInfo(UserInfo userInfo);
/**
* 修改用户
* @param userInfo
*/
void updateUserInfo(UserInfo userInfo);
/**
* 根据id删除用户
* @param id
*/
void deleteUserInfo(Integer id);
}
在dao包中创建impl包并创建持久层接口的实现类
package com.wedu.spring06.dao.impl;
import com.wedu.spring06.dao.IUserInfoDao;
import com.wedu.spring06.domain.UserInfo;
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.Repository;
import java.util.List;
/**
* 用户持久层实现
*/
@Repository("userInfoDao")
public class UserInfoDaoImpl implements IUserInfoDao {
@Autowired
private QueryRunner runner;
@Override
public List<UserInfo> findAllUserInfo() {
try {
return runner.query("select * from userinfo", new BeanListHandler<UserInfo>(UserInfo.class));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public UserInfo findUserInfoById(Integer id) {
try {
return runner.query("select * from userinfo where id=?", new BeanHandler<UserInfo>(UserInfo.class), id);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void saveUserInfo(UserInfo userInfo) {
try {
runner.update("insert into userInfo(username,password,age,regtime,siteaddress)value(?,?,?,?,?)",
userInfo.getUsername(), userInfo.getPassword(), userInfo.getAge(), userInfo.getRegtime(), userInfo.getSiteaddress());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void updateUserInfo(UserInfo userInfo) {
try {
runner.update("update userInfo set username=?,password=?,age=?,regtime=?,siteaddress=? where id=?",userInfo.getUsername(),
userInfo.getPassword(),userInfo.getAge(),userInfo.getRegtime(),userInfo.getSiteaddress(), userInfo.getId());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void deleteUserInfo(Integer id) {
try {
runner.update("delete from userInfo where id=?", id);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4、创建业务层接口和实现类
在service包中创建持久层接口
package com.wedu.spring06.service;
import com.wedu.spring06.domain.UserInfo;
import java.util.List;
/**
* 用户的业务层接口
*/
public interface IUserInfoService {
/**
* 查询所有用户
* @return
*/
List<UserInfo> findAllUserInfo();
/**
* 根据id查询用户
* @param id
* @return
*/
UserInfo findUserInfoById(Integer id);
/**
* 增加用户
* @param userInfo
*/
void saveUserInfo(UserInfo userInfo);
/**
* 修改用户
* @param userInfo
*/
void updateUserInfo(UserInfo userInfo);
/**
* 根据id删除用户
* @param id
*/
void deleteUserInfo(Integer id);
}
在service包中创建impl包并创建持久层接口的实现类
package com.wedu.spring06.service.impl;
import com.wedu.spring06.dao.IUserInfoDao;
import com.wedu.spring06.domain.UserInfo;
import com.wedu.spring06.service.IUserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户的业务层实现
*/
@Service("userInfoService")
public class UserInfoServiceImpl implements IUserInfoService {
@Autowired
private IUserInfoDao userInfoDao;
@Override
public List<UserInfo> findAllUserInfo() {
return userInfoDao.findAllUserInfo();
}
@Override
public UserInfo findUserInfoById(Integer id) {
return userInfoDao.findUserInfoById(id);
}
@Override
public void saveUserInfo(UserInfo userInfo) {
userInfoDao.saveUserInfo(userInfo);
}
@Override
public void updateUserInfo(UserInfo userInfo) {
userInfoDao.updateUserInfo(userInfo);
}
@Override
public void deleteUserInfo(Integer id) {
userInfoDao.deleteUserInfo(id);
}
}
5、创建配置类
创建spring配置类SpringConfiguration
package com.wedu.spring06.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
/**
* spring配置类
*/
//指定当前类是一个配置类
@Configuration
//指定spring在创建容器时要扫描的包
@ComponentScan("com.wedu.spring06")
//导入其他配置类
@Import(JdbcConfiguration.class)
//指定properties文件的位置
@PropertySource("classpath:jdbc.properties")
public class SpringConfiguration {
}
创建spring连接数据库的配置类JdbcConfiguration
package com.wedu.spring06.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/**
* spring连接数据库的配置类
*/
public class JdbcConfiguration {
@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(name="runner")//把当前方法的返回值作为bean对象存入spring的ioc容器中
@Scope("prototype")
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}
@Bean(name="dataSource")
public DataSource createDataSource() {
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
}
}
6、添加数据库配置信息文件jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
7、创建测试类并编写测试方法进行测试
package com.wedu.spring06.service;
import com.wedu.spring06.config.SpringConfiguration;
import com.wedu.spring06.domain.UserInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Date;
import java.util.List;
/**
* spring ioc实例:纯注解的用户业务层CRUD测试
*/
//使用spring的Runwith将Junit的注解main方法的替换
@RunWith(SpringJUnit4ClassRunner.class)
//告知spring运行器,spring ioc创建是基于xml还是注解,并说明位置
@ContextConfiguration(classes = SpringConfiguration.class)
public class UserInfoServiceTest {
@Autowired
private IUserInfoService userInfoService;
/**
* 查询所有账户
*/
@Test
public void findAllUserInfoTest() {
List<UserInfo> userInfoList = userInfoService.findAllUserInfo();
for (UserInfo userInfo : userInfoList) {
System.out.println(userInfo);
}
}
/**
* 添加账户
*/
@Test
public void saveUserInfoTest() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("test");
userInfo.setPassword("123456");
userInfo.setAge(29);
userInfo.setRegtime(new Date());
userInfo.setSiteaddress("https://blog.csdn.net/yu1755128147");
userInfoService.saveUserInfo(userInfo);
}
/**
* 根据id查询账户
*/
@Test
public void findUserInfoByIdTest() {
UserInfo userInfo = userInfoService.findUserInfoById(6);
System.out.println(userInfo);
}
/**
* 更新账户
*/
@Test
public void updateUserInfoTest() {
UserInfo userInfo = userInfoService.findUserInfoById(6);
userInfo.setUsername("测试");
userInfoService.updateUserInfo(userInfo);
}
/**
* 删除账户
*/
@Test
public void deleteUserInfoTest() {
userInfoService.deleteUserInfo(6);
}
}