一.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);
}
}