Autowired的主要功能
这个的话,我就简单的说一下,因为网上可以说有一大堆资料和答案,本篇博客的主要目的并不是关注讲解Autowired的底层原理,所说,这里简答说一下,如果想了解更加详细,可以自己的查阅相关的资料。
Autowired的核心功能如下:
- 可以对类成员变量、方法及构造函数进行标注;
- 消除 set ,get方法;
Autowired的具体应用实例
这个也是非常核心的,本博客的主要目的就是通过一个具体的实例将Autowired应用起来,因为本人也是刚刚开始使用springMVC框架,所以,其中很多东西都不是很清楚,自己在其中也是遇到了非常多的问题。我希望通过这个实例能够帮助到初学者,节约学习的时间,将注意力集中技术上,而不是调程序上。这个小程序是围绕着Spring程序开发的核心思想设计的,还用到了MySQL作为底层的数据库,将通过程序将MySQL中的数据库中的数据进行获取,打印出来,所以整个过程分为api层、dao层以及svc层。以下详细说明每一层是如何做的,代码也给出来了。
API层
api层是一个核心的Bean,和数据库保持着紧密的联系,是数据库的核心实体类,通过实体类可以对数据库中的字段进行相关的赋值,核心就是相关的set和get方法。可以通过数据库表进行自动生成。然后出了一个对应的实体类,还有一个对应的接口,这个接口就是通过这个实体类对数据库操作的核心接口。通过实现这个接口,进而操作数据库。具体的代码如下所示:
package person.entity.dto;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
public class Person {
/**
* 序列号serialVersionUID
*/
private static final long serialVersionUID = -155072364407342260L;
/**
* 主键
* 用户信息表的主键
**/
private Long id;
/**
*
**/
private String name;
/**
*
**/
private Integer age;
/**
* 人工的工资
**/
private Double salary;
/**
* 员工的出生日期
**/
private Date birthday;
/* ------------------------ 扩展属性 ------------------------ */
public static final String TABLE = "PERSON";
public static final String KEYS = "ID";
public static final String FIELDS = "ID,NAME,AGE,SALARY,BIRTHDAY";
@Autowired(required=false)
public Long getId(){
return this.id;
}
public void setId(Long id){
this.id = id;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public Integer getAge(){
return this.age;
}
public void setAge(Integer age){
this.age = age;
}
public Double getSalary(){
return this.salary;
}
public void setSalary(Double salary){
this.salary = salary;
}
public Date getBirthday(){
return this.birthday;
}
public void setBirthday(Date birthday){
this.birthday = birthday;
}
public String toString() {
StringBuilder sb = new StringBuilder("Person [");
sb.append("id=").append(id);
sb.append(", ").append("name=").append(name);
sb.append(", ").append("age=").append(age);
sb.append(", ").append("salary=").append(salary);
sb.append(", ").append("birthday=").append(birthday);
return sb.append("]").toString();
}
}
对应的接口代码如下所示:
package person.entity.service;
import java.sql.SQLException;
import person.entity.dto.Person;
public interface IPerson {
public Person findOneByVoKeys(Person findVo) throws SQLException;
}
在数据库表中,Person表对应的字段的类型主要是String、Integer、Long以及Date类型,可以通过这个小实验将这些数据类型的处理进行介绍。
有了API后,就数据库的DAO层设计。具体代码和设计思路如下所示:
DAO层
dao层暴露的接口如下所示
package person.dao.impl;
import java.sql.SQLException;
import java.util.List;
import person.entity.dto.Person;
public interface IPersonDao {
/**
* 功能:获取一条表记录 - 查询对象方式
* @param findVo 查询字段的VO对象
* @author zhaoyuming
* @version 2020-8-11 11:01:29
* @throws SQLException
*/
public Person findOneByVoKeys(Person findVo) throws SQLException;
}
具体的实现类如下所示:
package person.dao.impl;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Repository;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
import person.entity.dto.Person;
/**
* 说明:操纵表person(个人信息表)
* @author zym
* @version 创建时间:2020-8-11 11:01:29
*/
@Repository
public class PersonDao implements IPersonDao{
public Person findOneByVoKeys(Person findVo) throws SQLException {
StringBuilder sql = new StringBuilder();
//获取用户的id
long id = findVo.getId();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("用户的ID:"+id);
sql.append("SELECT person.id,person.name,person.age,person.salary,person.birthday ");
sql.append("FROM person ");
sql.append("WHERE person.id = ");
sql.append(id);
//加载spring配置文件
System.out.println(sql.toString());
ApplicationContext ctx=new ClassPathXmlApplicationContext("person/applicationTes.xml");
//加载数据库驱动类
DataSource dataSource=ctx.getBean("dataSource",DataSource.class);
Connection connection=(Connection)dataSource.getConnection();
System.out.println("连接数据库");
Statement stm=(Statement) connection.createStatement();
System.out.println("Statement");
ResultSet rs=stm.executeQuery(sql.toString());
if(rs!=null){
System.out.println("rs有内容");
}
else{
System.out.println("rs为空,没有查询到内容");
}
while(rs.next())
{
findVo.setId(Long.parseLong(rs.getString(1)));
findVo.setName(rs.getString(2));
findVo.setAge(Integer.valueOf(rs.getString(3)));
findVo.setSalary(Double.parseDouble(rs.getString(4)));
try {
findVo.setBirthday(sdf.parse(rs.getString(5)));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("用户的id:");
System.out.println(rs.getString(1));
System.out.println("用户名为:");
System.out.println(rs.getString(2));
System.out.println("年龄为:");
System.out.println(rs.getString(3));
System.out.println("薪水:");
System.out.println(rs.getString(4));
System.out.println("出生日期:");
System.out.println(rs.getString(5).toString());
}
return findVo;
}
}
其中的dao层的具体实现类中,核心就是连接数据库,查询数据库中的一条信息,从打印出来,最为关键的说是时间数据的处理,也是非常容易错的,所以大家一定要小心。还有就是数据从数据库中查询出来后都是String类型的,要转换成和实体类中对应的字段,进行相关的数据转换。
SVC层
这一层的核心就是实现api的接口,进而连接数据库,对数据库中的数据进行相应的查询、删除、更新等。
具体的代码如下所示:
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import person.dao.impl.IPersonDao;
import person.entity.dto.Person;
import person.entity.service.IPerson;
@Repository
public class PersonService implements IPerson {
@Autowired
private IPersonDao personDao;
@Override
public Person findOneByVoKeys(Person findVo) throws SQLException {
// TODO Auto-generated method stub
System.out.println("hello findOneByVoKeys");
return personDao.findOneByVoKeys(findVo);
}
}
在这一层中用了Autowired关键字,目的就是可以将操作数据的接口注入进去。其实这里也完全可以通过对应的new形式,生成相关的对象,但是Spring都是通过注入的形式,所说义需要写成对应的Autowired。
其实到这里已经全部完成了,剩下的就是来验证以上操作的正确性,以下就是验证的程序,通过实际的结果看看以上过程的争取性。
正确性验证
具体的程序如下:
package person.test;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import person.entity.dto.Person;
import person.entity.service.IPerson;
@Service
public class ExampleTest {
@Autowired
private IPerson iPerson;
/*IPerson iPerson = (IPerson) new PersonService();*/
public void Test() throws SQLException{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
ApplicationContext contest1 = new ClassPathXmlApplicationContext("person/applicationTes.xml");
Person person1 = (Person) contest1.getBean("person");
System.out.println(person1);
Person PersonInstacen = iPerson.findOneByVoKeys(person1);
System.out.println("员工的姓名:"+PersonInstacen.getName());
System.out.println("员工的薪水:"+PersonInstacen.getSalary());
System.out.println("员工的年龄:"+PersonInstacen.getAge());
System.out.println("员工的生日:"+sdf.format(PersonInstacen.getBirthday()));
}
}
通过程序可以看到,对应的首先是注入相关的IPerson接口。进而通过相应的接口调用查询person表的过程。
最后通过一个main方法,证明以上过程的正确性。
在这里的时候,我一直遇到一个问题,困扰我很久了。我当时就是直接进行相关的单元测试,其实是行不通的,因为单元测试的时候,其实IPerson根本无法得到对应的接口对象,所以在运行的时候回报空指针错误,根本无法获取对应IPerson对象,也无法注入进去,所以需要获取以上ExampleTest 类的对象,进而生成相应的对象,最后调用相关的方法。
代码如下:
package person.test;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PersonServicetTest {
public static void main(String[] args) throws SQLException {
ApplicationContext ps=new ClassPathXmlApplicationContext("person/applicationTes.xml");
ExampleTest personService=(ExampleTest) ps.getBean("pt");
personService.Test();
}
}
对应的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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<context:component-scan base-package="person.dao.impl"/>
<context:component-scan base-package="person.services.impl"/>
<!-- <context:annotation-config/> -->
<!--配置数据相关 事物 Spring增加对事物的支持-->
<bean id="dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="自己的"></property>
<property name="username" value="自己的"></property>
<property name="password" value="自己的"></property>
</bean>
<bean id = "pt" class = "person.test.ExampleTest"></bean>
<bean id = "person" class="person.entity.dto.Person">
<property name = "id" value = "1">
</property>
</bean>
</beans>
通过上的全过程,就会将这整个过程跑通,查询到数据库中的数据,同时可以在后台中打印出来。结果如下所示:
其实整个过程的核心就是xml文件的配置以及整个架构的设计。希望能够对初学者有帮助!