一.DbUtils
(1)DbUtils是什么?
DbUtils是Apache的一款用于简化Dao层代码的工具类,它底层封装了JDBC技术。
核心对象:
QueryRunner queryRunner = new QueryRunner(DataSource dataSource);
核心方法:
int update(); 执行增、删、改语句
T query(); 执行查询语句
ResultSetHandler<T> 这是一个接口,主要作用是将数据库返回的记录封装到实体对象
举个例子:
查询数据库所有账户信息到Account实体中
public class DbUtilsTest {
@Test
public void findAllTest() throws Exception {
// 创建DBUtils工具类,传入连接池
QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
// 编写sql
String sql = "select * from account";
// 执行sql
List<Account> list = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
// 打印结果
for (Account account : list) {
System.out.println(account);
}
}
}
(2)DbUtils快速入门:
1)准备数据库环境:
2)创建maven的java模块:pom.xml
<?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>com.wsl</groupId>
<artifactId>springday02-dbutils</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
3)导入相关jar包
<!--依赖管理-->
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.15</version>
</dependency>
<!--dbUtils工具包-->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring核心-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
</dependencies>
工具类导入:
实体类:
public class Account {
private Integer id;
private String name;
private Double money;
public Account() {
}
public Account(Integer id, String name, Double money) {
this.id = id;
this.name = name;
this.money = money;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
api介绍:
测试:
public class DbUtilsTest {
@Test
public void test01() throws Exception{
//新增记录
QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
String sql = "insert into account(name,money) values(?,?)";
queryRunner.update(sql,"张明明",30);
}
@Test
public void test02() throws Exception{
//查询一条记录
QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
String sql = "select * from account where id=?";
Account account = queryRunner.query(sql, new BeanHandler<>(Account.class), 3);
System.out.println(account);
}
@Test
public void test03() throws Exception{
//查询多条记录
QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
String sql = "select * from account";
List<Account> accountList = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
System.out.println(accountList);
}
}
(2)Spring的xml整合DbUtils
基于spring的xml配置实现账户的CRUD
AccountDao代码:
public interface AccountDao {
void save(Account account);
void update(Account account);
void delete(Integer id);
List<Account> findAll();
Account findById(Integer id);
}
public class AccountDaoImpl implements AccountDao {
// 声明 QueryRunner 对象
private QueryRunner queryRunner;
public void setQueryRunner(QueryRunner queryRunner) {
this.queryRunner = queryRunner;
}
@Override
public void save(Account account) {
try {
// 1.编写sql
String sql = "insert into account(name,money)values(?,?)";
// 2.执行sql
queryRunner.update(sql, account.getName(), account.getMoney());
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void update(Account account) {
try {
// 1.编写sql
String sql = "update account set name = ? , money = ? where id = ?";
// 2.执行sql
queryRunner.update(sql, account.getName(), account.getMoney(), account.getId());
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void delete(Integer id) {
try {
// 1.编写sql
String sql = "delete from account where id = ?";
// 2.执行sql
queryRunner.update(sql, id);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public List<Account> findAll() {
List<Account> list = null;
try {
// 1.编写sql
String sql = "select * from account";
// 2.执行sql
list = queryRunner.query(sql, new BeanListHandler<>(Account.class));
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
@Override
public Account findById(Integer id) {
Account account = null;
try {
// 1.编写sql
String sql = "SELECT * FROM account WHERE id = ?";
// 2.执行sql
account = queryRunner.query(sql, new BeanHandler<>(Account.class), id);
} catch (SQLException e) {
e.printStackTrace();
}
return account;
}
}
AccountService
public interface AccountService {
void save(Account account);
void update(Account account);
void delete(Integer id);
List<Account> findAll();
Account findById(Integer id);
}
public class AccountServiceImpl implements AccountService {
// 声明
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@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);
}
@Override
public List<Account> findAll() {
return accountDao.findAll();
}
@Override
public Account findById(Integer id) {
return accountDao.findById(id);
}
}
Spring的核心配置文件:
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--druid连接交给ioc容器-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/spring_db"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--queryRunner交给ioc容器-->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!--accountDao交给ioc容器-->
<bean id="accountDao" class="cn.wsl.dao.impl.AccountDaoImpl">
<property name="queryRunner" ref="queryRunner"></property>
</bean>
<!--accountService交给ioc容器-->
<bean id="accountService" class="cn.wsl.serivce.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
</beans>
代码测试:
public class AccountTest {
//新增
@Test
public void test01() throws Exception{
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
accountService.save(new Account(4,"张三",2000.0));
}
//修改
@Test
public void test02() throws Exception{
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
accountService.update(new Account(4,"张三",2050.0));
}
//删除
@Test
public void test03() throws Exception{
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
accountService.delete(4);
}
//查询所有
@Test
public void test04() throws Exception{
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
List<Account> all = accountService.findAll();
System.out.println(all);
}
//查询一个
@Test
public void test05() throws Exception{
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
Account account = accountService.findById(3);
System.out.println(account);
}
}
配置文件抽取:
引入context命名空间(约束)
修改配置文件标签:
二.Spring注解开发:
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。
(1)Spring常用注解:
Spring常用注解主要是替代<bean>
的配置
IOC控制反转:
- @Component:相当于 <bean></bean>
- @Repository:专门处理dao层,交给ioc容器
- @Service:专门处理service层,交给ioc容器
- @Controller:专门处理web层,交给ioc容器
注意,如果使用注解开发,必须开启注解组件扫描:
<?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="com.wsl"></context:component-scan>
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<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="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
</beans>
AccountDao
AccountService
DI:依赖注入:
- @Autowired:相当于 <property></property> ,根据类型注入
- @Qualifies:与@Autowired一起使用,根据id查找同类型下的实例
- @Resource :jdk提供的注解(@Autowired+@Qualifies)
补充:
- @Scope:相当于 <bean scope=""></bean>
singleton:单例对象(默认)
prototype:多例对象
- @PostConstruct:相当于 <bean init-method=""></bean>
- @PreDestroy:相当于 <bean detroy-method=""></bean>
- @Value:通过${} SPEL,从配置文件中获取数据
// <bean id="userService" class="cn.wsl.service.impl.UserServiceImpl"></bean>
@Service
@Scope("prototype") // 多例对象
public class UserServiceImpl implements UserService {
/*@Autowired
@Qualifier("userDaoImpl")*/
@Resource(name = "userDaoImpl")
private UserDao userDao;
// <property name="userDao" ref="userDao"></property>
// @Autowired
/*public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}*/
@Value("张三")
private String name ;
@Value("${jdbc.driver}")
private String driver;
@Override
public void save() {
System.out.println(name);
System.out.println(driver);
userDao.save();
}
@PostConstruct
public void init(){
System.out.println("init执行了...");
}
@PreDestroy
public void detroy(){
System.out.println("destroy执行了...");
}
}
(2)Spring常用注解整合DbUtils
改造:
AccountDao
@Repository
public class AccountDaoImpl implements AccountDao {
@Autowired
private QueryRunner queryRunner;
@Override
public void save(Account account) {
String sql ="insert into account(name,money) values(?,?)";
try {
queryRunner.update(sql,account.getName(),account.getMoney());
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void update(Account account) {
String sql = "update account set name=?,money =? where id=?";
try {
queryRunner.update(sql,account.getName(),account.getMoney(),account.getId());
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void delete(Integer id) {
String sql ="delete from account where id = ? ";
try {
queryRunner.update(sql,id);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public List<Account> findAll() {
List<Account> list = null;
String sql = "select * from account";
try {
list = queryRunner.query(sql,new BeanListHandler<>(Account.class));
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
@Override
public Account findById(Integer id) {
Account account = null;
String sql = "select * from account where id = ?";
try {
account = queryRunner.query(sql,new BeanHandler<>(Account.class),id);
} catch (SQLException e) {
e.printStackTrace();
}
return account;
}
}
AccountService
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@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);
}
@Override
public List<Account> findAll() {
List<Account> all = accountDao.findAll();
return all;
}
@Override
public Account findById(Integer id) {
Account account = accountDao.findById(id);
return account;
}
}
修改配置文件:
<?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="com.wsl"/>
<!--加载第三方配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--druid连接交给ioc容器:第三方类目前只能使用bean标签 -->
<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>
<!--queryRunner交给ioc容器:第三方类目前只能使用bean标签-->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
</beans>
测试:
(3)Spring新注解:
使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置
- @Configuration : 相当于applicationContext.xml
- @Bean:加载第三方类(对象),交给ioc容器
- @PropertySource :相当于 <context:property-placeholder location=""/>
- @ComponentScan :相当于 <context:component-scan base-package=""/>
- @Import :相当于 <import resource=""></import>
(4)利用纯注解整合DbUtils
创建SpringConfig配置类
@Configuration // applicationContext.xml
@ComponentScan("cn.wsl") // <context:component-scan base-package="cn.wsl"/>
@PropertySource("classpath:jdbc.properties") // <context:property-placeholder location="classpath:jdbc.properties"/>
public class SpringConfig {
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// 自定义druid对象,交给ioc容器
/*
<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("dataSource")
public DataSource createDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
// 自定义queryRunner对象,交给ioc容器
/*
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
*/
@Bean("queryRunner")
public QueryRunner createQueryRunner(@Autowired DataSource dataSource) { // 这里的代码就是从ioc容器中,完成了依赖注入...
QueryRunner queryRunner = new QueryRunner(dataSource);
return queryRunner;
}
}
测试
(5)配置类模块化
编写DataSourceConfig
public class DataSourceConfig {
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// 自定义druid对象,交给ioc容器
/*
<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("dataSource")
public DataSource createDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
修改主配置类:
三.Spring整合Junit
(1)介绍:
Junit是一个单元测试工具,点击run的执行测试方法时,其实底层是通过runner(运行器)来工作的,默认的Junit是不会自动加载spring环境。
如果想在Junit中直接获取spring的容器,我们需要导入spring提供的测试整合包,切换为spring的运行器,就可以直接获取IOC容器中的对象了。
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring整合junit-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
(2)使用
在进行单元测试时,指定junti的运行器为spring的
指定加载配置文件或者配置类
注意:注解-@ContextConfiguration(locations = "classpath:applicationContext.xml") 可以加载全注解配置类,也可以加载xml文件配置文件
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AccountTest {
@Autowired
AccountService accountService;
//新增
@Test
public void test01() throws Exception{
accountService.save(new Account(7,"张hah",2650.0));
}
//修改
@Test
public void test02() throws Exception{
accountService.update(new Account(4,"张三",2050.0));
}
//删除
@Test
public void test03() throws Exception{
accountService.delete(4);
}
//查询所有
@Test
public void test04() throws Exception{
List<Account> all = accountService.findAll();
System.out.println(all);
}
//查询一个
@Test
public void test05() throws Exception{
Account account = accountService.findById(5);
System.out.println(account);
}
}