对应工程heima-xmlioc
前期准备
在maven中配置要用到的jar包
<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>8.0.19</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>
<scope>test</scope>
</dependency>
</dependencies>
bean.xml配置
QueryRunner使用的是通过构造函数注入,因为QueryRunner类是java自带的,我们不能修改,不能使用set方法注入,所以bean文件采用constructor-arg
- constructor-arg:通过构造函数注入。
- property:通过setter对应的方法注入。
<!-- 配置service -->
<bean id="accountService" class="cn.smm.service.impl.AccountServiceImpl">
<!-- 注入dao -->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!-- 配置dao对象 -->
<bean id="accountDao" class="cn.smm.dao.impl.AccountDaoImpl">
<!-- 注入QueryRunner对象 -->
<property name="runner" ref="runner"></property>
</bean>
<!-- 配置QueryRunner -->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!-- 注入数据源 -->
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 连接数据库的必备信息 -->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
账户持久层实现类
public class AccountDaoImpl implements IAccountDao {
private QueryRunner runner;
public void setRunner(QueryRunner runner) {
this.runner = runner;
}
public List<Account> findAllAccount() {
try {
return runner.query("select * from account",
new BeanListHandler<Account>(Account.class));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Account findAccountById(Integer accountid) {
try {
return runner.query("select * from account where id =?",
new BeanHandler<Account>(Account.class), accountid);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void saveAccount(Account account) {
try {
runner.update("insert into account(name,money)values(?,?)",
account.getName(), account.getMoney());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void updateAccount(Account account) {
try {
runner.update("update account set name=?,money=? where id=?",
account.getName(), account.getMoney(), account.getId());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void deleteAccount(Integer accountid) {
try {
runner.update("delete from account where id=?", accountid);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
账户实体类
public class Account implements Serializable {
private Integer id;
private String name;
private Float 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 Float getMoney() {
return money;
}
public void setMoney(Float money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
账户业务层实现类
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
public Account findAccountById(Integer accountid) {
return accountDao.findAccountById(accountid);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer accountid) {
accountDao.deleteAccount(accountid);
}
}
junit单元测试类
public class AccountServiceTest {
@Test
public void testFindAll() {
// 1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.获取业务层对象
IAccountService as = ac.getBean("accountService", IAccountService.class);
// 3.执行方法
List<Account> allaccounts = as.findAllAccount();
for (Account aaa : allaccounts) {
System.out.println(aaa);
}
}
@Test
public void testFindOne() {
// 1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.获取业务层对象
IAccountService as = ac.getBean("accountService", IAccountService.class);
// 3.执行方法
Account oneaccount = as.findAccountById(1);
System.out.println(oneaccount);
}
@Test
public void testSave() {
// 出现报错说id没有默认值,那就在数据库里面把id弄成自增
Account saveaccount = new Account();
saveaccount.setName("水野朝阳");
saveaccount.setMoney(1000f);
// 1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.获取业务层对象
IAccountService as = ac.getBean("accountService", IAccountService.class);
// 3.执行方法
as.saveAccount(saveaccount);
}
@Test
public void testUpdate() {
// 1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.获取业务层对象
IAccountService as = ac.getBean("accountService", IAccountService.class);
// 3.执行方法
Account updateaccount = as.findAccountById(2);
updateaccount.setMoney(1000f);
as.updateAccount(updateaccount);
}
@Test
public void testDelete() {
// 1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.获取业务层对象
IAccountService as = ac.getBean("accountService", IAccountService.class);
// 3.执行方法
as.deleteAccount(6);
}
}
补充知识点:
xml实体
像 “<” 和 “&” 字符在 XML 元素中都是非法的。
-
“<” 会产生错误,因为解析器会把该字符解释为新元素的开始。
-
“&” 会产生错误,因为解析器会把该字符解释为字符实体的开始。
需要使用预先定义好的实体:
< < 小于号
> > 大于号
& & 和
' ' 单引号
" " 双引号
java实体类的作用
实体类其实就是俗称的POJO,这种类一般不实现特殊框架下的接口,在程序中仅作为数据容器用来持久化存储数据用的。它的一般格式就是:
public class A implements Serializable{
private String id;
public String getId(){
return this.id;
}
public void setId(String id){
this.id = id;
}
}
其实这样写的意义就在于封装,id作为类A的成员变量,也称属性,一般情况下拥有读和写的能力,我们将id设为private,则外部无法对其直接进行操作,同时通过set方法提供了外部更改其value的方法,又通过get方法使外界能读取该成员变量的值。
而特殊情况下,我们对id可能只有读没有写的权利,即readOnly,此时我们就可以将set方法去除,只提供get方法,就可以达到目的了。
其中,代码中实体类是实现了Serializable接口的,原因有以下两点。
- 将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;
- 按值将对象从一个应用程序域发送至另一个应用程序域。
实现serializable接口的作用是就是可以把对象存到字节流,然后可以恢复。所以你想如果你的对象没实现序列化怎么才能进行网络传输呢,要网络传输就得转为字节流,所以在分布式应用中,你就得实现序列化,如果你不需要分布式应用,那就没那个必要实现序列化。