java高级框架学习笔记

一、Spring

1. 概念

Spring 框架运行时

springruntime

1 test: spring 提供测试功能
2 Core Container:核心容器.Spring 启动最基本的条件.
2.1 Beans : Spring 负责创建类对象并管理对象
2.2 Core: 核心类
2.3 Context: 上下文参数.获取外部资源或这管理注解等
2.4 SpEl: expression.jar
3 AOP: 实现 aop 功能需要依赖
4 Aspects: 切面 AOP 依赖的包
5 Data Access/Integration : spring 封装数据访问层相关内容
5.1 JDBC : Spring 对 JDBC 封装后的代码.
5.2 ORM: 封装了持久层框架的代码.例如 Hibernate
5.3 transactions:对应 spring-tx.jar,声明式事务使

1.什么是Spring:Spring是一个基于IOC和AOP的结构J2EE系统的框架 。

2.容器(Container): Spring可以理解成一个管理类对象的大容器.
3 ApplicationContext 接口,是 BeanFactory 子接口.BeanFactory 的功能在 ApplicationContext 中都有.(BeanFactory 是老版本Spring的主要信息获得接口.)
4.从 Spring3 开始把 Spring 框架的功能拆分成多个 jar. Spring2 及以前就一个 jar

核心功能

  • IoC/DI 控制反转(IoC)/依赖注入(DI) ——解耦

  • AOP 面向切面编程 ——扩展

  • 声明式事务

2. IoC/DI

2.1 IoC控制反转

  • 不用通过new 实例化对象,而是将创建对象的控制权反转给Spring来处理。
  • 最大的作用: 解耦。

IoC创建对象的三种方式

(1)通过构造方法创建

两种构造方法创建方式

  • 无参构造创建:默认情况
  • 有参构造创建:需要明确配置

使用步骤:

①需要在类中提供有参构造方法

②在 applicationContext.xml中设置调用哪个构造方法创建对象,可以通过<constructor-arg>指定构造方法

配置参数:

index : 参数的索引,从 0 开始
name: 参数名
type:类型(区分开关键字和封装类,如: int 和 Integer)
如果设定的条件匹配多个构造方法执行最后的构造方法

(2)通过实例工厂创建

需要先创建工厂,才能生产对象。

使用步骤:

①编写实例工厂

②在applicationContext.xml中配置

1
2
<bean id="factory" class="com.qcmoke.pojo.PeopleFactory"></bean>
<bean id="peofactory" factory-bean="factory" factory-method="newInstance"></bean>

(3) 通过静态工厂创建

不需要创建工厂,快速创建对象
使用步骤:
(1)编写一个静态工厂(在方法上添加 static)
(2)在applicationContext.xml 中配置

1
<bean id="peostatic" class="com.qcmoke.pojo.PeopleStaticFactory" factory-method="newInstance"></bean>

2.2 DI依赖注入

  • 可以为Bean注入普通数据类型属性值,还可以注入其他Bean的引用。

2.3 案例

①导包:四个核心包一个日志包(commons-logging)

commons-logging-1.1.3.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar

②在 src 下新建 applicationContext.xml (文件名称和路径自定义)

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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">

<bean id="peo" class="com.qcmoke.pojo.People"/>
<!--
通过<bean/> 创建对象.
id 表示获取到对象标识
class 需要创建实例的全限定类名
-->
</beans>

默认配置文件被加载时创建对象.

③通过ApplicationContext容器调用applicationContext.xml 里配置的信息

通过调用getBean(“bean标签 id 值”,返回值类型)来获取对象;如果没有第二个参数,默认是 Object

1
2
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = ac.getBean("peo",People.class);

2. AOP

2.1 概念

AOP(Aspect Oriented Programming 面向切面编程)。 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程就叫做面向切面编程。

传统程序执行流程都是纵向执行流程,在原有纵向执行流程中添加横切面,不需要修改原有纵向程序代码就能实现原程序的扩展。

1551936068843

原有功能: 切点, pointcut

前置通知: 在切点之前执行的功能. before advice

后置通知: 在切点之后执行的功能,after advice

如果切点执行过程中出现异常,会触发异常通知.throws advice

所有功能总称叫做切面.

织入: 把切面嵌入到原有功能的过程叫做织入

特点:1.高扩展性 2.释放了部分逻辑.让职责更加明确

2.3 实现方式

有两种实现AOP的方式

  • Schema-baed
  • AspectJ

依赖:

aopalliance.jar aspectjweaver.jar
commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar

2.3.1 Schema-based

(1)配置applicationContext.xml

导入xml约束(命名空间):

1
2
3
4
5
6
7
8
9
10
<?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: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>

(2)编写切点类

Demo.java

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
package com.qcmoke.test;

/**
* 切点类
*
* @author qcmoke
*
*/
public class Demo {
public void demo1() {
System.out.println("demo1");
}

public void demo2() { //原有功能(切点)
System.out.println("demo2");
}

public void demo3() {
System.out.println("demo3");
}

public void function(Demo demo) {
demo.demo1();
demo.demo2();
demo.demo3();
}
}

(3)编写通知类

MyBeforeAdvice.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.qcmoke.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**
* 前置通知类(需要实现 MethodBeforeAdvice接口)
*
* @author qcmoke
*/
public class MyBeforeAdvice implements MethodBeforeAdvice {
/* 前置通知
* 第0个参数:切点方法对象
* 第1个参数:切点方法参数
* 第2个参数:切点方法所在的对象
* */
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {

System.out.println("\n执行前置通知");
}
}

MyAfterAdvice.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.qcmoke.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

/**
* 后置通知类(需要实现AfterReturningAdvice接口)
*
* @author qcmoke
*
*/
public class MyAfterAdvice implements AfterReturningAdvice {
/* 后置通知
* 第0个参数:切点方法返回值
* 第1个参数:切点方法对象
* 第2个参数:切点方法参数
* 第3个参数:切点方法所在的对象
* */
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("执行后置通知\n");
}
}

(4) 在applicationContext.xml配置文件里配置<aop:config>配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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: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">
<!-- 配置 Demo 类,测试使用 -->
<bean id="demo" class="com.qcmoke.test.Demo"></bean>
<!-- 配置通知类对象,在切面中引入 -->
<bean id="mybefore" class="com.qcmoke.advice.MyBeforeAdvice"></bean>
<bean id="myafter" class="com.qcmoke.advice.MyAfterAdvice"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut expression="execution(* com.qcmoke.test.Demo.demo2())" id="mypoint" /><!-- 注意星号后要有空格 -->
<!-- 通知 -->
<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint" />
<aop:advisor advice-ref="myafter" pointcut-ref="mypoint" />
</aop:config>
</beans>

(5)编写测试类

AopTest.java

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
package com.qcmoke.test;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 要求:在不改动AopDemo类的情况下,在Demo#function()里添加其他功能。
* 比如:AopDemo#demo2()方法前后输出“\n执行前置通知”和“执行后置通知\n”
*
* @author qcmoke
*
*/
public class AopTest {

@SuppressWarnings("resource")
@Test
public void testUseAop() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Demo demo = ac.getBean("demo", Demo.class);
demo.function(demo);
}

@Test
public void testNoAop() {
Demo demo = new Demo();
demo.function(demo);
}
}
2.3.2 AspectJ

(1)配置applicationContext.xml

需要将xml约束加入到applicationContext.xml文件开头。

1
2
3
4
5
6
7
8
9
10
<?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: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>

(2)编写切点类

PointObject.java

1
2
3
4
5
6
7
package com.qcmoke.test;

public class PointObject {
public void function(){// 原有功能(切点)
System.out.println("执行原有功能(切点)");
}
}

(3)编写通知类

MyAspectJAdvice.java

1
2
3
4
5
6
7
8
9
10
11
package com.qcmoke.advice;

public class MyAspectJAdvice {
public void beforefunction() {
System.out.println("执行前置通知");
}

public void afterfunction() {
System.out.println("执行后置通知");
}
}

(4) 在applicationContext.xml配置文件里配置<aop:config>配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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: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">

<!-- 配置切点类 -->
<bean id="pointObject" class="com.qcmoke.test.PointObject"></bean>

<!-- 配置通知类 -->
<bean id="aspectJAdvice" class="com.qcmoke.advice.MyAspectJAdvice"></bean>

<!-- 配置通知关联切点 -->
<aop:config>
<aop:aspect ref="aspectJAdvice">
<aop:pointcut expression="execution(* com.qcmoke.test.PointObject.function())" id="mypoint"/> <!-- 配置切点方法 -->
<aop:before method="beforefunction" pointcut-ref="mypoint"/><!-- 配置前置通知 -->
<aop:after method="afterfunction" pointcut-ref="mypoint"/><!-- 配置后置通知 -->
</aop:aspect>
</aop:config>
</beans>

(5)编写测试类

AopTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.qcmoke.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopTest {

public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
PointObject demo = ac.getBean("pointObject", PointObject.class);
demo.function();
}
}

2.4 注解方式使用AOP

通过注解实现AOP的方式其实是基于AspectJ的方式。

实现步骤:

(1)导包:

aopalliance.jar
aspectjweaver.jar
commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar

(2)配置applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

</beans>

(3)编写切点类

假设如下:

PointObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.qcmoke.test;

import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 1. 需要通过@Component声明需要被扫描的类组件,相当于<bean/>
* 如果没有参数: @Component 那么扫描后形成的Spring管理对象名称默认是首字母小写的类名
* 如果有参数: @Component("自定义的名称"),相当于<bean id="自定义的名称"/>
*
* 2. 需要通过@Pointcut("execution(* 切点名称)")指定切点方法,并给切点指定名称,一般就是方法的全限定路径
* @author qcmoke
*
*/

@Component
public class PointObject {

@Pointcut("execution(* com.qcmoke.test.PointObject.function())")
public void function(){// 原有功能(切点)
System.out.println("执行原有功能(切点)");
}
}

(4)编写通知类

MyAdvice.java

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
package com.qcmoke.advice;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* 1. 需要通过@Component声明需要被扫描的类组件,相当于<bean/>
* 如果没有参数: @Component 那么扫描后形成的Spring管理对象名称默认是首字母小写的类名
* 如果有参数: @Component("自定义的名称"),相当于<bean id="自定义的名称"/>
* 2. 需要通过@Aspect。相当于<aop:aspect/>,表示通知方法在当前类中
* 3. 通过@Before("切点名称");@AfterReturning("切点名称").....等指定通知方法
* @author qcmoke
*
*/
@Component
@Aspect
public class MyAdvice {
@Before("com.qcmoke.test.PointObject.function()")
public void beforefunction() {
System.out.println("执行前置通知");
}

@AfterReturning("com.qcmoke.test.PointObject.function()")
public void afterfunction() {
System.out.println("执行后置通知");
}
}

(5) 配置applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 扫描含有注解的包,将包路径放到base-package属性值里,如果需要扫描多个包,包路径之间可以通过逗号分隔 -->
<context:component-scan base-package="com.qcmoke.advice,com.qcmoke.test"></context:component-scan>

<!--注解都是使用cglib动态代理方式。 proxy-target-class的值为true表示cglib动态代理;为false表示jdk动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>

(6)编写测试类

AopTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.qcmoke.test;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopTest {

@Test
public void viewAllNames() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
String[] names = ac.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}

@Test
public void testForAdvice() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
PointObject pointObject = (PointObject) ac.getBean("pointObject");
pointObject.function();
}
}

3. 声明式事务

编程式事务和声明式事务的区别:

3.1 概念

  1. 编程式事务是由程序员编程事务控制代码,而声明式事务得事务控制代码已经由 spring 写好,程序员只需要简单声明出哪些方法需要进行事务控制和如何进行事务控制即可。

  2. 声明式事务针对的都是 ServiceImpl 类下需要事务处理的方法.

  3. 事务管理器基于通知(advice)的(即AOP).

3.2 实现步骤

3.3 声明式事务中属性解释

  1. **name=”” *哪些方法需要有事务控制
    1.1 支持
    通配符
  2. **readonly=”boolean” **是否是只读事务.
    2.1 如果为 true,告诉数据库此事务为只读事务.数据化优化,会对
    性能有一定提升,所以只要是查询的方法,建议使用此数据.
    2.2 如果为 false(默认值),事务需要提交的事务.建议新增,删除,修
    改.
  3. propagation 控制事务传播行为.(针对多个增删改互相调用的情况)
    3.1 当一个具有事务控制的方法被另一个有事务控制的方法调用
    后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异
    常?)
    3.2 REQUIRED (默认值): 如果当前有事务,就在事务中执行,如果当
    前没有事务,新建一个事务.
    3.3 SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事
    务,就在非事务状态下执行.
    3.4 MANDATORY:必须在事务内部执行,如果当前有事务,就在事务
    中执行,如果没有事务,报错.
    3.5 REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事
    务,如果当前有事务,把当前事务挂起.
    3.6 NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正
    常执行,如果当前有事务,把当前事务挂起.
    3.7 NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,
    如果当前有事务,报错.
    3.8 NESTED:必须在事务状态下执行.如果没有事务,新建事务,如果
    当前有事务,创建一个嵌套事务.
  4. isolation=”” 事务隔离级别
    4.1 在多线程或并发访问下如何保证访问到的数据具有完整性的.
    4.2 脏读:
    4.2.1 一个事务(A)读取到另一个事务(B)中未提交的数据,另一
    个事务中数据可能进行了改变,此时A事务读取的数据可能和数据
    库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫
    做脏读.
    4.3 不可重复读:
    4.3.1 主要针对的是某行数据.(或行中某列)
    4.3.2 主要针对的操作是修改操作.
    4.3.3 两次读取在同一个事务内
    4.3.4 当事务A第一次读取事务后,事务B对事务A读取的淑君
    进行修改,事务 A 中再次读取的数据和之前读取的数据不一致,过
    程不可重复读.
    4.4 幻读:
    4.4.1 主要针对的操作是新增或删除
    4.4.2 两次事务的结果.
    4.4.3 事务A按照特定条件查询出结果,事务B新增了一条符合
    条件的数据.事务 A 中查询的数据和数据库中的数据不一致的,事
    务 A 好像出现了幻觉,这种情况称为幻读.
    4.5 DEFAULT: 默认值,由底层数据库自动判断应该使用什么隔离界

    4.6 **READ_UNCOMMITTED: **可以读取未提交数据,可能出现脏读,不
    重复读,幻读.
    4.6.1 效率最高.
    4.7 **READ_COMMITTED:**只能读取其他事务已提交数据.可以防止脏
    读,可能出现不可重复读和幻读.
    4.8 **REPEATABLE_READ: **读取的数据被添加锁,防止其他事务修改
    此数据,可以防止不可重复读.脏读,可能出现幻读.
    4.9 **SERIALIZABLE: **排队操作,对整个表添加锁.一个事务在操作数
    据时,另一个事务等待事务操作完成后才能操作这个表.
    4.9.1 最安全的
    4.9.2 效率最低的.
  5. rollback-for=”异常类型全限定路径”
    5.1 当出现什么异常时需要进行回滚
    5.2 建议:给定该属性值.
    5.2.1 手动抛异常一定要给该属性值.
  6. no-rollback-for=””
    6.1 当出现什么异常时不滚回事务.

4. 常用注解总结

注意:

  1. 使用注解一定要添加扫描的类所在的包路径

  2. 并且尽量开启cglib动态代理,(在使用AOP时,cglib兼容service接口接收代理对象,也兼容以service实现类接收代理对象;而jdk动态代理只兼容service接口接收代理对象)

  3. 使用注解后default-autowire全局自动注入配置就不生效了。

1
2
3
4
5
6
<!-- 扫描含有注解的包,将包路径放到base-package属性值里,如果需要扫描多个包,包路径之间可以通过逗号分隔 -->
<context:component-scan base-package="com.qcmoke.advice,com.qcmoke.test"></context:component-scan>

<!--注解都是使用cglib动态代理方式。 proxy-target-class的值为true表示cglib动态代理;为false表示jdk动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
  1. @Component 创建类对象,相当于配置<bean/>
  2. @Service@Component 功能相同.
    2.1 @Service一般写在 ServiceImpl类上.
  3. @Repository@Component 功能相同.
    3.1 @Repository一般写在数据访问层类上.
  4. @Controller@Component 功能相同.
    4.1 @Controller一般写在控制器类上.
  5. @Resource(不需要写对象的 get/set)
    5.1 java 中jdk自带的注解
    5.2 默认按照 byName 注入,如果没有名称对象,按照 byType注入
    5.2.1 建议把对象名称和 spring 容器中对象名相同
  6. @Autowired(不需要写对象的 get/set)
    6.1 spring 自带的注解
    6.2 默认按照 byType 注入.
  7. @Value() 获取 properties 文件中内容
  8. @Pointcut()定义切点
  9. @Aspect() 定义切面类
  10. @Before()前置通知
  11. @After 后置通知
  12. @AfterReturning 后置通知,必须切点正确执行
  13. @AfterThrowing 异常通知
  14. @Arround 环绕通知

二、Springmvc

MVC的概念:

  • M指的是module(模型)

  • V指的是view(视图)

  • C指的是controller(控制器)

传统的MVC开发模式中:

​ M包括service,dao,pojo,bean等

​ V包括jsp,html等

​ C包括servlet

而springmvc,不同的是springmvc是不包括传统mvc开发模型的service和dao的。而是对控制层进行mvc化封装。

1. 重要核心组件

  • DispatcherServlet 前端控制器(分发器、请求入口,负责分发请求,接收所有请求,如果配置/不包含 jsp)
  • HandlerMapping 处理器映射器(解析url请求,负责请求和控制器建立一一对应的关系以此来查找Controller)
  • HandlAdapter:处理器适配器( 负责调用具体的法(Handler).)
  • Controller(Handler)后端控制器(后端处理器)
  • ViewResolver    视图解析器(定位和跳转页面,解析不同的文件

2 环境搭建

2.1 纯配置文件配置

(1)导包

commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
spring-webmvc-4.1.6.RELEASE.jar

(2) 配置前端控制器 (在web.xml中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">

<!-- 配置前端控制器 -->
<servlet>
<!-- 由于spring不能控制servlet容器,故不能控制传统的servlet。 解决方式: 只需要在web.xml中配置前端控制器DispatcherServle生效
,然后在DispatcherServle中获取所有前端发送的请求, 再将请求进行解析分配给对应的后端控制器,这些后端控制器由于不是直接受到servlet容器的控制,所以这些spring容器能够管理这些后端容器。 -->
<servlet-name>springmvc123</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springmvc文件路径和名称,让spring来管理后端控制器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!-- 让前端控制器自启动 -->
</servlet>
<servlet-mapping>
<servlet-name>springmvc123</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

(3)创建后端控制器

DemoController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.qcmoke.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class DemoController implements Controller {
/**
* http://localhost:8080/springmvc01_纯配置文件环境搭建/demo
*/
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("执行了springmvc的控制器");

//执行跳转,默认是转发到main.jsp
ModelAndView mav = new ModelAndView("main");
return mav;
}

}

(4)在src下配置springmvc.xml

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
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 后端控制器 -->
<bean id="demoController" class="com.qcmoke.controller.DemoController"></bean>


<!-- 处理器映射器(解析请求) -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<!--
key:控制器逻辑名,相当于servlet类的@WebServlet("/key")
value-ref:控制器对象,相当于servlet对象
-->
<map>
<entry key="demo" value-ref="demoController"></entry>
</map>
</property>
</bean>


<!-- 处理器适配器( 负责调用具体的方法.),需要创建Controller(Handler)后端控制器来让处理器适配器来执行 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>


<!-- 视图解析器(定位和跳转页面) -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>

2.2 注解搭建环境

(1)导包

commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
spring-webmvc-4.1.6.RELEASE.jar

(2)配置前端控制器 (在web.xml中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>myspringmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myspringmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

(3)创建后端控制器

DemoController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.qcmoke.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class DemoController {

/* 返回值表示跳转到的页面 */
@RequestMapping("demo")
public String demo() {
System.out.println("执行了demo");
return "/main.jsp";
}

@RequestMapping("demo2")
public String demo2() {
System.out.println("执行了demo2");
return "/main.jsp";
}

}

(4)在src下配置springmvc.xml

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
38
<?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:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!--
1. 配置spring-mvc xml约束
2. 注解扫描包名
3. 配置注解驱动

-->

<!-- 注解扫描包名
扫描后对象放置到springmvc容器中。
注意:springmvc是spring容器的子容器
-->
<context:component-scan base-package="com.qcmoke.controller"></context:component-scan>

<!-- 注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置注解驱动相当于配置以下:
1.HandlAdapter
2.HandlerMapping
-->

<!-- 放行静态资源,防止把静态文件当作控制器来处理 -->
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>

</beans>

3. 传参

针对于后端控制器处理方法的参数

默认要求前端传入的name名称要和控制器HandlerMethod的参数名称相同。返回值表示跳转到的页面

spring会自动将请求的数据值注入到方法的参数中,即使是bean对象,也同样会根据bean对象的get/set 方法进行注入。

  1. 参数是基本数据类型:
    默认保证参数名称和请求中传递的参数名相同即可注入
    如果请求参数名和方法参数名不对应使用@RequestParam(“请求的数据名称”)赋值,此外@RequestParam(defaultValue=“值”)可以设置参数默认值

    @RequestParam(required=true)要求请求必须传入值,否则出错

  1. 参数是对象类型

    根据请求参数名和对象中属性名对应(get/set 方法)进行注入

  1. 参数是集合类型(请求数据为多个同名参数,如复选框)

    参数使用集合即可获取注入的请求数据

    必须使用@RequestParam()

4. 设置字符编码

需要在web.xml文件中添加以下过滤器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 配置字符编码过滤器 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

三、Mybatis

spring整合mybatis

1.5.1 环境搭建:

(1) 导包

导 入 mybatis 所 有 jar 和 spring 基 本包,还有

spring-jdbc

spring-tx

spring-aop

spring-web

另外还要spring 整合 mybatis 的包mybatis-spring等

(2)配置 web.xml

目的是让tomcat启动时加载web.xml后自动加载applicationContext.xml文件(3)编写 spring 配置文件 applicationContext.xml
目的是让spring IOC/DI的作用来管理mybatis和service

1.5.2 编写代码

(1)正常编写 pojo

(2)编写 mapper,必须使用接口绑定方案或注解方案(必须有接口)

(4)正常编写 Service 接口和 Service 实现类

(5)需要在 Service 实现类中声明 Mapper 接口对象,并生成get/set 方法

四、Struts

struts执行流程简单描述图:

1553446030661

搭建步骤:

1.拷贝Struts2的核心Jar包到WEB-INF/lib/下

asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
commons-fileupload-1.3.1.jar 用于实现文件上传功能的jar包。
commons-io-2.2.jar
commons-lang3-3.2.jar
freemarker-2.3.22.jar reemarker是比jsp更简单好用,功能更加强大的表现层技术,用来替代jsp的。 在Struts2中提倡使用 freemarker模板,但实际项目中使用jsp也很多。
javassist-3.11.0.GA.jar
log4j-api-2.2.jar
log4j-core-2.2.jar
ognl-3.0.6.jar 用来支持ognl表达式的,类似于EL表达式,功能比EL表达式强大的多。
struts2-core-2.3.24.jar 核心包
xwork-core-2.3.24.jar Struts2核心包,是WebWork内核。

2.在web.xml配置前端控制器FilterDispatcher

前端控制器实际上是一个过滤器,是所有请求的入口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<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"
version="2.5">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<!-- 配置前端控制器 -->
<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>
</web-app>

3.在src下配置名称为struts.xml

名称一定要是struts.xml,这是约束条件。

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
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<!--
package:包,用于对Action进行封装。 1、name:包名,根元素下可以有多个包,彼此之间不能重名。
2、extends:继承,用于指定继承的包,相当于将继承包下的配置信息复制到了当前包下。
3、namespace:命名空间,用于规定Action的访问路径,可以是"/",也可以是"/路径名"必须以“/”开头。
4、请求Action时,按照如下格式拼写URL:
-->


<package name="day01" namespace="/demo" extends="struts-default">
<!-- action:业务控制器,用于注册业务控制器组件(类)。
1、name:action名称,用于规定Action的访问路径。
一个包下可以有多个action,彼此之间不能重名。
namespace属性值和action标签里面的name属性值构成访问路径
如果命名空间是"/"时:http://IP:PORT/ProjectName/NAMESPACE/ACTIONNAME或者http://IP:PORT/ProjectName/NAMESPACE/ACTIONNAME.action
如果命名空间是"/NAMESPACE"时:http://IP:PORT/ProjectName/NAMESPACE/ACTIONNAME或者http://IP:PORT/ProjectName/NAMESPACE/ACTIONNAME.action

2class:业务控制器组件,用于指定业务控制器对应的类。

3、method:方法,用于指定访问当前action时要调用的方法。如果不配置默认执行的方法execute方法-->

<action name="hello" class="com.qcmoke.action.HelloAction" method="sayHello">
<!--配置action方法返回值对应的页面
result:输出组件,用于转发、重定向、直接输出。
1、name:名称,一个action下可以有多个result,彼此之间不能重名。
2、默认做转发,标记内容设置成转发的页面。-->
<result name="success" type="dispatcher">
<!-- name属性:和方法返回值一样,默认值为 success
type属性:指定转发或者重定向,默认值做转发操作
dispatcher(请求转发)
redirect(重定向到页面)
redirectAction(重定向到Action)
chain(解决重定向request作用域失效) -->

/hello.jsp
</result>
</action>
</package>

<!-- 由于day02的包继承自day01,并且没有扩展功能,故day01和day02是等价的,即以下链接效果是一样的
http://localhost:8080/struts02/demo/hello.action?realName=zhangsan&age=21&user.userName=zhangsan&user.password=123456
http://localhost:8080/struts02/demo2/hello.action?realName=zhangsan&age=21&user.userName=zhangsan&user.password=123456
-->
<package name="day02" namespace="/demo2" extends="day01"></package>
</struts>

4.创建action

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.qcmoke.action;

import com.qcmoke.pojo.User;

// 案例1
public class HelloAction {

// 定义实体对象属性,接收表单参数:用户名、密码
private User user;

public void setUser(User user) {
System.out.println("注入对象user...");
this.user = user;
}

public User getUser() {
return this.user;
}

public HelloAction() {
System.out.println("实例化Action...");
}

// 定义基本类型属性,接收表单参数:姓名
private String realName;
private Integer age;

public String getRealName() {
return realName;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public void setRealName(String realName) {
System.out.println("注入参数realName...");
this.realName = realName;
}

/**
* 在业务方法中输出“Hello,Action.”
*/
public String sayHello() {

System.out.println("Hello,Action.");
// 输出基本类型数据
System.out.println("姓名:" + realName);
// 输出域模型方式注入的参数

System.out.println("用户名:" + user.getUserName());
System.out.println("密码:" + user.getPassword());

return "success";
}
}

用到的pojo类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.qcmoke.pojo;

public class User {
private String userName;// 用户名
private String password;// 密码

public String getPassword() {
return password;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public void setPassword(String password) {
this.password = password;
}
}

转发到的页面:

1
2
3
4
5
6
7
8
9
10
11
<%@page pageEncoding="utf-8"%>
<html>
<head>
</head>
<body>
<h1>Hello,Struts2.</h1>
<h1>姓名:${realName}</h1>
<h1>用户名:${user.userName }</h1>
<h1>密码:${user.password }</h1>
</body>
</html>

五、Hibernate

1. 定义

Hibernate是一个开源,轻量级的ORM(对象关系映射)工具(框架)

对象关系映射技术ORM简化了数据创建,数据处理和数据访问。它是将对象映射到数据库中存储的数据(表)的编程技术。 不需要编写数据库特定的sql语句就能完成对数据库数据的操控,一定程度上摆脱了不同数据库sql差异带来的不便。

img

orm思想

(1)让实体类和数据库表进行一一对应关系(使用配置文件完成对应联系)

  • 让实体类和数据库表对应

  • 让实体类属性和表字段对应

(2)不需要用sql语句直接操作数据库表,而是通过操控实体类对象间接操控数据表。

2. 环境搭建

下面以用户管理的案例搭建java工程项目的方式来说明步骤。

项目结果如下:

2.1 数据库准备

这里使用的是mysql作为数据库来进行讲解。首先在数据库中创建一个数据库用来存Hibernate生成的表。

sql:

1
mysql> create database ssh;

2.2 导包

antlr-2.7.7.jar
dom4j-1.6.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.7.Final.jar
hibernate-entitymanager-5.0.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar
log4j-1.2.16.jar
mysql-connector-java-5.0.4-bin.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.7.2.jar

2.3 创建实体类和对应的映射文件

实体类src/com/qcmoke/entity/User.java

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
38
39
40
41
42
package com.qcmoke.entity;

public class User {

/* hibernate要求实体类有一个属性唯一的 */
private int uid;
private String username;
private String password;
private String address;

public int getUid() {
return uid;
}

public void setUid(int uid) {
this.uid = uid;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

映射配置文件src/com/qcmoke/entity/User.hbm.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 1 配置类和表对应
class标签
name属性:实体类全路径
table属性:数据库表名称
-->
<class name="com.qcmoke.entity.User" table="t_user">
<!-- 2 配置实体类id和表id对应
hibernate要求实体类有一个属性唯一值
hibernate要求表有字段作为唯一值
-->
<!-- id标签
name属性:实体类里面id属性名称
column属性:生成的表字段名称
-->
<id name="uid" column="uid">
<!-- generator:设置数据库表id增长策略
native:生成表id值就是主键自动增长
uuid:使用uuid生成的不同随机值作为增长策略,需要实体类id属性是String类型-->
<generator class="native"></generator>
<!-- <generator class="uuid"></generator> -->
</id>
<!-- 配置其他属性和表字段对应
name属性:实体类属性名称
column属性:生成表字段名称;column属性可以省略的,不写默认和name属性值一样的
type属性:设置生成表字段的类型(Java类型,也可以是Hibernate预置的类型),不写默认自动对应类型,一般不会去配置
-->
<property name="username" column="username"></property>
<property name="password" column="password" type="string"></property>
<property name="address" column="address"></property>
</class>
</hibernate-mapping>

2.4 核心配置文

src/hibernate.cfg.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 第一部分: 配置数据库信息 必须的 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///ssh</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>

<!-- 第二部分: 配置hibernate信息 可选的-->
<property name="hibernate.show_sql">true</property> <!-- 输出底层sql语句 -->
<property name="hibernate.format_sql">true</property> <!-- 输出底层sql语句格式 -->
<property name="hibernate.hbm2ddl.auto">update</property><!-- 配置hibernate.hbm2ddl.auto之后,hibernate会自动创建表 。update: 如果已经有表,更新,如果没有,创建-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!-- 配置数据库方言。让hibernate框架识别不同数据库的自己特有的语句,比如分页语句-->

<!-- 第三部分: 把映射文件放到核心配置文件中 必须的-->
<mapping resource="com/qcmoke/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>

2.5 测试类

src/com/qcmoke/hibernatetest/HibernateTest.java

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.qcmoke.hibernatetest;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import com.qcmoke.entity.User;

public class HibernateTest {

@Test
public void testAddUser() {
/** 第一步 加载hibernate核心配置文件 */
// 到src下面找到名称hibernate.cfg.xml配置文件,创建对象,把配置文件标签放到对象里面
Configuration cfg = new Configuration();
cfg.configure();

/** 第二步 创建SessionFactory对象 */
// 读取hibernate核心配置文件内容,创建sessionFactory;在过程中,根据映射关系,在配置数据库里面把表创建。一个项目一般创建一个sessionFactory对象
SessionFactory sessionFactory = cfg.buildSessionFactory();

/** 第三步 使用SessionFactory创建session对象,session对象是单线程对象,常用方法有(1)添加 save方法;(2)修改 update方法(3)删除 delete方法(4)根据id查询 get方法 */
Session session = sessionFactory.openSession(); // 类似于连接

/** 第四步 开启事务 */
Transaction tx = session.beginTransaction();

/** 第五步 写具体逻辑 crud操作 */
// 添加功能
try {
User user = new User();
user.setUsername("qcmoke");
user.setPassword("123456");
user.setAddress("贵州");

// 调用session的方法实现添加
session.save(user);

/** 第六步 提交事务 */
tx.commit();
} catch (Exception e) {
tx.rollback(); // 回滚事务
e.printStackTrace();
} finally {
/** 第七步 关闭资源 */
session.close();
sessionFactory.close();
}
}
}

3. 三大查询对象

  • Query
  • Criteria
  • SQLQuery

3.1 Query

1 使用query对象,可以不写sql语句,但是写hql语句

(1)hql:hibernate query language,hibernate提供查询语言,这个hql语句和普通sql语句很相似

(2)hql和sql语句区别:

  • 使用sql操作表和表字段

  • 使用hql操作实体类和属性

2 查询所有hql语句:

(1)from 实体类名称

3 Query对象使用

(1)创建Query对象

(2)调用query对象里面的方法得到结果



----------- 本文结束 -----------




如果你觉得我的文章对你有帮助,你可以打赏我哦~
0%