Spring之DI应用及JDBC模板

内容

1.DI应用之Setter方式属性注入
2.DI应用之Contructor方式属性注入
3.DI应用之P命名空间属性注入
4.DI应用之属性自动注入
5.DI应用之注解的使用
6.Spring之JDBC模板

一.使用Setter方法进行属性注入

1.简单类型属性的注入(8种基本类型及String类型)

//User
public class User {

private int id;
private String username;
private String password;
private Date birthday;

//省略setter和getter
}
<?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">

<!-- 使用类中Setter方法进行属性注入 -->

<!--1.简单类型属性的注入
property:表示属性的名称,默认会调用相应的setter方法进行属性注入
value:表示付的简单类型的值
-->
<bean id="user" class="di.model.User">
<property name="id" value="1"></property>
<property name="username" value="张三"></property>
<property name="password" value="1234"></property>
<property name="birthday" value="2018/10/10"></property>
</bean>
</beans>

2.pojo类型属性注入


//User
public class User {

private int id;
private String username;
private String password;
private Date birthday;
private Address address;

//省略setter和getter
}

//Address

public class Address {

private int id;
private String addrname;

//省略setter和getter
}
<!--2.pojo属性的注入 -->
<bean id="user2" class="di.model.User">
<property name="id" value="1"></property>
<property name="username" value="张三"></property>
<property name="password" value="1234"></property>
<property name="birthday" value="2018/10/10"></property>
<!-- 对pojo属性进行注入
其中ref属性或ref标签表示引入spring容器中相应bean对像(可以通过id或name引入)。
-->
<property name="address">
<ref bean="addr"/>
</property>
</bean>

<bean id="addr" class="di.model.Address">
<property name="id" value="1001"></property>
<property name="addrname" value="杭州"></property>
</bean>

3.集合属性注入


//User
public class User {

private Map<String,String> map;
private Set<String> set;
private List<Object> list;
//省略setter和getter
}
<!--List-->
<bean id="user3" class="di.model.User" >
<property name="list">
<!--使用list标签定义list属性注入-->
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
<!-- 可以引入外部spring子文件中bean -->
<ref bean="addr"/>
<!--也可以在内部使用bean标签定义对像,和外部bean标签一样-->
<bean class="di.model.Order">
<property name="id" value="1000"></property>
<property name="ordername" value="100号定单"></property>
<property name="price" value="2000"></property>
</bean>
</list>
</property>
</bean>

<bean id="addr" class="di.model.Address">
<property name="id" value="1001"></property>
<property name="addrname" value="杭州"></property>
</bean>
<!--set类型属性注入 -->
<bean id="user4" class="di.model.User" >
<property name="set">
<!--使用set标签定义set属性注入-->
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
</bean>
<!-- map集合属性注入 -->

<bean id="user5" class="di.model.User">
<!--使用map标签定义map属性注入-->
<property name="map">
<map>
<!--entry标签表示键值对-->
<entry>
<key><value>key1</value></key>
<value>val1</value>
</entry>
<entry>
<key><value>key2</value></key>
<value>val2</value>
</entry>
<entry>
<key><value>key3</value></key>
<value>val3</value>
</entry>
</map>
</property>
</bean>

4.properties对像属性注入


//User
public class User {

private Properties props;
//省略setter和getter
}
<!-- properties属性注入 -->
<bean id="user6" class="di.model.User">

<property name="props">
<props>
<prop key="key1">prop1</prop>
<prop key="key2">prop2</prop>
<prop key="key3">prop3</prop>
</props>
</property>
</bean>

二.Contructor方式属性注入

1.步骤


1.定义有参构造方法(一般还需要提供无参构造)
2.在applicationContext.xml文件使用<constructor-arg>标签设置即可

2.代码


<?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">

<!--
index表示构造方法中参数下标,一般下标从0开始
constructor-arg标签的数量和构造器参数的数量一致
type:参数类型,来进一步限定使用的构造方法
ref:表示引入上下文中其他的bean对像
-->
<bean id="user" class="di.model.User">
<constructor-arg index="0" value="1" type="int"></constructor-arg>
<constructor-arg index="1" value="admin" type="String"></constructor-arg>
<constructor-arg index="2" value="1234" type="String"></constructor-arg>
<constructor-arg index="3" value="20" type="int"></constructor-arg>
<constructor-arg index="4" ref="addr" ></constructor-arg>
</bean>

<bean id="addr" class="di.model.Address">
<property name="id" value="100"></property>
<property name="addrname" value="杭州"></property>
</bean>
</beans>

3.测试


@Test
public void testDI1(){
//使用构造器来实例化对像

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

User user = ac.getBean("user", User.class);
System.out.println(user.getId()+","+user.getUsername()+","+user.getPassword()+","+user.getAddr().getAddrname());

}

4.优缺点


优点:
1.比setter效率高。
缺点:
1.业务逻辑比较复杂,需要重载很多的构造方法,导致代码的书写及维护工作变的很难。

注意:一般不推荐使用构造方式注入。

三.P命名空间属性注入

1.步骤


1.在applicationContext.xml文件头部加上P命名空间
"xmlns:p="http://www.springframework.org/schema/p"
2.在bean标签中使用p:属性的方式来进行属性注入。

2.代码


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<!--引入p命名空间-->
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- P命名空间注入
简单类型使用p:属性=“值”方式来注入
pojo类型使用p:属性-ref="值"方式来注入
注意:属性其实指的是setter方法
-->
<bean id="user2" class="di.model.User" p:id="1" p:username="user" p:password="1234" p:age="20" p:addr-ref="addr"></bean>

</beans>

四.属性自动注入

1.步骤


注意:只适用于pojo类型的自动注入
1.指定属性自动注入的方式(default|no|byName|byType|constructor)
其中no|byName|byType会经常使用

2.代码


<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd" >


<!-- 3.自动注入 -->
<!--
byName:spring会到容器寻找一个bean,该bean的id或name值等于该对像中引用类型属性对应的set方法的后缀(可以理解为pojo类型属性的名字)
byType:spring会到容器寻找一个bean,会按该bean的类型去自动注入,注意:spring容器中需要注入的类型不能重复,在容器中不应该找到两个Address对像。
-->
<bean id="user3" class="di.model.User" autowire="byName"></bean>

<bean id="user4" class="di.model.User" autowire="byType"></bean>

<bean id="addr" class="di.model.Address">
<property name="id" value="200"></property>
<property name="addrname" value="上海"></property>
</bean>
</beans>

3.测试


@Test
public void testDI3(){
//自动属性注入(byName)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

User user = ac.getBean("user3", User.class);

System.out.println(user.getUsername()+","+user.getAddr().getAddrname());

}

@Test
public void testDI4(){
//自动属性注入(byType)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

User user = ac.getBean("user4", User.class);

System.out.println(user.getUsername()+","+user.getAddr().getAddrname());

}

五.注解的使用

1.常用IOC注解


1.@Component:
一般使用在类上,spring会扫描该注解对应类,并为该类创建对像。
MVC分层时,一般该注解应用于Controller层,Service层,Dao层
2.@Controller:
和@Component用法一样
MVC分层时,一般该注解应用于Controller层
3.@Service
和@Component用法一样
MVC分层时,一般该注解应用于Service层
4.@Respository:
和@Component用法一样
MVC分层时,一般该注解应用于Dao层
5.@Autowire:
一般用于pojo类型属性上,会从spring容器中织入对像到相应的属性上去(按byType来织入)。
6.@Qulifier:
一般用于pojo类型属性上,和@Autowired配合使用,转化为按bean的名称指定(按byName来织入)
7.@Resource:
一般用于pojo类型属性上,指定bean的名称去织入(按byName来织入),替代 5和 6注解。
8.@PostConstruct
一般用于方法上,表示调用构造器之后要执行的方法,等同于init-method
9.@PreDestroy
一般用于方法上,表示对像销毁前要执行的方法,等同于destory-method
10.@Scope
一般用于类上,表示对像生命周期(作用域 singleton|prototype|request|session|global session)

2.使用步骤


1.在applicationContext.xml文件头部引入命名空间
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
2.在applicationContext.xml中使用<context:component-scan base-package="包名,包名">
扫描指定包下的类,如果该类有上述IOC注解,就会为该类创建对像。
3.在类上和属性上使用合适的注解即可。

3.代码


<?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:p="http://www.springframework.org/schema/p"
<!--加入context命名空间-->
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" >

<!--base-package指定要扫描的包名:多个包之间可用逗号隔开,也可以指定总包名-->
<context:component-scan base-package="anno"></context:component-scan>

</beans>

Dao层


//spring容器会创建UserDao类的对像
//其中value属性作用是:为该对像指定name值,即相当于UserDao dao = new UserDao()
//如果没指定value值,则默认会使用类名第一个字母小写的方式作为该bean的name,即userDao为name值。
@Repository(value="dao")
public class UserDao {

public User selectById(int id){

User user = new User();
user.setId(1);

return user;
}
}

Service层


//spring容器会创建UserService类的对像
//其中value属性作用:为该容器中该对像指定name值,相当于UserService ser = new UserService()
@Service(value="ser")
public class UserService {

//该注解表示按名称自动织入UserDao对像。name表示容器中UserDao对像的name值。
//可以替代 @Autowired和@Qualifier注解
@Resource(name="dao")
//也可以使用该注解进行属性自动织入(按类型织入)
//也可和@Resource()注解一起使用 (按名称织入),其中value属性表示bean的name值
@Autowired
@Qualifier(value="dao")
private UserDao dao;


public User findById(int id){

return dao.selectById(id);
}

}

4.测试


@Test
public void testAnno(){

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-anno.xml");

UserService ser = ac.getBean("ser", UserService.class);

User user = ser.findById(1);

System.out.println(user);

}

六.Spring集成单元测试

1.原因


一般会把spring容器中的对像,织入到单元测试类中,不需要手动创建对像,使用管理。

2.步骤


1.引入spring-test.jar
2.在单元测试类上使用注解@ContextConfiguration和@RunWith
@ContextConfiguration用来加载applicationContext.xml文件
相当于ApplicationContext ac = new ClasspathXmlApplicationContext(String location);
@RunWith用来实例化SpringJUnit4ClassRunner类对像的
3.在单元测试的属性上使用@Autowired织入对像

3.代码


@RunWith(value=SpringJUnit4ClassRunner.class)
//classpath:该前缀的作用是直接定位到工程中classess文件夹下
@ContextConfiguration(value={"classpath:applicationContext-anno.xml"})
public class SpringTest {

@Autowired
UserService ser;

@Test
public void testDI(){

User user = ser.findById(1);

System.out.println(user);
}
}

七.Spring之JDBC模板

1.为什么使用JDBCTemplate


Spring JDBC是Spring所提供的持久层技术,它的主要目标是降低使用JDBC API的门槛,以一种更直接,更简洁,更
简单的方式使用JDBC API, 在Spring JDBC里,仅需做那些与业务相关的DML操作,而将资源获取,Statment创建,
资源释放以及异常处理等繁杂而乏味的工作交给Spring JDBC.
虽然ORM的框架已经成熟丰富,但是JDBC的灵活,直接的特性,依然让他拥有自己的用武之地,如在完全依赖查询
模型动态产生查询语句的综合查询系统中,Hibernaye,MyBatis,JPA等框架都无法使用,这里JDBC是唯一的选择.

2.使用步骤

2.1 引入jar包依赖


<!--引入jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.8.RELEASE</version>
</dependency>

<!--数据源-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>

<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>

2.2 使用JdbcTemplate模板Api


//Spring操作数据模板类(工具类)
JdbcTemplate
//DML操作(增删改)
JdbcTemplate.update(sql,ArgsObj....);
//DDL|DCL操作
JdbcTemplate.execute(sql)
//DQL查询单个数据
jdbcTemplate.queryForObject(String sql, RowMapper<T> var2, Object... var3);
//查询所有数据List<T>
jdbcTemplate.query(String sql, RowMapper<T> var2, Object... var3);
//返回List<Map<String,Object>>
jdbcTemplate。queryForList(String sql,Object... var3)

//注意:
其中RowWapper<T> 将结果封装的处理器; 得到Result解析成实体类对象即可!

2.3 引入资源文件


driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/javaee
user=root
password=tiger

2.5 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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 开启包扫描 -->
<context:component-scan base-package="jdbc"></context:component-scan>

<!-- 加载properties文件 -->
<context:property-placeholder location="db.properties"/>

<!-- dataSource数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>

<!--创建模板对像-->
<bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>

2.6 把模板对像织入Dao层


@Repository
public class StudentDao {
//注意:JdbcTemplate是线程安全的,可以直接作为全局变量使用
@Autowired
private JdbcTemplate temp;

//增
public void insert(Student stu){
temp.update("insert into student(sname) values(?)", new Object[]{stu.getSname()});
}
//删
public void delete(int id){
temp.update("delete from student where id = ?", id);
}
//改
public void update(Student stu){
temp.update("update student set sname=? where id=?", stu.getSname(),stu.getId());
}
//查单个对像
public Student selectById(Integer id){

Student stu = temp.queryForObject("select * from student where id = ?",new RowMapper<Student>(){
@Override
public Student mapRow(ResultSet resultset, int i) throws SQLException {

Student stu = beanHandler(resultset);

return stu;
}},id);

return stu;
}
//查总记录数
public int selectCount(){
int count = temp.queryForObject("select count(*) from Student",Integer.class);
return count;
}
//查所有
public List<Student> selectAll(){
List<Student> stu = temp.query("select * from student", new RowMapper<Student>(){
@Override
public Student mapRow(ResultSet resultset, int i) throws SQLException {

Student stu = beanHandler(resultset);

return stu;
}
});
return stu;
}

/**
* Bean封装处理器
* @param resultset
* @return
*/
public Student beanHandler(ResultSet rs){

Student stu = new Student();
try {
int id = rs.getInt("id");
String sname = rs.getString("sname");
stu.setId(id);
stu.setSname(sname);
} catch (SQLException e) {
e.printStackTrace();
}

return stu;
}
}

2.7 测试


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value="classpath:applicationContext-jdbc.xml")
public class TestJDBC2 {

@Autowired
StudentDao dao;

@Test
public void testSave(){

Student stu = new Student();
stu.setSname("张三");
dao.insert(stu);
}

@Test
public void testRemove(){

dao.delete(3);

}

@Test
public void testModify(){

Student stu = new Student();
stu.setId(1);
stu.setSname("张三");
dao.update(stu);
}

@Test
public void testFindById(){

Student stu = dao.selectById(1);
System.out.println(stu.getSname());
}

@Test
public void testFindAll(){

List<Student> list =dao.selectAll();

System.out.println(list);

}

@Test
public void testFindCount(){

int i = dao.selectCount();
System.out.println(i);
}
}

模板   Spring   DI
发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();