发表于: 2020-05-19 11:50:26
1 1358
辅导师兄
[真传弟子] JAVA-孙壮壮
加油!!!
今天完成的事:
关于spring用XML,注解,半注解方式实现mysql数据库的CRUD,并进行单元测试,下面先介绍使用纯xml的方式
首先导入相关依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</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>
JUnit 是 Java 编写语言的单元测试框架,JUnit 促进了 “先测试后编码”的理念,强调建立测试数据的一段代码,可以先测试,然后再应用。这个方法就好比“测试一点,编码一点,测试一点,编码一点...” 增强了程序员的产量和程序的稳定性,可以减少程序员的压力和排错的时间。
JUnit 有如下特点:
一个开放的资源框架,用于编写和运行测试
提供注释来识别测试方法,提供断言来运行测试,提供测试运行来运行测试
JUnit 测试可以自动运行并且检查自身结果并提供即时反馈
JUnit 在进度条中显示进度。如果运行良好则是绿色;如果运行失败,则是红色
一般 IDE 为我们提供了 JUnit 运行环境,我们只需依赖 JUnit 框架,并编写需要的测试类及测试方法。
编写实体类
public class Bmb implements Serializable {
private Integer id;
private String name;
private String qq;
private String type;
private String jointime;
private String school;
private String study_id;
private String daily_link;
private String hope;
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 String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getJointime() {
return jointime;
}
public void setJointime(String jointime) {
this.jointime = jointime;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getStudy_id() {
return study_id;
}
public void setStudy_id(String study_id) {
this.study_id = study_id;
}
public String getDaily_link() {
return daily_link;
}
public void setDaily_link(String daily_link) {
this.daily_link = daily_link;
}
public String getHope() {
return hope;
}
public void setHope(String hope) {
this.hope = hope;
}
@Override
public String toString() {
return "Bmb{" +
"id=" + id +
", name='" + name + '\'' +
", qq='" + qq + '\'' +
", type='" + type + '\'' +
", jointime='" + jointime + '\'' +
", school='" + school + '\'' +
", study_id='" + study_id + '\'' +
", daily_link='" + daily_link + '\'' +
", hope='" + hope + '\'' +
'}';
}
编写业务层接口和实现类
public interface IBmbService {
/**
* 查询所有账户
*/
List<Bmb> listAllBmbs();
/**
* 根据id查询
*/
Bmb getBmbById(Integer BmbId);
/**
* 保存
*/
void saveBmb(Bmb bmb);
/**
* 更新
*/
void updateBmb(Bmb bmb);
/**
* 删除
*/
void deleteBmb(Integer bmbId);
}
public class BmbServiceImpl implements IBmbService {
private IBmbDao bmbDao;
public void setBmbDao(IBmbDao bmbDao){
this.bmbDao = bmbDao;
}
public List<Bmb> listAllBmbs() {
return bmbDao.listAllBmbs();
}
public Bmb getBmbById(Integer bmbId) {
return bmbDao.getBmbById(bmbId);
}
public void saveBmb(Bmb bmb) {
bmbDao.saveBmb(bmb);
}
public void updateBmb(Bmb bmb) {
bmbDao.updateBmb(bmb);
}
public void deleteBmb(Integer bmbId) {
bmbDao.deleteBmb(bmbId);
}
}
编写持久层接口和实现类
public interface IBmbDao {
/**
* 查询所有账户
*/
List<Bmb> listAllBmbs();
/**
* 根据id查询
*/
Bmb getBmbById(Integer BmbId);
/**
* 保存
*/
void saveBmb(Bmb bmb);
/**
* 更新
*/
void updateBmb(Bmb bmb);
/**
* 删除
*/
void deleteBmb(Integer bmbId);
}
public class BmbDaoImpl implements IBmbDao {
private QueryRunner runner;
public void setRunner(QueryRunner runner){
this.runner = runner;
}
public List<Bmb> listAllBmbs() {
try{
return runner.query("select * from bmb",new BeanListHandler<Bmb>(Bmb.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
public Bmb getBmbById(Integer BmbId) {
try{
return runner.query("select * from bmb where id = ?",new BeanHandler<Bmb>(Bmb.class),BmbId);
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void saveBmb(Bmb bmb) {
try{
runner.update("insert into bmb(name,qq,type,jointime,school,study_id,daily_link,hope)" +
"values(?,?,?,?,?,?,?,?)",bmb.getName(),bmb.getQq(),bmb.getType(),bmb.getJointime()
,bmb.getSchool(),bmb.getStudy_id(),bmb.getDaily_link(),bmb.getHope());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void updateBmb(Bmb bmb) {
try{
runner.update("update bmb set name = ?,qq = ? where id = ?",bmb.getName(),bmb.getQq(),bmb.getId());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void deleteBmb(Integer bmbId) {
try{
runner.update("delete from bmb where id = ?",bmbId);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
编写spring的配置文件bean.xml
<?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">
<!-- 配置Service -->
<bean id="bmbService" class="com.ptt.service.impl.BmbServiceImpl">
<!-- 注入dao -->
<property name="bmbDao" ref="bmbDao"></property>
</bean>
<!--配置Dao对象-->
<bean id="bmbDao" class="com.ptt.dao.impl.BmbDaoImpl">
<!-- 注入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">
<!--连接数据库的必备信息-->
编写业务层测试文件
public class BmbServiceTest {
private ApplicationContext ac;
private IBmbService service;
@Before
public void init(){
ac = new ClassPathXmlApplicationContext("bean.xml");
service = ac.getBean("bmbService",IBmbService.class);
}
@Test
public void testListAllBmbs() {
List<Bmb> bmbs = service.listAllBmbs();
for (Bmb bmb : bmbs){
System.out.println(bmb);
}
}
@Test
public void testGetBmbById(){
Bmb bmb = service.getBmbById(13);
System.out.println(bmb);;
}
@Test
public void testSaveBmb(){
Bmb bmb = new Bmb();
bmb.setName("test");
bmb.setQq("123456");
bmb.setType("后端工程师");
bmb.setJointime("1995-5-10");
bmb.setSchool("9527");
bmb.setStudy_id("9527");
bmb.setDaily_link("http://www.jnshu.com/daily/95029?dailyType=others&total=13&page=1&uid=34292&sort=0&orderBy=3");
bmb.setHope("加油");
service.saveBmb(bmb);
}
@Test
public void testUpdateBmb(){
Bmb bmb = service.getBmbById(13);
bmb.setName("周星星");
service.updateBmb(bmb);
}
@Test
public void testdeleteBmb(){
service.deleteBmb(15);
}
}
添加@test就可对maven工程进行junit单元测试,选中方法右键点击run执行测试方法,查询测试结果
LOG4j:
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
使用LOG4j首先要在POM.XML文件中加入依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
日志输出级别一般分为四个:ERROR、WARN、INFO、DEBUG
-
ERROR 为严重错误 主要是程序的错误
WARN 为一般警告,比如session丢失
INFO 为一般要显示的信息,比如登录登出
DEBUG 为程序的调试信息 - appenderName是日志输出位置的配置的命
- org.apache.log4j.ConsoleAppender(控制台)
- org.apache.log4j.FileAppender(文件)
- org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
- org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
- org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
配置后axis.log就已经在我们指定的文件下
运行测试,就可以在log文件中看到log信息了
对于我们主要的是会用就行
关于半注解半XML方式
首先我们需要在xml配置文件中开启对注解的支持
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- 告知spring在创建容器时要扫描的包(配置注解)-->
<context:component-scan base-package="com.ptt"></context:component-scan>
我们看到
曾经XML的配置
* <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
现在是
<context:component-scan base-package="com.ptt"></context:component-scan>
业务层代码
@Service("bmbService")
public class BmbServiceImpl implements IBmbService {
@Autowired
private IBmbDao bmbDao;
/*此时不再需要set方法
public void setBmbDao(IBmbDao bmbDao){
this.bmbDao = bmbDao;
}*/ 后面不变
持久层代码
@Repository("bmbDao")
public class BmbDaoImpl implements IBmbDao {
@Autowired
private QueryRunner runner;
/*不再需要持久化(set)方法
public void setRunner(QueryRunner runner){
this.runner = runner;
}
*/ 后面不变
这里我们用到了三个标签,其实他们分为两种
第一种:用于创建对象,他们的作用和XML配置文件中编写一个<bean>标签实现的功能时一样的
作用:用于把当前类的对象存入spring容器中
属性:value 用于指定bean的id,当我们不写时,它的默认值是当前类的类名,且首字母改小写
@Service("bmbService")
public class BmbServiceImpl implements IBmbService {
有四个:Component一般下面三个都不在范围内时就用它
Controller:一般用在表现层
Service:一般用在业务层
Repository:一般用在持久层
以上三个注解他们的作用和属性与Component是一模一样的
他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰
关于Autowired注解
用于注入数据的:
他们的作用就和在xml配置文件中的bean标签中写一个property标签的作用是一样的
Autowired:注解
写的位置 可以是变量上,也可以是方法上(一般写方法上)
作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何一个bean的类型和要注入的变量类型匹配,则报错
如果ioc容器中有多个类型匹配时,先看类型,然后再看变量名称来进行匹配,如果两个都不一样就报错
细节:当使用注解来注入属性时,set方法可以省略
关于纯注解属实麻烦,太多标签要认识,这里就不说了,可以参考下面链接
https://blog.csdn.net/a1092882580/article/details/104338785
这里我们再了解下用于注入数据的注解
上面我们了解了@Autowired注解
还有@Qualifier注解
作用 :
在按照类型注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用,必须和 @Autowired 一起使用。但是在给方法参数注入时可以单独使用。
属性
value : 用于指定注入 Bean 的唯一标识 (Id)
@Resource 注解
作用 :
自动按照名称注入(By Name),直接按照 Bean 的 Id 进行注入,它可以独立使用。
属性
name : 指定注入 Bean 的 id
@Value 注解
作用
注入基于类型和 String 类型数据
属性
value : 用于指定数据的值。它可以使用 Spring 中的 SpEL( Spring 的 el 表达式,写法:${表达式})
后续我们应该根据业务来恰当的选择XML还是注解的方式
明天计划的事:准备买一台,然后这周内完成任务一
遇到的问题:学了后面感觉在慢慢忘了前面
收获:学了后面感觉在慢慢忘了前面
评论