Spring学习笔记

Tips:本笔记主要信息来源为传智播客的《60集精通java教程Spring框架开发》,笔记内容为:学习资料 + 个人补充;如有内容或排版方面的错误,欢迎纠正~


内容分布

  1. spring概念和ioc入门(ioc操作xml配置文件)
  2. spring的ioc操作(注解)和aop概念
  3. jdbcTemplate和spring管理事务
  4. ssh框架整合[开发]1

Spring概念与IOC入门

Spring概念

  1. Spring是开源的轻量级框架

  2. Spring的核心包括两个部分
      -aop:面向切面编程,扩展功能不是修改源代码实现
      -ioc:控制反转
        - 比如有一个类,在类里面有方法(不是静态的方法),调用类里面的方法,创建类的对象,使用对象调用方法,创建类对象的过程,需要new出来对象。在这里,对象的创建不是通过new方式实现,而是交给spring配置创建类对象

  3. spring是一站式框架
      spring在javaee三层结构中,每一层都提供不同的解决技术
        - web层:springMVC
        - service层:spring的ioc
        - dao层:spring的jdbcTemplate

  4. Spring的版本
      -hibernate:5.x
      -Spring4.x(这里学习的版本)

Spring的ioc操作

  1. 把对象的创建交给spring进行管理
  2. ioc操作两部分:
    1)ioc的配置文件方式
    2)ioc的注解方式

IOC底层原理

  1. ioc底层原理使用技术
    (1)xml配置文件
    (2)dom4j解决xml
    (3)工厂设计模式
    (4)反射

  2. 画图分析ioc实现原理

1.1
1.2

IOC和DI区别

  1. IOC: 控制反转,把对象创建交给spring进行配置
  2. DI: 依赖注入,向类里面的属性中设置值
  3. 关系:依赖注入不能单独存在,需要在ioc基础之上完成操作

Spring整合web项目原理

Spring整合web项目原理

  1. 加载spring核心配置文件
    ApplicationContext context = new ClasssPathXmlApplicationContext("xml路径")//new 对象;的方法,功能可以实现,效率很低

  2. 实现思想:把加载配置文件和创建对象过程,在服务器启动时候完成

  3. 实现原理
    (1)ServletContext对象
    (2)监听器
    (3)具体使用:

    • 在服务器启动时候,为每个项目创建一个ServletContext对象
    • 在ServletContext对象创建时候,使用监听器可以具体到ServletContext对象在什么时候创建
    • 使用监听器监听到ServletContext对象创建时候,
      • 加载spring配置文件,把配置文件配置对象创建
      • 把创建出来的对象放到ServletContext域对象里面(setAttribute方法)
    • 获取对象时候,到ServletContext域得到(getAttribute方法)

Spring整合web项目演示

  1. 导包

    • struts2相关jar包:
      struts2相关jar包
    • Spring相关jar包
      Spring相关jar包
    • Spring-web整合包:
      Spring-web-3.0.7.jar(myeclipse2015可支持的最高版本)
  2. 代码实现之准备部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//---UserService.java---
public class UserService {
private UserDao userDao;
public void add(){
System.out.println("service........");
userDao.add();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
//---UserDao.java---
public class UserDao {
public void add(){
System.out.println("dao........");
}
}
  1. 代码实现之Spring与struts2配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!------ applicationContext.xml ------>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置userDao和userService -->
<bean id="userDao" class="cn.pinzhi.dao.UserDao"></bean>
<bean id="userService" class="cn.pinzhi.service.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>

<!------ struts.xml------>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="spring_web" namespace="/" extends="struts-default">
<action name="userAction" class="cn.pinzhi.action.UserAction" method="execute"></action>
</package>
</struts>
  1. 代码实现之spring与struts2的整合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//------web.xml------
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>spring_web</display-name>
<!-- 重要:配置struts2的核心过滤器 -->
<!--配置struts2的过滤器,要放到其他过滤器后面,保证其他过滤器可以执行 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 指定Spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean2.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

//-----UserAction.java----
public class UserAction extends ActionSupport{
@Override
public String execute() throws Exception {
System.out.println("action....");
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
UserService userService = (UserService)ctx.getBean("userService");
userService.add();
return NONE;
}
}
  1. 验证
    通过访问 localhost:8080\项目名\UserAction.action 验证

Spring的bean管理(xml)

bean实例化的方式

  在Spring中通过配置文件创建对象

  • bean实例化的三种方式

       1.使用类的无参构造方法创建(重点)

    1
    2
    <!--   若类中没有无参构造方法,会出现异常。 -->
    <bean id=“user” class=“cn.itcast.ioc.User”></bean>

       2.使用静态工厂创建

1
2
3
4
5
6
7
8
9
10
11
12
 //创建静态的方法,返回类对象
//Bean2Factory.java
public class Bean2Factory{
//静态的方法,返回Bean2对象
public static Bean2 getBean2(){
return new Bean2();
}
}

//applicationContext.xml
<!-- 使用静态工厂创建对象 -->
<bean id=“bean2” class=“cn.itcast.bean.Bean2Factory” factory-method=“getBean2”></bean>

   3.使用实例工厂创建

1
2
3
4
5
6
7
8
9
10
11
12
13
 // Bean3Factory.java
//创建非静态方法,返回类对象
public class Bean3Factory{
//普通的方法,返回Bean3对象
public Bean3 getBean3(){
return new Bean3();
}
}

//applicationContext.xml
<!-- 使用实例工厂创建对象-->
<bean id="bean3Factory" class="cn.itcast.bean.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>

Bean标签常用属性

  1. id属性:起名称,id属性值名称任意命名
    • id属性值,不能包含特殊符号
    • 根据id值得到配置对象
  2. class属性:创建对象所在类的全路径
  3. name属性:功能和id属性一样的,id属性值不能包含特殊符号,但是在name属性值里面可以包含特殊符号

  4. scope属性

    • singleton:默认值,单例
    • prototype:多例
    • request:创建对象把对象放到request域里面
    • session:创建对象把对象放到session域里面
    • globalSession:创建对象把对象放到globalSession里面

属性注入

属性注入介绍

  创建对象时候,向类里面属性里面设置值

属性注入的方式的三种方式

  1. 使用set方法注入(重点)
  2. 使用有参数构造注入
  3. 使用接口注入
    ! 在spring框架里面,支持前两种方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     //使用有参数构造注入属性
    <!-- 第一种:构造方法的方式 -->
    <bean id="car" class="cn.itcast.spring.demo4.Car">
    <constructor-arg name="name" value=" 保 时 捷 "/>
    <constructor-arg name="price" value="1000000"/> </bean>

    //------------------------------------------
    //使用set方法注入属性(重点)
    <!-- 第二种:set方法的方式 -->
    <bean id="car2" class="cn.itcast.spring.demo4.Car2">
    <property name="name" value=" 奇 瑞 QQ"/>
    <property name="price" value="40000"/>
    </bean>

注入对象类型属性(重点)

  • 具体实现过程
    (1)在service里面把dao作为类型属性
    (2)生成dao类型属性的set方法
    (3)配置文件中注入关系

相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//------------------------------------
public class UserService{
//定义一个service类,dao类为类的属性
private UserDao userDao;
//在service类中包含dao属性的set方法
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
}
//------------------------------------
<bean id="userDao" class="cn.itcast.dao.UserDao" />
<!-- 注入对象类型的属性 -->
<bean id="person" class="cn.itcast.spring.demo4.Person">
<property name="name" value=" 会 希 "/>
<!-- ref属性:引用另一个 bean的id或name -->
<property name="car2" ref="car2"/>
</bean>

P名称空间注入(Spring2.x 版本后提供的方式)

1
2
3
4
5
6
7
8
9
10
<!--第一步:引入p名称空间 -->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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">
<!--第二步:使用p名称空间.
* 普通属性: p:属性名称=””
* 对象类型属性: p:属性名称-ref=””
-->
<!-- p名称空间的属性注入的方式 -->
<bean id="car2" class="cn.itcast.spring.demo4.Car2" p:name=" 宝 马 7" p:price="1200000"/>
<bean id="person" class="cn.itcast.spring.demo4.Person" p:name=" 思 聪 " p:car2-ref="car2"/>
</beans>

SpEL 的方式的属性注入(Spring3.x 版本后提供的方式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--SpEL:Spring Expression Language. 
语法:#{ SpEL }
-->
<!-- SpEL的注入的方式 -->
<bean id="car2" class="cn.itcast.spring.demo4.Car2">
<property name="name" value="#{' 奔 驰 '}"/>
<property name="price" value="#{800000}"/>
</bean>
<bean id="person" class="cn.itcast.spring.demo4.Person">
<property name="name" value="#{'冠希'}"/>
<property name="car2" value="#{car2}"/>
</bean>
<bean id="carInfo" class="cn.itcast.spring.demo4.CarInfo">
</bean>
<!--引用了另一个类的属性 -->
<bean id="car2" class="cn.itcast.spring.demo4.Car2"> <!-- <property name="name" value="#{'奔驰'}"/> -->
<property name="name" value="#{carInfo.carName}"/>
<property name="price" value="#{carInfo.calculatePrice()}"/>
</bean>

注入复杂类型属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!-- Spring 的复杂类型的注入===================== --> 
<bean id="collectionBean" class="cn.itcast.spring.demo5.CollectionBean">
<!-- 数组类型的属性 -->
<property name="arrs">
<list>
<value>会希</value>
<value>冠希</value>
<value>天一</value>
</list>
</property>
<!-- 注入List集合的数据 -->
<property name="list">
<list>
<value>芙蓉</value>
<value>如花</value>
<value>凤姐</value>
</list>
</property>
<!-- 注入Map集合 -->
<property name="map">
<map>
<entry key="aaa" value="111"/>
<entry key="bbb" value="222"/>
<entry key="ccc" value="333"/>
</map>
</property>
<!-- Properties 的注入 -->
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>

Spring的Bean管理(注解)

注解介绍:

  1. 代码里面特殊标记,使用注解可以完成功能
  2. 注解写法 @注解名称(属性名称=属性值)
  3. 注解使用在类上面,方法上面 和 属性上面

Spring注解开发准备

  1. 导入jar包

    • 基本的jar包
      4.1

    • aop的jar包:Spring-aop-4.3.4.RELEASE.jar

  2. 创建类,创建方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public interface UserDao {
    public void sayHello();
    }

    public class UserDaoImpl implements UserDao {
    @Override
    public void sayHello() {
    System.out.println("Hello Spring...");
    }
    }
  3. 创建spring配置文件,引入约束
    (1)第一天做ioc基本功能,引入约束beans
    (2)做spring的ioc注解开发,引入新的约束
    4.2

  1. 开启注解扫描
    1
    2
    <!-- Spring 的注解开发:组件扫描(类上注解: 可以直接使用属性注入的注解) -->
    <context:component-scan base-package="com.itheima.spring.demo1"/>

注解创建对象

  1. 在创建对象的类上面使用注解实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //通过注解注册Bean
    @Component(value="userDao")
    public class UserDaoImpl implements UserDao {
    @Override
    public void sayHello() {
    System.out.println("Hello Spring Annotation...");
    }
    }

    //测试方法中获取bean对象
    @Test public void demo2() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml");
    UserDao userDao = (UserDao) applicationContext.getBean("userDao"); userDao.sayHello();
    }
  2. 创建对象有四个注解(目前这四个注解功能是一样的,都创建对象)
    (1)@Component
    (2)@Controller:web层
    (3)@Service:业务层
    (4)@Repository:持久层

! 指定创建对象单实例还是多实例的方法

1
2
3
4
5
6
7
8
9
//注解的方式
@Service(value="user")//注解bean对象
@Scope(value="prototype")//指定对象是多例,默认是单例:Singleton
public class User{
...
}

//配置文件的方式
<bean id="" class="" scope="singleton"></bean>

注解注入属性:(使用注解注入的方式,可以不用提供 set 方法.)

  • @Value :用于注入普通类型.
  • @Autowired :自动装配: * 默认按类型进行装配.
    • 按名称注入:
    • @Qualifier:强制使用名称注入.
  • @Resource相当于:
    • @Autowired和@Qualifier一起使用.

示例:

1
2
3
4
5
6
7
8
9
10
11
12
//创建dao和service对象
@Component("userDao")//value值可以省略
public class UserDao{
...
}

@Service("userService")//目前功能与Component相同
public class UserService{
@Autowired//根据类名自动匹配属性
private UserDao userDao;
@Resource(name="userDao")//通过bean名字匹配属性
private UserDao userDao2;

配置文件和注解混合使用

1
2
3
4
5
6
7
8
9
10
//使用配置文件方式实现创建对象操作
<!-- 配置对象-->
<bean id="bookDao" class="xxx.xx.xxx.bookDao"></bean>
<bean id="bookService" class="xx.xx.xx.BookService"></bean>

//使用注解方式注入属性
public class BookService{
@Resource(name="bookDao")
private BookDao bookDao;
}

AOP

AOP相关概念

  1. AOP:面向切面(方面)编程,在不修改源码的情况下扩展功能
  2. AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
  3. AOP底层使用动态代理实现
    • 第一种情况,有接口情况,(JDK 的动态代理 )使用动态代理创建接口实现类代理对象
    • 第二种情况,没有接口情况,( Cglib 的动态代理)使用动态代理创建类的子类代理对象

AOP原理

5.1
5.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Cglib 动态代理增强一个类中的方法:
public class MyCglibProxy implements MethodInterceptor{
private CustomerDao customerDao;
public MyCglibProxy(CustomerDao customerDao){
this.customerDao = customerDao;
}
// 生成代理的方法:
public CustomerDao createProxy(){
// 创建Cglib的核心类:
Enhancer enhancer = new Enhancer(); // 设置父类:
enhancer.setSuperclass(CustomerDao.class); // 设置回调:
enhancer.setCallback(this); // 生成代理:
CustomerDao customerDaoProxy = (CustomerDao) enhancer.create();
return customerDaoProxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if("delete".equals(method.getName())){
Object obj = methodProxy.invokeSuper(proxy, args);
System.out.println("日志记录================");
return obj;
}
return methodProxy.invokeSuper(proxy, args);
}
}

Spring 的基于 AspectJ 的 AOP 开发

  • 在spring里面进行aop操作,使用aspectj实现
    (1)aspectj不是spring一部分,和spring一起使用进行aop操作
    (2)Spring2.0以后新增了对AspectJ支持

  • 使用aspectj实现aop有两种方式
    (1)基于aspectj的xml配置
    (2)基于aspectj的注解方式

AOP操作术语

  1. Joinpoint(连接点): 类里面可以被增强的方法,这些方法称为连接点
  2. Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
  3. Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.
    通知分为:前置通知;后置通知;异常通知;最终通知;环绕通知(切面要完成的功能)
  4. Aspect(切面): 是切入点和通知(引介)的结合
  5. Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
  6. Target(目标对象):代理的目标对象(要增强的类)
  7. Weaving(织入):是把增强应用到目标的过程.把advice 应用到 target的过程
  8. Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

切入点表达式

 切入点,即实际增强的方法

  • 表达式格式为
    execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
    (1)execution(* cn.itcast.aop.Book.add(..))
    (2)execution(* cn.itcast.aop.Book.*(..))
    (3)execution(* *.*(..))
    (4) 匹配所有save开头的方法 execution(* save*(..))

Spring 使用 AspectJ 进行 AOP 的开发:XML 的方式(*

  1. 导包
     除了导入基本的jar包之外,还需要导入aop相关的jar包
    5.3

  2. 创建配置文件,导入aop约束

    1
    2
    3
    4
    5
    6
    7
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    </beans>
  3. 编写切面类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class MyAspectXml { 
    // 定义前置增强方法
    public void before(){
    System.out.println("前置增强===========");
    }
    // 定义后置增强方法
    public void methodName(){
    System.out.println("后置增强===========");
    }
    }
  4. 配置切入点

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!-- 配置切面类 --> 
    <bean id="myAspectXml" class="cn.itcast.spring.demo3.MyAspectXml"></bean>
    <!-- 进行 aop的配置 -->
    <aop:config>
    <!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
    <aop:pointcut expression="execution(* cn.itcast.spring.demo3.OrderDao.*(..))" id="pointcut1"/>
    <!-- 配置切面 -->
    <aop:aspect ref="myAspectXml">
    <aop:before method="before" pointcut-ref="pointcut1"/>
    <aop:after method="methodName" pointcut-ref="pointcut1"/>
    </aop:aspect>
    </aop:config>
  5. 编写测试程序

    1
    2
    3
    4
    5
    6
    7
    8
    @Test
    public void testOrderDao(){
    //获取applicationContext
    ApplicationContext ctx = new ClassPathXmlApplicationContext("bean2.xml");
    //使用接口类取得Bean
    OrderDao orderDao = (OrderDao)ctx.getBean("orderDao");
    orderDao.save();
    }

Spring 使用 AspectJ 进行 AOP 的开发:注解的方式

  1. 创建对象
1
2
3
<!-- 创建对象 -->
<bean id="book" class="cn.pinzhi.aop.Book"></bean>
<bean id="myBook" class="cn.pinzhi.aop.MyBook"></bean>
  1. 在配置文件中开启aop操作

    1
    2
    <!-- 开启aop操作 -->
    <aop:aspect-autoproxy></aop:aspectj-autoproxy>
  2. 在增强类上使用注解

    1
    2
    3
    4
    5
    6
    7
    8
    @Aspect
    public class MyBook{
    //在方法上使用注解完成增强配置
    @Before(value="execution(* cn.itcast.aop.Book.*(..))")
    public void Before1(){
    System.out.println("before...");
    }
    }

Spring的jdbcTemplate操作

jdbcTemplate引入

  1. spring框架一站式框架
    (1)针对javaee三层,每一层都有解决技术
    (2)在dao层,使用 jdbcTemplate

  2. spring对不同的持久化层技术都进行封装
    6.1

  3. jdbcTemplate使用和dbutils使用很相似,都数据库进行crud操作

用jdbcTemplate实现增删改

  1. 导入jdbcTemplate使用的jar包
    • spring-jdbc-4.2.4.RELEASE.jar
    • spring-tx-4.2.4.RELEASE.jar
    • jdbc-connector-xx.jar(依赖包)
  2. 创建对象,设置数据库信息

  3. 创建jdbcTemplate对象,设置数据源

  4. 调用jdbcTemplate对象里面的方法实现操作

    • int update(String sql,Object… args);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Test
public void update(){
//设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/Spring_day03");
dataSource.setUsername("root");
dataSource.setPassword("root");

//创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//调用jdbcTemplate里的方法实现操作
//增
String sql1 = "insert into user values(?,?)";
int rows1 = jdbcTemplate.update(sql1,"lucy","250");
System.out.println(rows1);

//删
String sql2 = "delete from user where name=?";
int rows2 = jdbcTemplate.update(sql1,"lucy");
System.out.println(rows2);

//增改
String sql3 = "update user set password=?where name =?";
int rows3 = jdbcTemplate.update(sql3,"250","lucy");
System.out.println(rows3);
}

用jdbcTemplate实现查询操作

回顾:jdbc上的查询操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 Connection conn = null;
PrepareStatement pstmt = null;
ResultSet rs = null;
try{
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//创建连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Spring_day03","root","root");
//编写sql语句
String sql = "seelect * from user where username=?";
//预编译sql
pstmt = conn.prepareStatement(sql);
//设置参数
pstmt.setString(1,"lucy");
//执行sql语句
rs = pstmt.excuteQuery();
//遍历结果集
while(rs.next()){
//得到返回的结果
String username = rs.getString("username");
String password = rs.getString("password");
User user = new User();
user.setUsername(username);
user.setPassword(password);
System.out.println(user);
}
}catch(Exception e){
}
finally{
try{
rs.close();
pstmt.close();
conn.close();
}catch(){
}
}

jdbcTemplate上的查询操作

  • 查询的种类
    • 返回结果为一个值
      使用方法:T queryForObject(String sql,Class<t> re quiredType);
      //参数1:sql语句;参数2:返回值类型.class
    • 返回结果为一个对象
      使用方法:T queryForObject(String sqlRowMapper<T> rowMapper,Object... args);
      //参数1:sql语句;参数2:RowMapper接口(要自己写);参数3:可变参数
    • 返回结果为List集合
      使用方法:List<T> query(String sqlRowMapper<T> rowMapper,Object... args);
      //参数1:sql语句;参数2:RowMapper接口(要自己写);参数3:可变参数

实现过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  //创建dataSource(略)
//创建jdbaTemplate对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//单值查询
String sql = "select count(*) from user";
int count = jdbcTemplate.queryForObject(sql,Interger.class);
System.out.println(count);

//对象查询
String sql = "select * from user where name=?";
User user = jdbcTemplate.queryForObject(sql,new MyRowMapper(),"marry");
System.out.println(user);

//对象集合查询
String sql = "select * from user";
List<User> users = jdbcTemplate.queryForObject(sql,new MyRowMapper());
System.out.println(users);

//-------Mapper.java---------
class MyRowMapper implements RowMapper<User>{
@Override
public User mapRow(ResultSet rs,int num)throws SQLException{
//从结果集中得到数据
String username = rs.getString("username");
String password = rs.getString("password");
//把得到的数据封装到对象中
User user = new User();
user.setUsername(username);
user.setPassword(password);

return user;
}
}

Spring配置连接池和dao使用jdbcTemplate

Spring配置c3p0连接池

  1. 导包
    c3p0-0.9.2.1.jar
    mchange-commons-java-0.2.3.4.jar

  2. 在Spring配置文件中配置连接池

1
2
3
4
5
6
7
8
<!-- 配置c3p0连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/Spring_day03"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>

在dao中使用jdbcTemplate

配置xml文件后就可以直接使用连接池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//---- 创建service和dao,配置service和dao对象----
//--------applicationContext.xml-------
<!-- 注入JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframwork.jdbc.core.JdbaTemplate">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="userDao" class="cn.itcast.c3p0.UserDao">
<!-- 注入jdbcTemplate对象 -->
<property name="jdbcTemplate" ref="jdbcTemplate"></bean>
</bean>
<bean id="userService" class="cn.itcast.c3p0.UserService">
<!-- 注入dao对象 -->
<property name="userDao" ref="userDao"></property>
</bean>

事务操作

回顾:事务

  1. 什么是事务?
    事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.

  2. 事务特性:

    • 原子性 :强调事务的不可分割.
    • 一致性 :事务的执行的前后数据的完整性保持一致.
    • 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰
    • 持久性 :事务一旦结束,数据就持久到数据库
  3. 如果不考虑隔离性引发安全性问题:

    • 脏读 :一个事务读到了另一个事务的未提交的数据
    • 不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
    • 虚读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.
  4. 解决读问题:设置事务隔离级别

    • 未提交读 :脏读,不可重复读,虚读都有可能发生
    • 已提交读 :避免脏读。但是不可重复读和虚读有可能发生
    • 可重复读 :避免脏读和不可重复读.但是虚读有可能发生.
    • 串行化的 :避免以上所有读问题.

Spring事务管理api

  • spring事务管理两种方式
    • 第一种 编程式事务管理(不用)
    • 第二种 声明式事务管理
      (1) 基于xml配置文件实现
      (2) 基于注解实现

相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//------基于配置文件实现------
//---Spring配置文件---
<!-- 第一步:配置事务管理器 -->
<bean id="transactionManager" class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 第二步:配置事务增强(前提:引入tx约束) -->
<tx:advice id="txadvice" transaction-manager="transaction">
<!-- 做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配规则 -->
<tx:meyhod name="acount*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 第三步 配置切面 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execute(* cn.itcast.service.OrderService.*(..))" id="ponitcut1"/>
<!-- 切面 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//------注解方式实现事务------
<!-- 第一步:配置事务管理器 -->
<bean id="transactionManager" class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 第2步:开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 第3步:在要使用事务方法所在类上面添加注解 -->
@Transactional
public class OrderService{
...
}

Tips

  1. Spring分模块开发(将配置文件中的一部分分出去)
    1
    2
    <!-- 在主配置文件中,引入其他配置文件 -->
    <import resource="classpath:user.xml" />

在最后

  Spring的基本内容已结束,随后还有ssh的整合部分,暂时不会去写,因为hibernate还没学习。谢谢你们的阅读

To be continue…


1. qqqqq
感谢你的阅读!