Spring_AOP
1. AOP相关概念
常用的术语如下:
●Target (目标对象) :代理的目标对象
●Proxy (代理) :一个类被AOP织入增强后,就产生一 个结果代理类
●Joinpoint (连接点) :所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方
法类型的连接点
●Pointcut (切入点) :所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
●Advice (通知/增强) :所谓通知是指拦截到Joinpoint之后所要做的事情就是通知
●Weaving (织入) :是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
2. Srping_aop的动态代理
2.1.基于jdk动态代理
public class ProxyTest {
public static void main(String[] args) {
//目标对象
final Target target = new Target();
//增强对象
final Advice advice = new Advice();
//返回值是动态生成的代理对象
MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
//目标对象类加载器
target.getClass().getClassLoader(),
//目标对象的相同接口字节码数组对象
target.getClass().getInterfaces(),
new InvocationHandler() {
//调用代理对象的任何方法,实质都是调用invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前置增强
advice.before();
method.invoke(target, args);
//后置增强
advice.after();
return null;
}
}
);
proxyInstance.running();
}
}
2.2.基于cglib动态代理
public class ProxyTest {
public static void main(String[] args) {
//目标对象
final Target target = new Target();
//增强对象
final Advice advice = new Advice();
//返回值是动态生成的代理对象
//创建增强器
Enhancer enhancer = new Enhancer();
// 2. 设置父类
enhancer.setSuperclass(Target.class);
//设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
advice.before();
Object invoke = method.invoke(target, args);
advice.after();
return invoke;
}
});
//创建代理对象
Target proxy =(Target) enhancer.create();
proxy.running();
}
}
3. XML方式实现AOP
3.1实现步骤:
①导入AOP相关坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
<scope>test</scope>
</dependency>
②创建目标接口和目标类(内部有切点)
③创建切面类(内部有增强方法)
④将目标类和切面类的对象创建权交给spring
<!--目标对象-->
<bean id="target" class="cn.xxxx.proxy.aop.Target"/>
<!--切面对象-->
<bean id="myAspect" class="cn.xxxx.proxy.aop.MyAspect"/>
⑤在applicationContext.xml中配置织入关系
<!--配置织入:告诉spring那些(切点)需要增强-->
<aop:config>
<!--声明切面-->
<aop:aspect ref="myAspect">
<!--切面: 切点+通知-->
<aop:before method="beforeqian" pointcut="execution(public void cn.xxxx.proxy.aop.Target.running())"></aop:before>
</aop:aspect>
</aop:config>
⑥测试代码
3.2 切点表达式
表达式语法:
execution ([修饰符]返回值类型 包名.类名.方法名(参数))
●访问修饰符可以省略
返回值类型、包名、类名、方法名可以使用星号*代表任意
●包名与类名之间一个点代表当前包下的类,两个点…表示当前包及其子包下的类
●参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表
例如:
execut ion (public void com. ithe ima. aop. Target .method() )
execution (void com. itheima .aop. Target. *(..))
execution(* com. itheima.aop. *.*(..)
execution(* com. itheima.aop. .*.* (. .) )
execution(* *..*.*(..))
3.3 通知的类型
通知的配置语法:
<aop:通知类型method=“切面类中方法名”pointcut= "切点表达式"> </aop:通知类型>
名称 | 标签 | 说明 |
---|---|---|
前置通知 | <aop:before > | 用于配置前置通知。指定增强的方法在切入点方法之前执行 |
后置通知 | < aop:after-returning> | 用于配置后置通知。指定增强的方法在切入点方法之后执行 |
环绕通知 | < aop:around> | 用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行 |
异常抛出通知 | < aop:throwing> | 用于配置异常抛出通知。指定增强的方法在出现异常时执行 |
最终通知 | < aop:after> | 用于配置最终通知。无论增强方式执行是否有异常都会执行 |
示例:
<aop:config>
<!--声明切面-->
<aop:aspect ref="myAspect">
<!--切面: 切点+通知-->
<!--前置通知-->
<!--<aop:before method="beforeqian" pointcut="execution(public void cn.xxxx.proxy.aop.Target.running())"></aop:before>-->
<!--后置通知-->
<!--<aop:after-returning method="afterRunning" pointcut="execution(public void cn.xxxx.proxy.aop.Target.running())"></aop:after-returning>-->
<!--环绕通知 execution(任意修饰符 cn.xxxx.proxy.aop.任意类.任意方法(任意多个参数))-->
<!--<aop:around method="around" pointcut="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:around>-->
<!--异常增强-->
<aop:after-throwing method="excption" pointcut="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:after-throwing>
<!--最中增强-->
<aop:after method="after" pointcut="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:after>
</aop:aspect>
</aop:config>
切面类:
public class MyAspect {
//前置增强
public void beforeqian(){
System.out.println("前置增强");
}
//后置增强
public void afterRunning(){
System.out.println("后置增强");
}
//环绕增强
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前增强");
Object proceed = pjp.proceed();
System.out.println("环绕后增强");
return proceed;
}
//异常抛出增强
public void excption(){
System.out.println("异常抛出增强!!!");
}
//最终增强
public void after(){
System.out.println("最终增强!!!");
}
}
3.4.切点表达式的抽取
<!--切点表达式的抽取-->
<aop:pointcut id="myPointcut" expression="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:pointcut>
<aop:around method="around" pointcut-ref="myPointcut"></aop:around>
<aop:after-returning method="afterRunning" pointcut-ref="myPointcut"></aop:after-returning>
4. 基于注解的AOP开发
开发步骤:
①创建目标接口和目标类(内部有切点)
②创建切面类(内部有增强方法)
③将目标类和切面类的对象创建权交给spring
@Component("myAspect") @Component("target")
④在切面类中使用注解配置织入关系
@Aspect //标注当前类是一个切面类
public class MyAspect {
//前置增强
@Before("execution(* cn.xxxx.anno.*.*(..))")
public void beforeqian(){
System.out.println("前置增强");
}
}
⑤在配置文件中开启组件扫描和AOP的自动代理
<!--扫描包-->
<context:component-scan base-package="cn.xxxx.anno"/>
<!--aop自动代理-->
<aop:aspectj-autoproxy/>
⑥测试
4.2 注解配置aop详解
前置通知 @Before
后置通知 @AfterReturning
环绕通知 @Around
异常抛出通知 @AfterThrowing
最终通知 @After
4.2.1 使用注解切点表达式的抽取
//抽取切点表达式
@Pointcut("execution(* cn.xxxx.anno.*.*(..))")
public void pointcut(){}
//异常抛出增强
@AfterThrowing("MyAspect.pointcut()")
public void excption(){
System.out.println("异常抛出增强!!!");
}
//最终增强
@After("pointcut()")
public void after(){
System.out.println("最终增强!!!");
}
Spring 简介:
1、Spring的体系结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MiJ7UfML-1652404831826)(https://pic.baixiongz.com/uploads/2021/10/28/27a625f3634fd.png)]
2.Spring 程序开发步骤
- 导入Spring开发的基本包坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
- 编写Dao接口和实现类
@Override
public void sava() {
System.out.println("sava running");
}
3.创建Spring核心配置文件
4.在Spring配置文件中配置UserDaoImpl
//在Resource 目录下创建 configuration file --> spring sonfiguration
<?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">
//配置ID
<bean id="user" class="cn.xxxx.domain.User" scope="prototype">
<property name="name" value="三"/> // 赋初始值
<property name="age" value="15"/>
<property name="gender" value="男"/>
</bean>
</beans>
- 使用Spring的API获得Bean实例
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationControl.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.sava();
}
3. Spring 配置文件
3.1 Bean标签范围:
scope : 值对象的作用范围
取值范围 | 说明 |
---|---|
singleton | 默认值,单例的 |
prototype | 多例的 获取的地址是不同的 |
request | WEB 项目中,Spring创建一个Bean对象。将一个对象存入request域中 |
session | WEB 项目中,Spring创建一个Bean对象。将一个对象存入session域中 |
global session | WEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session |
a)、当scope 的取值为 singleton时
<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl" scope="singleton"></bean> //获取的地址是同一个 ,Bean的实例化个数为一个;
Bean实例化实际:当Spring核心文件被加载时 实例化配置的Bean实例
Bean的生命周期 :
对象创建:当应用加载 ,创建容器时,对象就被创建了
对象运行: 只要容器在,对象就一直活着
对象销毁: 当应用卸载,销毁容器时,对象就销毁了
b)、当scope 的取值为 prototype 时
<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl" scope="prototype "></bean> //获取的地址是多个 ,Bean的实例化个数多个;
Bean实例化实际:当调用getBean()方法时实例化Bean
Bean的生命周期 :
对象创建:当使用对象时,创建新的对象实例
对象运行: 只要对象在使用中,就一直活着
对象销毁: 当对象长时间不用时,被Java的回收器回收了
**3.2 依赖注入: **
3.2.1 > 分析:
因为UserService和UserDao 都在Spring容器中,而最终程序直接使用的是UserService,
所以可以在Spring容器中,将UserDao设置到UserService内部。
3.2.2 > 依赖注入概念 :
它是Spring 框架核心IOC的具体实现。
3.2.3 > 依赖注入的方式:
- 构造方法:
<bean id="userService" class="cn.xxxx.service.UserSersiceImpl" >
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
userServiceimpl:
public UserSersiceImpl(UserDao userDao) {
this.userDao = userDao;
}
public void sava(){
userDao.sava();
}
- set方法:
<bean id="userService" class="cn.xxxx.dao.impl.UserDaoImpl">
<!--对象引用类型 使用ref 普通类型使用value-->
<property name="userDao" ref="userDao"></property>
</bean>
<!-- p命名空间 注入本质也是set方法注入 首先导入P命名空间-->
xmlns:p="http://www.springframework.org/schema/p"
<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl" scope="prototype"></bean>
<bean id="userService" class="cn.xxxx.service.UserSersiceImpl" p:userDao-ref="userDao"> </bean>
main:
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.sava();
3.2.4 : 集合注入的类型 :
-
普通数据类型
-
引用数据类型
-
集合数据类型
<!--测试集合注入-->
<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl">
<property name="strList">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="mapuser">
<map>
<entry key="user1" value-ref="user1"></entry>
<entry key="user2" value-ref="user2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="aaa">12323</prop>
<prop key="bbb">144545</prop>
</props>
</property>
</bean>
<!--domian 实体类 -->
<bean id="user1" class="cn.xxxx.domain.User">
<property name="name" value="jack"/>
<property name="age" value="18"/>
<property name="gender" value="男"/>
</bean>
<bean id="user2" class="cn.xxxx.domain.User">
<property name="name" value="luck"/>
<property name="age" value="12"/>
<property name="gender" value="女"/>
</bean>
3.3 引入其他配置文件
<import resource="applicationContext-user.xml"/>
Spring的重点配置 :
<bean> 标签
id属性:在容器中bean实例的唯一标识,不允许重复
class 属性:要实例化的bean的全限定名
scope 属性:Bean 的作用范围,常是Singleton(默认)和 prototype
<property> 标签:属性注入
name属性:属性名称
value属性:注入的普通属性值
ref属性:注入的对象引用值
<list>标签
<map> 标签
<properties>标签
<constructor-arg>标签
4.Spring相关API
4.1 ApplicationContext的实现类
1> ClassPathPathXmlApplicationContext
从类的根路径下加载配置文件
2>FileSystemXmlApplicationConText
从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
public void test01() {
ApplicationContext ac = new FileSystemXmlApplicationContext("F:\\y2\\SSMKJ\\SSM_Studay\\Spring_01\\src\\main\\resources\\applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.sava();
}
3>AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建spring容器,他用看来读取注解;
4.2 getBean() 方法使用
public Object getBean()throws BeansException{
sava();
return getBean(name);
}
public <T> T getBean(Class<T> requiredType) {
sava();
return getBean(requiredType);
}
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//UserDao userDao = (UserDao) app.getBean("id");
UserDao userDao = app.getBean(UserDao.class);
userDao.sava();
5 .配置数据源
@Test
//测试创建c3p0数据源
public void test001() throws Exception {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/ssm");
comboPooledDataSource.setUser("root");
comboPooledDataSource.setPassword("lyg146837");
Connection connection = comboPooledDataSource.getConnection();
System.out.println(connection);
connection.close();
}
//c3p0加载properties文件
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
ComboPooledDataSource cd = new ComboPooledDataSource();
cd.setDriverClass(rb.getString("jdbc.driver"));
cd.setJdbcUrl(rb.getString("jdbc.url"));
cd.setUser(rb.getString("jdbc.username"));
cd.setPassword(rb.getString("jdbc.password"));
Connection connection = cd.getConnection();
System.out.println(connection);
connection.close();
@Test
//测试创建Druid数据源
public void testDruid() throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/ss");
druidDataSource.setUsername("root");
druidDataSource.setPassword("lyg146837");
DruidPooledConnection connection = druidDataSource.getConnection();
System.out.println(connection);
connection.close();
}
5.1 Spring 容器产生数据源
创建bean实例:
<!--cp30-->
<bean id="dateSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/ssm"></property>
<property name="user" value="root"></property>
<property name="password" value="lyg146837"></property>
</bean>
<!--druid数据源-->
<bean id="dateSourceds" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssm"></property>
<property name="username" value="root"></property>
<property name="password" value="lyg146837"></property>
</bean>
测试Spring 容器配置产生cp30数据源:
public void test001() throws Exception {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dateSource = (DataSource) app.getBean("dateSource");
Connection connection = dateSource.getConnection();
System.out.println(connection);
connection.close();
}
5.2 Spring 加载properties文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<!--引入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
<!--引入context地址-->
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="jdbc.properties"/>
<bean id="dateSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
6. Spring 注解开发
1. Spring 原始注解
注解名 | 作用 |
---|---|
@Component | 使用在类上用于实例化Bean |
@Controller | 使用在web层类上用于实例化Bean |
@Service | 使用在service层类上用于实例化Bean |
@Repository | 使用在dao层类上用于实例化Bean |
@Autowired | 使用在字段上用于根据类型依赖注入 |
@Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
@PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
@PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
1.1 使用注解创建bean对象
//<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl"></bean>
@Component("userDao")
1.2 使用注解注入参数
// <property name="userDao" ref="userDao"/>
@Autowired
@Qualifier("userDao")
@Resource(name="userDao") //效果同上
1.3 配置组件扫描
<!--配置组件扫描--> 告诉spring 需要扫描的包,从而找到它下面的注解
<context:component-scan base-package="cn.xxxx"/>
1.4 @Value 注入普通属性
@Value("${jdbc.driver}"); //从Spring容器中加载值,注入到属性上
private String driver;
1.5 @Scope 标注作用范围
@Scope("singleton") //允许实例化单个bean
@Scope("prototype") //允许实例化多个bean
2. Spring 新注解
注解名 | 使用说明 |
---|---|
@Configuration | 指定当前类是一个配置类 |
@ComponentScan(basePackage=“{包名1,包名2}”) | 用于通过注解指定sprig在创建容器时扫描的包 |
@Bean(name=“id叫啥”) | 用于把当前方法的返回值作为bean对象添加到IOC容器中,添加到IOC中,Bean在IOC中是以set类型存储的就必须有键值对,所以这个name属性就是当前bean的id 如果不写的话,默认是方法的全名,不做改变 当我们使用注解配置方法是,如果方法有参数,spring框架会在容器中寻找有没有可用的bean对象,寻找的方法和@Autowired是一样的 |
@Import(value=“XXX.class”) | 用于导入其他的配置类 那么有import注解的类就是父配置类,引入的就是子配置类 |
@PropertySource(value=“classpath:jdbc.properties”) | 用于指定properties文件的位置 关键字classpath代表的当前类路径下的 |
@Qualifier() | 可以用在参数修饰中,当一个类有多个对象的时候,来确定这个函数用哪一个 public QueryRunner createQueryRunner(@Qualifier(“ds2”) DataSource datasource) |
测试实例:
创建dataSource类:
// <context:property-placeholder location="jdbc.properties"/>
@PropertySource("classpath:jdbc.properties") //解析properties配置文件到容器中
public class DataSourceConfig {
@Value("${jdbc.driver}") //从容其中获取,并赋给下面对应的属性
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource") //将该方法的返回值,以指定的名称存到Spring容器中
public DataSource getDataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(username);
comboPooledDataSource.setPassword(password);
return comboPooledDataSource;
}
}
创建SpringConfig类:
@Configuration
//<context:component-scan base-package="cn.xxxx"/>
//扫描配置
@ComponentScan("cn.xxxx")
@Import({DataSourceConfig.class}) //导入DataSourceConfig数据源类
public class SpringConfig {
}
3. Spring集成Junit
导入坐标:
junit 坐标
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
springJunit 测试坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
创建测试类:
- 测试XXX.xml配置文件形式
@RunWith(SpringJUnit4ClassRunner.class) //让SpringJUnit代替原来的运行期进行测试
@ContextConfiguration("classpath:applicationContext.xml") //使用配置文件的方式告诉SpringJUnit需要测试的Spring容器
public class SpringJunitTest {
@Autowired //自动注入 如果有值 代表测试成功
private UserDaoService userService;
@Autowired
private DataSource dataSource;
@Test
public void test1() throws SQLException {
userService.save();
System.out.println(dataSource.getConnection());
}
}
- 测试使用全注解方式:
@ContextConfiguration(classes = {SpringConfig.class}) //使用quan注解方式告诉SpringJunit
7.Spring 集成Web环境
7.1基本环境搭建:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //读取配置创建Spring容器
UserService bean = app.getBean(UserService.class);
bean.save();
}
web.xml代码
<servlet>
<servlet-name>usercontrol</servlet-name>
<servlet-class>cn.xxxx.control.UserControl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>usercontrol</servlet-name>
<url-pattern>/userc</url-pattern>
</servlet-mapping>
</servlet>
7.2 ApplicationContext 获取上下文方式
7.1.1 使用监听器创建Spring容器
- 创建ContextLoad类,实现ServletContextListener接口的初始化和销毁方法:
public class ContextLoad implements ServletContextListener {
//初始化方法 当Spring创建容器时 会执行此方法
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //读取配置文件
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("app",app); //将容器存到最大的作用域中
System.out.println("创建完毕");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
- 在web.xml 文件中配置监听器
<listener>
<listener-class>cn.xxxx.listener.ContextLoad</listener-class>
</listener>
- 在servlet中使用
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext(); //创建ServletContext对象
ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app"); //从ServletContext对象中获取容器
UserService bean = app.getBean(UserService.class);
bean.save();
}
7.1.2 优化上方代码:
<!-- 创建初始化参数-->
<context-param>
<param-name>springResource</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
ContextLoad类代码:
ServletContext servletContext = servletContextEvent.getServletContext();
String springResource = servletContext.getInitParameter("springResource");
ApplicationContext app = new ClassPathXmlApplicationContext(springResource);
7.1.3 Spring 提供获取上下文工具
- 导入坐标:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
- 使用:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
ServletContext servletContext = this.getServletContext();
ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService bean = app.getBean(UserService.class);
bean.save();
}
Sping MVC
1. 简介:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TmbF9K5f-1652404831827)(https://www.fnkc.net/public/2022/01/07/47b5100bb3212.png)]
1.1 使用步骤:
- 导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
-
配置SpringMVC核心控制器DispatherServlet
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
创建Controller类和视图页面
-
使用注解配置Controller类中的业务方法的映射地址
@Controller public class UserMVCControl { @RequestMapping("/quick") public String save(){ System.out.println("Control save running!!"); return "success.jsp"; } }
-
配置SpringMVC核心文件spring-mvc.xml
<context:component-scan base-package="cn.xxxx.control"/>
2. SpringMVC 组件解析
2.1 SpringMVC 注解解析
@RequestMapping
作用: 作用于建立请求URl和处理请求方法之间的对应关系
位置: 类上,请求URl的第一级访问目录 ,不写的话,相当于应用的根目录
方法上,请求URl的第二级访问目录 ,于类上使用的@RequestMapping标注的一级目录一起组成一串虚拟路径。
@RequestMapping("/user")
public class UserMVCControl {
@RequestMapping("/quick")
public String save(){
System.out.println("Control save running!!");
return "/success.jsp"; //斜杠表示从当前应用下查找
}
}
//http://localhost:8088/spring_mvc/user/quick
参数:
@RequestMapping(value = "/quick",method = RequestMethod.POST,params = {"username"})
- value 用于指定请求的URl ,作用和path一样
- method 用于指定请求方式
- params 用于指定限制请求参数的条件,参数的key和value必须和配置的一样。
2.2 SpringMVC的XML配置解析
<!--原地址-->
return "/jsp/success.jsp";
<!--配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property> <!--前缀-->
<property name="suffix" value=".jsp"></property> <!--后缀-->
</bean>
<!--解析后-->
return "success";
小结 :
相关组件:
- 前端控制器: DispatcherServlet
- 处理器映射器 : HandlerMapping
- 处理器适配器 : HandlerAdapter
- 处理器 : Handler
- 视图解析器 : ViewResolver
- 视图 : View
3. SpringMVC 的数据响应
3.1 SpringMVC 的数据响应方式
1)页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
//第一种
@RequestMapping(value = "/quick2")
public ModelAndView save2(){
/*
Model:模型: 作用封装数据
View: 视图: 作用展示数据
*/
ModelAndView modelAndView =new ModelAndView();
//设置模型数据
modelAndView.addObject("username","lyg");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
//第二种
@RequestMapping(value = "/quick3")
public ModelAndView save3(ModelAndView modelAndView){
//设置模型数据
modelAndView.addObject("username","光");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
success.jsp页面
${username}
2)回写数据
- 直接返回字符串
@RequestMapping(value = "/quick4")
public void save4(HttpServletResponse response) throws IOException {
//设置模型数据
response.getWriter().print("hello22222");
}
@RequestMapping(value = "/quick5")
@ResponseBody //告诉Spring不要进行页面跳转 直接返回数据
public String save5(){
//设置模型数据
return "hello33333333";
}
- 返回对象或集合
- 导入mvc命名空间
- 配置处理器映射器
<!--第一种 手动配置 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
</list>
</property>
</bean>
<!--第二种:注解驱动-->
<mvc:annotation-driven/>
- 创建对象并以json形式返回
@RequestMapping(value = "/quick6")
@ResponseBody
public User save6() {
User user = new User();
user.setName("阿光");
user.setAge(21);
return user;
}
4.获得请求数据
4.1 获得请求数据
-
基本类型参数
//Control类的方法的形参名称,要和请求的name一致 http://localhost:8088/spring_mvc/user/quick7?username=guang&age=18 @RequestMapping(value = "/quick7") @ResponseBody public void save7(String username,int age) { System.out.println(username+","+age); }
-
POJO类型参数 (简单javabean)
//Control中的业务方法的POJO参数的属性名与请求的name一致,参数值会自动映射 // 其次User类中 要有getter 和setter 方法 http://localhost:8088/spring_mvc/user/quick8?name=liguang&age=21 @RequestMapping(value = "/quick8") @ResponseBody public void save8(User user) { System.out.println(user); }
-
数组类型参数
-
集合类型参数
1. 创建Vo类 创建字段类型是User的泛型集合
public class UserVo {
private List<User> userList;
public UserVo(List<User> userList) {
this.userList = userList;
}
}
2. 创建页面
<form action="<%=request.getContextPath()%>/user/quick10" method="post">
<input type="text" name="userList[0].name"/><br>
<input type="text" name="userList[0].age"/><br>
<input type="text" name="userList[1].name"/><br>
<input type="text" name="userList[1].age"/><br>
<input type="submit" value="提交">
</form>
3. 控制台输出
@RequestMapping(value = "/quick10")
@ResponseBody
public void save10(UserVo userVo) {
System.out.println(userVo);
}
4.1.2开启静态资源访问
<!-- <mvc:resources mapping="/js/**" location="/js/"/>-->
<mvc:default-servlet-handler/>
4.1.3 配置全局乱码过滤器
<!--配置全局编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.1.4 参数绑定注解@RequestParam()
参数:
- value : 与请求数据名称匹配
- required : 此在指定的请求参数是否必须包括,默认是true,提交时如果没有参数会报错 如果是flase,代表请求时参数非必须,如果没参数输出null,不报错。
- defaultValue : 当没有指定请求参数时,则使用指定的默认值赋值 默认值
http://localhost:8088/spring_mvc/user/quick12?name=222
@RequestMapping("/quick12")
@ResponseBody
public void save12(@RequestParam(value = "name",required = false,defaultValue = "guang") String username) {
System.out.println(username);
}
4.1.5 获得Restful 风格的参数
HTTP协议里的四种操作方式:
- GET : 用于获取资源 例:/user/1 GET : 得到id =1 的user
- POST : 用于新建资源 例:/user POST : 新增user
- PUT : 用于更新资源 例:/user/1 PUT :更新id=1的user
- DELETE : 用于删除资源 例:/user/1 GET : 得到id =1 的user
http://localhost:8088/spring_mvc/user/quick13/songdan
@RequestMapping("/quick13/{username}")
@ResponseBody
public void save13(@PathVariable(value = "username") String username) {
System.out.println(username);
}
//输出:
songdan
4.1.6 自定义类型转换器
-
定义转换器类实现Converter接口
public class DataConverter implements Converter<String, Date> { @Override public Date convert(String dateStr) { SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd"); Date parse = null; try { parse = format.parse(dateStr); } catch (ParseException e) { e.printStackTrace(); } return parse; } }
-
在配置文件中声明转换器
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="cn.xxxx.converter.DataConverter"></bean> </list> </property> </bean>
-
在中引用转换器
<mvc:annotation-driven conversion-service="conversionService"/>
4.2 文件上传
4.2.1 文件上传客户端的三要素
- 表单项type = “file”
- 表单的提交方式是post
- 表单的enctype属性是多部份表单形成,及enctype =“multipart/form-data”
4.2.2 单文件上传步骤
-
导入fileupload和io坐标
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.8.0</version> </dependency>
-
配置文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <property name="maxUploadSize" value="500000"/> </bean>
-
编写文件上传代码
多文件上传
3.1)、编写form表单代码
1. 第一种不同上传的文件name也不一样 <form method="post" action="<%=request.getContextPath()%>/user/quick15" enctype="multipart/form-data"> 名称<input type="text" name="username"/><br> 文件<input type="file" name="upfile"/><br> 文件<input type="file" name="upfile2"/><br> <input type="submit" value="提交"><br> </form> 2. 第二种不同上传的文件name属性一样 <form method="post" action="<%=request.getContextPath()%>/user/quick16" enctype="multipart/form-data"> 名称<input type="text" name="username"/><br> 文件<input type="file" name="upfile"/><br> 文件<input type="file" name="upfile"/><br> <input type="submit" value="提交"><br> </form>
3.2、选择文件
3.3、编写代码转移文件到新地址
1. 第一种接收的name属性不一样
@RequestMapping("/quick15")
@ResponseBody
public void save15(String username,MultipartFile upfile,MultipartFile upfile2) throws IOException {
System.out.println(username);
String originalFilename = upfile.getOriginalFilename();
upfile.transferTo(new File("F:\\newfile\\"+originalFilename));
String originalFilename2 = upfile2.getOriginalFilename();
upfile2.transferTo(new File("F:\\newfile\\"+originalFilename2));
}
transferTo("新地址提前创建"+获取到的要上传的文件);
2. 第二种接受的name属性一样
@RequestMapping("/quick16")
@ResponseBody //多个name属性一样时,使用数组接收
public void save16(String username,MultipartFile[] upfile) throws IOException {
System.out.println(username);
for (MultipartFile multipartFile : upfile) {
String originalFilename = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("F:\\newfile\\"+originalFilename));
}
}
JdbcTemplate
1. Spring JdbcTemplate 基本使用
1.1开发步骤:
-
导入spring-jdbc和spring-tx坐标
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.5.RELEASE</version> </dependency>
-
创建数据库表和实体
-
创建JdbcTemplate对象
-
执行数据库操作
//新增 @Test public void test1() throws PropertyVetoException { //创建数据源 ComboPooledDataSource dataSource =new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/ssm"); dataSource.setUser("root"); dataSource.setPassword("lyg146837"); JdbcTemplate jdbcTemplate =new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); //执行操作 int tom = jdbcTemplate.update("insert Account values(?,?)", "tom", 5000.22); System.out.println(tom); }
1.2 Spring产生JdbcTemplate对象
第一步:(配置数据源bean和jdbc模板bean)
<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
第二步:(加载ApplicationContext.xml文件)
//删除
@Test
public void test2(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate bean = app.getBean(JdbcTemplate.class);
bean.update("delete from Account where name=?","tom");
}
1.3 使用SpringTest测试JdbcTemplate模板
1.3.1 执行更新操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void test1(){
int tom = jdbcTemplate.update("update Account set money=? where name=?", 8000, "tom");
System.out.println(tom);
}
}
1.3.2 执行查询操作
@Test
public void queryAll(){
//查询全部使用query("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码))
List<Account> query = jdbcTemplate.query("select * from Account", new BeanPropertyRowMapper<Account>(Account.class));
System.out.println(query);
}
//查询单个对象queryForObject("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码),"sql参数")
Account tom = jdbcTemplate.queryForObject("select * from Account where name =?", new BeanPropertyRowMapper<Account>(Account.class), "tom");
System.out.println(tom);
1.3.4 查询记录数
@Test
public void queryCount() {
//返回值是一个普通类型,Mapper参数也是简单类型
Long count = jdbcTemplate.queryForObject("select count(*) from Account", Long.class);
System.out.println(count);
}
spring Test(练习)
1.1 Spring 环境搭建步骤
- 创建工程(Project&Module)
- 导入静态页面(jsp页面)
- 导入需要坐标(pom.xml)
- 创建包结构(controller、service、dao,domain)
- 导入数据库脚本
- 创建POJO类
- 创建配置文件(applicationContext.xml、spring-mvc.xml、jdbc.properties)
1.2 配置 web.xml 和spring、spring-mvc
<!---web.xml->
<!--全局初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring 监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- spring-mvc 前端控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--spring-->
<!-- 加载jdbc.properties文件-->
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="jdbc.driver"/>
<property name="jdbcUrl" value="jdbc.url"/>
<property name="user" value="jdbc.user"/>
<property name="password" value="jdbc.password"/>
</bean>
<!-- 配置jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--spring-mvc-->
<!--注解驱动-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 静态资源开放-->
<mvc:default-servlet-handler/>
非重点:(从数据库获取刚插入的主键)
@Override
public Long save(User user) {
PreparedStatementCreator creator = new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement("insert sys_user values(?,?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
preparedStatement.setObject(1, null);
preparedStatement.setString(2, user.getUsername());
preparedStatement.setString(3, user.getEmail());
preparedStatement.setString(4, user.getPassword());
preparedStatement.setString(5, user.getPhoneNum());
return preparedStatement;
}
};
//创建keyholder
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(creator, keyHolder);
//jdbcTemplate.update("insert sys_user values(?,?,?,?,?)",null,user.getUsername(),user.getEmail(),user.getPassword(),user.getPhoneNum());
//获得生成的主键
long userId = keyHolder.getKey().longValue();
return userId;
}
spring 的事务
1. 编程式事务相关对象
- PlatformTransactionManager
- TransactionDefinition
- TransactionStatus
2. 基于XML的声明事务相关
<!--目标对象-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--通知:事务的增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--设置事物的属性信息-->
<tx:attributes>
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"></tx:method>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--事务的aop织入-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor>
</aop:config>
3.基于注解的事务
applicationContext文件:
<!-- 配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事务驱动注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Repository("accountDao") //创建dao层实例
@Service("accountService") //创建service实例
Sping MVC
1. 简介:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jf8XFx9W-1652404831828)(https://www.fnkc.net/public/2022/01/07/47b5100bb3212.png)]
1.1 使用步骤:
- 导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
-
配置SpringMVC核心控制器DispatherServlet
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
创建Controller类和视图页面
-
使用注解配置Controller类中的业务方法的映射地址
@Controller public class UserMVCControl { @RequestMapping("/quick") public String save(){ System.out.println("Control save running!!"); return "success.jsp"; } }
-
配置SpringMVC核心文件spring-mvc.xml
<context:component-scan base-package="cn.xxxx.control"/>
2. SpringMVC 组件解析
2.1 SpringMVC 注解解析
@RequestMapping
作用: 作用于建立请求URl和处理请求方法之间的对应关系
位置: 类上,请求URl的第一级访问目录 ,不写的话,相当于应用的根目录
方法上,请求URl的第二级访问目录 ,于类上使用的@RequestMapping标注的一级目录一起组成一串虚拟路径。
@RequestMapping("/user")
public class UserMVCControl {
@RequestMapping("/quick")
public String save(){
System.out.println("Control save running!!");
return "/success.jsp"; //斜杠表示从当前应用下查找
}
}
//http://localhost:8088/spring_mvc/user/quick
参数:
@RequestMapping(value = "/quick",method = RequestMethod.POST,params = {"username"})
- value 用于指定请求的URl ,作用和path一样
- method 用于指定请求方式
- params 用于指定限制请求参数的条件,参数的key和value必须和配置的一样。
2.2 SpringMVC的XML配置解析
<!--原地址-->
return "/jsp/success.jsp";
<!--配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property> <!--前缀-->
<property name="suffix" value=".jsp"></property> <!--后缀-->
</bean>
<!--解析后-->
return "success";
小结 :
相关组件:
- 前端控制器: DispatcherServlet
- 处理器映射器 : HandlerMapping
- 处理器适配器 : HandlerAdapter
- 处理器 : Handler
- 视图解析器 : ViewResolver
- 视图 : View
3. SpringMVC 的数据响应
3.1 SpringMVC 的数据响应方式
1)页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
//第一种
@RequestMapping(value = "/quick2")
public ModelAndView save2(){
/*
Model:模型: 作用封装数据
View: 视图: 作用展示数据
*/
ModelAndView modelAndView =new ModelAndView();
//设置模型数据
modelAndView.addObject("username","lyg");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
//第二种
@RequestMapping(value = "/quick3")
public ModelAndView save3(ModelAndView modelAndView){
//设置模型数据
modelAndView.addObject("username","光");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
success.jsp页面
${username}
2)回写数据
- 直接返回字符串
@RequestMapping(value = "/quick4")
public void save4(HttpServletResponse response) throws IOException {
//设置模型数据
response.getWriter().print("hello22222");
}
@RequestMapping(value = "/quick5")
@ResponseBody //告诉Spring不要进行页面跳转 直接返回数据
public String save5(){
//设置模型数据
return "hello33333333";
}
- 返回对象或集合
- 导入mvc命名空间
- 配置处理器映射器
<!--第一种 手动配置 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
</list>
</property>
</bean>
<!--第二种:注解驱动-->
<mvc:annotation-driven/>
- 创建对象并以json形式返回
@RequestMapping(value = "/quick6")
@ResponseBody
public User save6() {
User user = new User();
user.setName("阿光");
user.setAge(21);
return user;
}
<mvc:annotation-driven conversion-service="conversionService">
<!--消息转换器:不使用默认的jackson组件-->
<mvc:message-converters register-defaults="true">
<!-- 配置FastJson工具中的消息转换器类-->
<bean id="fastJsonConverters" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 消息转换器类中的字段赋值,支持的枚举类型-->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
4. 重定向到某个页面
return "redirect:/role/list";
4.获得请求数据
4.1 获得请求数据
-
基本类型参数
//Control类的方法的形参名称,要和请求的name一致 http://localhost:8088/spring_mvc/user/quick7?username=guang&age=18 @RequestMapping(value = "/quick7") @ResponseBody public void save7(String username,int age) { System.out.println(username+","+age); }
-
POJO类型参数 (简单javabean)
//Control中的业务方法的POJO参数的属性名与请求的name一致,参数值会自动映射 // 其次User类中 要有getter 和setter 方法 http://localhost:8088/spring_mvc/user/quick8?name=liguang&age=21 @RequestMapping(value = "/quick8") @ResponseBody public void save8(User user) { System.out.println(user); }
-
数组类型参数
-
集合类型参数
1. 创建Vo类 创建字段类型是User的泛型集合
public class UserVo {
private List<User> userList;
public UserVo(List<User> userList) {
this.userList = userList;
}
}
2. 创建页面
<form action="<%=request.getContextPath()%>/user/quick10" method="post">
<input type="text" name="userList[0].name"/><br>
<input type="text" name="userList[0].age"/><br>
<input type="text" name="userList[1].name"/><br>
<input type="text" name="userList[1].age"/><br>
<input type="submit" value="提交">
</form>
3. 控制台输出
@RequestMapping(value = "/quick10")
@ResponseBody
public void save10(UserVo userVo) {
System.out.println(userVo);
}
4.1.2开启静态资源访问
<!-- <mvc:resources mapping="/js/**" location="/js/"/>-->
<mvc:default-servlet-handler/>
4.1.3 配置全局乱码过滤器
<!--配置全局编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.1.4 参数绑定注解@RequestParam()
参数:
- value : 与请求数据名称匹配
- required : 此在指定的请求参数是否必须包括,默认是true,提交时如果没有参数会报错 如果是flase,代表请求时参数非必须,如果没参数输出null,不报错。
- defaultValue : 当没有指定请求参数时,则使用指定的默认值赋值 默认值
http://localhost:8088/spring_mvc/user/quick12?name=222
@RequestMapping("/quick12")
@ResponseBody
public void save12(@RequestParam(value = "name",required = false,defaultValue = "guang") String username) {
System.out.println(username);
}
4.1.5 获得Restful 风格的参数
HTTP协议里的四种操作方式:
- GET : 用于获取资源 例:/user/1 GET : 得到id =1 的user
- POST : 用于新建资源 例:/user POST : 新增user
- PUT : 用于更新资源 例:/user/1 PUT :更新id=1的user
- DELETE : 用于删除资源 例:/user/1 GET : 得到id =1 的user
http://localhost:8088/spring_mvc/user/quick13/songdan
@RequestMapping("/quick13/{username}")
@ResponseBody
public void save13(@PathVariable(value = "username") String username) {
System.out.println(username);
}
//输出:
songdan
4.1.6 自定义类型转换器
-
定义转换器类实现Converter接口
@Component public class DataConverter implements Converter<String, Date> { @Override public Date convert(String dateStr) { SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd"); Date parse = null; try { parse = format.parse(dateStr); } catch (ParseException e) { e.printStackTrace(); } return parse; } }
-
在配置文件中声明转换器
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="cn.xxxx.converter.DataConverter"></bean> </list> </property> </bean>
-
在中引用转换器
<mvc:annotation-driven conversion-service="conversionService"/>
4.2 文件上传
4.2.1 文件上传客户端的三要素
- 表单项type = “file”
- 表单的提交方式是post
- 表单的enctype属性是多部份表单形成,及enctype =“multipart/form-data”
4.2.2 单文件上传步骤
-
导入fileupload和io坐标
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.8.0</version> </dependency>
-
配置文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <property name="maxUploadSize" value="500000"/> </bean>
-
编写文件上传代码
多文件上传
3.1)、编写form表单代码
1. 第一种不同上传的文件name也不一样 <form method="post" action="<%=request.getContextPath()%>/user/quick15" enctype="multipart/form-data"> 名称<input type="text" name="username"/><br> 文件<input type="file" name="upfile"/><br> 文件<input type="file" name="upfile2"/><br> <input type="submit" value="提交"><br> </form> 2. 第二种不同上传的文件name属性一样 <form method="post" action="<%=request.getContextPath()%>/user/quick16" enctype="multipart/form-data"> 名称<input type="text" name="username"/><br> 文件<input type="file" name="upfile"/><br> 文件<input type="file" name="upfile"/><br> <input type="submit" value="提交"><br> </form>
3.2、选择文件
3.3、编写代码转移文件到新地址
1. 第一种接收的name属性不一样
@RequestMapping("/quick15")
@ResponseBody
public void save15(String username,MultipartFile upfile,MultipartFile upfile2) throws IOException {
System.out.println(username);
String originalFilename = upfile.getOriginalFilename();
upfile.transferTo(new File("F:\\newfile\\"+originalFilename));
String originalFilename2 = upfile2.getOriginalFilename();
upfile2.transferTo(new File("F:\\newfile\\"+originalFilename2));
}
transferTo("新地址提前创建"+获取到的要上传的文件);
2. 第二种接受的name属性一样
@RequestMapping("/quick16")
@ResponseBody //多个name属性一样时,使用数组接收
public void save16(String username,MultipartFile[] upfile) throws IOException {
System.out.println(username);
for (MultipartFile multipartFile : upfile) {
String originalFilename = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("F:\\newfile\\"+originalFilename));
}
}
JdbcTemplate
1. Spring JdbcTemplate 基本使用
1.1开发步骤:
-
导入spring-jdbc和spring-tx坐标
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.5.RELEASE</version> </dependency>
-
创建数据库表和实体
-
创建JdbcTemplate对象
-
执行数据库操作
//新增 @Test public void test1() throws PropertyVetoException { //创建数据源 ComboPooledDataSource dataSource =new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/ssm"); dataSource.setUser("root"); dataSource.setPassword("lyg146837"); JdbcTemplate jdbcTemplate =new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); //执行操作 int tom = jdbcTemplate.update("insert Account values(?,?)", "tom", 5000.22); System.out.println(tom); }
1.2 Spring产生JdbcTemplate对象
第一步:(配置数据源bean和jdbc模板bean)
<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
第二步:(加载ApplicationContext.xml文件)
//删除
@Test
public void test2(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate bean = app.getBean(JdbcTemplate.class);
bean.update("delete from Account where name=?","tom");
}
1.3 使用SpringTest测试JdbcTemplate模板
1.3.1 执行更新操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void test1(){
int tom = jdbcTemplate.update("update Account set money=? where name=?", 8000, "tom");
System.out.println(tom);
}
}
1.3.2 执行查询操作
@Test
public void queryAll(){
//查询全部使用query("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码))
List<Account> query = jdbcTemplate.query("select * from Account", new BeanPropertyRowMapper<Account>(Account.class));
System.out.println(query);
}
//查询单个对象queryForObject("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码),"sql参数")
Account tom = jdbcTemplate.queryForObject("select * from Account where name =?", new BeanPropertyRowMapper<Account>(Account.class), "tom");
System.out.println(tom);
1.3.4 查询记录数
@Test
public void queryCount() {
//返回值是一个普通类型,Mapper参数也是简单类型
Long count = jdbcTemplate.queryForObject("select count(*) from Account", Long.class);
System.out.println(count);
}
数据校验:
//实体类:
@NotNull(message = "用户id不能为空")
private Integer id;
@NotNull
@Length(min = 2, max = 8, message = "用户名不能少于2位大于8位")
private String name;
@Email(regexp = "[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]", message = "邮箱格式不正确")
private String email;
Controller:
@Controller
public class UserController {
@RequestMapping("/validate")
public String validate(@Valid User user, BindingResult result) {
// 如果有异常信息
if (result.hasErrors()) {
// 获取异常信息对象
List<ObjectError> errors = result.getAllErrors();
// 将异常信息输出
for (ObjectError error : errors) {
System.out.println(error.getDefaultMessage());
}
}
return "index";
}
@RequestMapping(value = "/addUser")
public String add() {
return "addUser";
}
}
拦截器
1. 方法及介绍
方法名 | 介绍 |
---|---|
preHandle() | 目标方法请求处理执行之前调用返回布尔值,如果返回true,则继续执行,false则不再执行,多个HandInterceptor的情况下,并且返回true 会先执行下一个Interceptor的preHandle()方法; |
postHandle() | 目标方法执行之后,视图返回之前执行 |
afterCompletion() | 所有流程执行完毕之后执行 |
2. 使用步骤
-
创建拦截器类实现HandInterceptor接口
测试要拦截的方法:
@Controller public class MvcControl { @RequestMapping("/test") public ModelAndView show() { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("hello", "3爱香香"); modelAndView.setViewName("index"); return modelAndView; } }
public class MyIntercepter implements HandlerInterceptor { //目标方法执行之前执行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取请求参数 String param = request.getParameter("param"); if("yes".equals(param)){ return true;//如为true,可放行, }else { request.getRequestDispatcher("/error.jsp").forward(request,response); return false;//如为false,目标方法不执行,postHandle(),afterCompletion()也不执行 } } //目标方法执行之后,视图返回之前执行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { modelAndView.addObject("hello","3不爱香香"); //修改modelAndView的值 System.out.println("方法执行之后,视图返回之前"); } //所有流程执行完毕之后执行 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("所有流程执行完毕之后执行"); } }
-
在spring-mvc配置文件中配置interceptor拦截器
<!-- 配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!--path:表示对哪个方法进行拦截--> <mvc:mapping path="/**"/> <!--对哪些资源放行--> <mvc:exclude-mapping path="/user/login"/> <bean class="cn.xxxx.interceptor.MyIntercepter"/> </mvc:interceptor> </mvc:interceptors>
-
实现拦截效果
SpringMvc 异常处理
-
简单映射异常
<!--创建异常处理器--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--默认异常--> <!-- <property name="defaultErrorView" value="error"/>--> <!--手动配置捕捉的异常--> <property name="exceptionMappings"> <map> <entry key="java.lang.ClassCastException" value="error1"/> <entry key="java.lang.ClassCastException" value="error2"/> </map> </property> </bean>
-
自定义异常类处理异常
步骤:
- 创建异常处理器类实现HandlerExceptionResolver
- 配置异常处理器
- 编写异常页面
- 测试异常跳转
1. 框架概述:
a)、三层架构
- 页面层: 和用户打交道,接收请求的参数,显示处理结果: jsp html 、servlet
- 业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库。获取数据
- 数据访问层: 访问数据库 执行对数据的查询、修改删除等操作;
所对应的包 及其框架:
界面层: controller 包(servlet) springmvc (框架)
业务逻辑层: service 包(XXXXservice) 类 spring (框架)
数据访问层 :dao 包 (XXXXXDao类) mybatis (框架)
交互:
用户使用界面层<–>业务逻辑层<–>数据访问层<–>数据库(mysql);
b)、 框架
框架是一个模板; 规定了一些条款,内容,加入自己的东西;
MyBatis SQL Mapper Framework for Java (sql映射框架)
- sql mapper :sql 映射
可以把数据库表中的数据,映射为一个java对象一行数据可以被看作一个java对象,操作这个对象 相当于操作表中的数据。
- Data Access Objects(DAOs) : 对数据库执行增、删、改、查;
**mybatis 提供的功能: **
创建Connection,Statement、ResultSet的能力,
以及执行sql语句,循环sql 把sql的结果转为java对象,List集合,
还有关闭Connection,Statement、ResultSet资源的能力 ;
开发人员只需提供:sql语句 ;
2. MyBatis 框架快捷入门
a)、实现步骤 例子:
- 新建student 表
- 加入maven的mybatis 坐标,和mysql的驱动坐标;
- 创建实体类,Student 保存表中的一行数据
- 创建持久dao接口 定义操作数据库的方法;
- 创建一个mybatis使用的配置文件
创建在和dao层接口同一目录下; 名字最好和接口保持一致
叫做sql映射文件 :写sql语句 。一般一个表对应一个sql 映射 ,是xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
<!--约束文件检查标签、属性必须符合规则-->
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper当前文件的跟标签 必须的,namespace 是指命名空间 一般写接口的全限定名称-->
<mapper namespace="org.mybatis.example.BlogMapper">
<!--id 是select语句的唯一标识 写语句对应的方法名-->
<!--resultType 是sql语句执行后得到的ResultSet 遍历他得到的java类型 值一般写类型的全限定名称-->
//查询方法
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
//新增方法
<insert id="insertStudent">
insert student values(#{字段名1},#{字段名2},#{字段名3},#{字段名4});
</insert>
</mapper>
- 创建mybatis 的主配置文件 一个项目只有一个主配置文件
主配置文件包含了数据库连接信息 和sql映射文件的位置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--设置myBatis日志输出到控制台-->
<settings>
<setting name="logImpl" value="StDOUT_LOGGING"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- mapper编译后的路径-->
<mapper resource="cn/guang/dao/StudentDao.xml"/>
</mappers>
</configuration>
加入插件 :
<resources>
<resource>
<directory>src/main/resources/${env}</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
- 创建使用mybatis类
通过mybatis访问数据库 ;
import org.apache.ibatis.io.Resources;
//获取主文件
String config = "mybatis.xml";
//读取文件
// InputStream ins = Resources.getResourceAsStream(config);
InputStream ins = myAPP.class.getClassLoader().getResourceAsStream(config);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(ins);
//**重要
SqlSession sqlSession = factory.openSession();
//重要指定要执行的sql语句的标识 namespace +"."+ id
String sqlIdsls = "cn.guang.dao.StudentDao" + "." + "selectAll";
String sqlIdins = "cn.guang.dao.StudentDao" + "." + "insertStudent";
List<Student> studentList = sqlSession.selectList(sqlIdsls);
for (Student stu : studentList) {
System.out.println(stu);
}
//执行inert的结果
int insert = sqlSession.insert(sqlIdins, student);
//myBatyis 默认不提交事务 执行insert delete update 之后需要手动提交事务
sqlSession.commit();
sqlSession.close();
**b)、 工具类使用 **
创建 MyBatis 工具类:
static SqlSessionFactory sqlSessionFactory = null;
static {
String config = "mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(config);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
if (sqlSessionFactory != null) {
sqlSession = sqlSessionFactory.openSession();
}
return sqlSession;
}
创建类获取方式:
public static void main(String[] args) {
//**重要
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//重要指定要执行的sql语句的标识 namespace +"."+ id
String sqlId = "cn.guang.dao.StudentDao.selectAll";
List<Student> studentList = sqlSession.selectList(sqlId);
for (Student stu : studentList) {
System.out.println(stu);
}
sqlSession.close();
}
c)、创建mybatis 的mapper和主配置文件模板
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vm0Chbgt-1652404831829)(C:\Users\李桑\AppData\Roaming\Typora\typora-user-images\image-20211107222423393.png)]
3. MyBatis 框架Dao代理 ※
使用动态代理的要求:
- mapper 文件的namespace 一定要是dao接口的全限定名称
- mapper 文件中的标签id 是dao 接口的方法名称
a)、mybatis 的动态代理
根据你提供的接口,创键出实现类,并创建这个类的对象搜索,完成qlSession 调用方法 并访问数据库;
使用mybatis的动态代理机制 ,使用sqlSession.getmapper( dao接口) 获取dao接口的实现类对象;
//不用创建到接口impl实现类
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
List<Student> studentList = mapper.selectStudents();
for (Student stu : studentList) {
System.out.println(stu);
}
*b)、理解参数
parameterType: 表示参数的类型
<select id="selectById" parameterType="java.lang.Integer" <!--指定mybatis接受的参数类型是Integer类型-->
resultType="cn.guang.entity.Student">
select *
from student
where id = #{id}
</select>
类型别名: (不区分大小写) parameterType= “可直接写别名”
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
c)、dao接口有一个简单类型参数
dao接口中方法的参数只有一个简单类型,(java基本类型和String ) 占位符 #{任意字符} 和方法的参数名无关;
<select id="selecyByemail" parameterType="string"
resultType="cn.guang.entity.Student">
select *
from student
where email = #{email} <!--任意字符-->
</select>
d)、dao接口有多个简单类型参数:
@Param 命名参数
Student selecyBynameAndage(@Param("myName") String name,@Param("myAge") Integer age);
mapper 配置文件:
<select id="selecyBynameAndage" resultType="cn.guang.entity.Student">
select *
from student
where name = #{myName}
and age = #{myAge}
</select>
d 2 )、dao接口多个简单参数,使用位置:
语法格式 #{arg0}, #{arg1}
select * from student where name =#{org0} and age =#{org1};e)、dao接口使用对象作为参数:
#{} 特点 :
-
使用的PrepareStatement 对象执行sql 语句 效率更高;
-
使用的PrepareStatement 避免sql 注入 更安全;
-
#{}常常作为列值使用,位于等号的右侧,#{}的值和数据类型有关;
e.2 、 $占位符
语法: ${字符}
<select id="selectByName" parameterType="java.lang.Integer"
resultType="cn.guang.entity.Student">
select *
from student
where id = ${Myname}
${} 表示将sql 语句内容 和${} 的内容 使用“+”连接在一起
String sql ="select * from student where name ="+"name"
</select>
List<Student> selecyByName(@Param("Myname") String name); //Dao接口方法
${}的特点:
- 使用Statement对象, 效率低 ;
- 它的值是 连接字符串的方式 ,有sql注入的风险;
- 数据是原样使用的 不区分数据类型;
- 通常在确保数据安全的情况下使用;
public void test05() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//**数据是原样使用的 不区分数据类型;
List<Student> students = mapper.selecyByName("'李四'");
for (Student stu : students) {
System.out.println("学生信息" + stu);
}
sqlSession.close();
}
使用$ 占位符 表示表名或者列名 :
<select id="selectOrderById" resultType="cn.guang.entity.Student">
select *
from student
where name =#{Myname} //#{ } 代表列值
order by ${stuid} desc //使用${ }占位符可以代表列名
</select>
3.2)、封装myBatis 输出结果
f1)、 resultType
查询结果 : 同名的列 赋给同名的属性
resultType属性: 在select 标签中 作为它的属性出现
它的表示结果分为两种类型 1.Java全限定名称 2. 使用别名
自定义别名:
一) 、 resultType 返回对象
-
声明别名: 在mybatis的主配置文件中使用typeAliase设置
<typeAliases> 第一种 <!--type属性 填写Java的全限定名称,aliases 属性 “别名”--> <typeAlias type="cn.guang.entity.Student" alias="stu"/> 第二种: <!-- 使用package 语句 设置一个包名 mybatis 将其包下的类名变成别名 (不区分大小写)--> <package name="cn.guang.entity"/> </typeAliases
-
使用别名 : 在mapper 文件中 设置 resultType = “别名”
第一种
select *
from student
where name = ${Myname}
</select>
二)、resultType 返回简单数据类型 一个值
dao接口:
long selectCount();
mapper 文件;
<select id="selectCount" parameterType="java.lang.Long" resultType="longs">
select count(*) from student
</select>
f1)、 resultMap :
- 先定义resultMap 标签 ,指定指定列名和属性名称的关系;
- 在select标签使用resultMap 属性 指定以上定义的Resultmap的id值;
<resultMap id="proMap" type="cn.guang.entity.ProvinceCity">
<!-- 定义列名和属性名对应 主键列使用 id 标签 其他列使用result 标签-->
<id column="pid" property="nid"/>
<!-- column 对应 select标签 里的字段名 , property 对应实际数据库的字段名-->
<result column="pName" property="nName"/>
</resultMap>
<!-- 使用resultmap属性 指定映射关系的id--> resultMap 和resultType二选一,不能同时使用
<select id="selectAll" resultMap="proMap">
select pid, pName
from pro
</select>
f2)、列名和Java对象的属性名不一样:
-
使用resultMap指定列名和对象属性的关系;
-
使用 resultType :使用列“别名” 让列别名和属性名一致;
<select id="selectCustStu2" resultType="cn.guang.entity.CustStudent"> select id as cid, name as cName, email, age from student </select>
f3)、like 模糊查询:
- 第一种方式:
public List<CustStudent> selectCustStuByName(@Param("MyName") String sName);
mapper :
<select id="selectCustStuByName" resultType="cn.guang.entity.CustStudent">
select * from student where name like #{MyName} //传入的值
</select>
执行 模糊查询:
public void selectCustByname() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
CustStudentDao mapper = sqlSession.getMapper(CustStudentDao.class);
String name = "%李%"; //传入的值
List<CustStudent> custStudents = mapper.selectCustStuByName(name);
custStudents.forEach(stu -> System.out.println(stu));
sqlSession.close();
}
sql : select * from student where name like '%李%'
2.第二种方式:
语法: where name like “%“空格#{MyName} 空格”%”
<select id="selectCustStuByName" resultType="cn.guang.entity.CustStudent">
select * from student where name like "%" #{MyName} "%" //传入的值
</select>
4. MyBatis 框架动态SQL ※
动态SQL的使用场景:
多条件查询 使用动态sql 和实体
4.1 if 标签
语法:
<if test ="boolean判断结果">
sql 代码
</if>
在mapper文件中
<select id="selectStudent" resultType="cn.guang.entity.Student">
select * from student
<if test="条件">
sql语句
</if>
<if test="条件">
sql语句
</if>
</select>
示例: dao接口:
List<Student> selectif( Student student);
mapper 文件:
<select id="selectif" resultType="stu">
select * from student
where id =-1 //条件 避免当没满足第一个条件,直接走到第二个条件时 多 or 或者 and 运算符
<if test="name !=null and name != ''">
name =#{name}
</if>
<if test="age>0">
<!--多个if条件需要 按需求使用 “ or ” 或 “ and ” 连接-->
and age =#{age}
</if>
</select>
test if :
// 省略从sqlSession 获取
Student student = new Student();
student.setName("李四");
student.setAge(22);
List<Student> selectif = mapper.selectif(student);
//遍历
sql: select * from student where name =? and age =?
小于号 ” < “ 在mapper.xml文件中时不能出现的; 所以需要使用实体符号表:
< | 小于 | & lt; |
---|---|---|
> | 大于 | & gt; |
>= | 大于等于 | & gt;= |
<= | 小于等于 | & lt;= |
4.2 where 标签
使用where时。里面是一个或多个if标签,如果其中一个条件为true时,where标签 会自动转成WHERE 关键字,附加在SQL语句之后,如果没有一个条件达成,则会忽略where标签 里的 if;
where 标签会把和它 紧邻的 “ or ” 或者 “ and ” 删掉
<select id="selectwhere" resultType="stu">
select * from student
<where>
<if test="name !=null and name != ''">
name =#{name}
</if>
<if test="age>0">
and age <#{age}
</if>
</where>
</select>
4.3 foreach 循环标签
第一种: 循环简单的LIst;
语法:
select * from student
<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="成员之间的分隔符">
#{item 的值}
</foreach>
collection:表示循环的对象的类型,数组还是List集合,数组 =“array ” 集合 =“list”
item= 集合中的成员 (变量名)
示例:
<select id="selectforeach" resultType="stu">
select * from student
<!--判断list是否为null 并且 size是否大于零-->
<if test="list!=null and list.size>0">
where id in
<foreach collection="list" open="(" close=")" item="myid" separator=",">
#{myid}
</foreach>
</if>
</select>
//输出foreach
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
List<Integer> list = new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
List<Student> selectforeachlist = mapper.selectforeach(list);
selectforeachlist.forEach(stus -> System.out.println(stus));
sqlSession.close();
sql : ==> select * from student where id in ( ? , ? , ? )
Parameters: 1001(Integer), 1002(Integer), 1003(Integer)
第二种: 循环List;
<foreach collection="list" open="(" close=")" item="stu" separator=",">
#{stu.id}
</foreach>
List<Student> lists =new ArrayList<>();
Student stu1 =new Student();
stu1.setId(1001);
Student stu2 =new Student();
stu1.setId(1002);
lists.add(stu1);
lists.add(stu2);
List<Student> selectforeachlist = mapper.selectforeach(list);
sql : select * from student where id in ( ? , ? )
4.4 代码片段 :
sql 标签:
定义一个代码片段,可以在mapper 文件中 的select 、 insert 等地方 使用include;
<!--使用sql代码片段标签 定义定义一条sql语句-->
<sql id="sqlStr">
select *
from student
</sql>
<!--使用sql代码片段标签 定义两个 字段名-->
<sql id="columns">
id,name
</sql>
<select id="selectif" resultType="stu">
select <include refid="columns"/> from student == select id,name from Student
<include refid="sqlStr"/> == select * from Student
where
<if test="name !=null and name != ''">
name =#{name}
</if>
<if test="age>0">
and age =#{age}
</if>
</select>
5. MyBatis 配置文件
mybatis 配置文件分为两类: 主配置文件和mapper文件 ;
**1. 标签: **
settings 是mybatis的全局设置,一般写在上面,一般使用默认值就可以了;
2. typeAliase 别名:
<typeAliases>
<!--type属性 填写Java的全限定名称,aliases 属性 “别名”-->
<!-- 第一种 :-->
<!-- <typeAlias type="java.lang.Long" alias="longs"/>-->
<typeAlias type="cn.guang.entity.Student" alias="stu"/>
<!-- <typeAlias type="cn.guang.entity.CustStudent" alias="cust"/>-->
<!-- 第二种 :-->
<!-- <!– 使用package 语句 设置一个包名 mybatis 认为它的别名是其包下的类名 (不区分大小写)–>-->
<package name="cn.guang.entity"/>
</typeAliases>
3. 配置环境 :
environments: 环境标签,在一个environments标签中 可以配置多个environment,default的值必须是其中一个数据源的Id;
environment: 表示一个数据库的链接信息;
属性: id自定义环境标识,唯一值
transactionManager: 事务管理器
dataSource : 数据源 ,创建的Connection对象,连接数据库;
属性:type 数据源的类型,
属性值: 1)、POOLED,mabatis会在内存中创建 PooledDataSource类,管理连接对象,使用连接池
2)、 UNPOOLED 不使用连接池
3)、 JNDI
<environments default="myStudent">
<environment id="myStudent">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="lyg146837"/>
</dataSource>
</environment>
</environments>
4、使用数据库属性配置文件
需要把数据库的配置信息放到一个单独的文件中,这个文件的后缀是.properties,在这个文件中使用自定义的key =value 的格式 表示数据;
步骤:
-
在resources目录中,创建xxxx.properties;
-
在文件中使用key=value的格式存储数据;
例如: jdbc.driver= com.mysql.cj.jdbc.Driver
jdbc.driver:com.mysql.cj.jdbc.Driver
jdbc.url:jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=UTC
jdbc.username:root
jdbc.password:lyg146837
- 在mybatis 主配置文件中,引用jdbc.properties
<!--引入jdbc配志文件-->
<properties resource="jdbc.properties"/>
- 在property 中使用 ${key } 获取
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
5. mapper标签:
mapper 文件的配置方式:
resource: mapper的路径
<mappers>
<mapper resource="cn/guang/dao/StudentDao.xml"/>
</mappers>
第二种:
<!-- mapper name =文件的所在包名
作用: 一次性加载该包下的所有mapper文件
使用要求: 1. mapper 文件必须和dao接口在同一目录下,
2. mapper 文件必须和dao接口名字保持一致;
-->
<package name="cn.guang.dao"/>
6.扩展
PageHelper 分页插件:
PageHelper 对象
**2. 基于PageHelper分页: **
(1)maven 坐标:
<!--pagehelper 分页依赖-->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
(2) 在environments之前 添加:
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
查询语句之前调用 PageHelper.startPage(页码,每页的大小) 静态方法
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
PageHelper.startPage(2,3); //第二页 显示三条数据
List<Student> students = mapper.selectPageHelper();
students.forEach(stu -> System.out.println(stu));
sqlSession.close();
sql: select * from student order by id LIMIT ?, ?
==> Parameters: 3(Long), 3(Integer)
<== Columns: id, name, email, age
<== Row: 1004, 宋, songdan@qq.com, 20
<== Row: 1005, 三, songdan@qq.com, 20
<== Row: 1008, 王五, wangwu@qq.com, 25
<== Total: 3
SSM 整合
所需maven依赖
<dependencies>
<!--spring相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--servlet和jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
<!--mybatis相关-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</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>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
applicationContext配置文件
<?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:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx.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">
<!--组件扫描 扫描service和mapper-->
<context:component-scan base-package="cn.xxxx">
<!--排除controller的扫描-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>
<!--加载propeties文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--配置数据源信息-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置sessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--加载mybatis核心文件-->
<property name="configLocation" value="classpath:sqlMapConfig-spring.xml"></property>
</bean>
<!--扫描mapper所在的包 为mapper创建实现类-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.xxxx.dao"></property>
</bean>
<!--声明式事务控制-->
<!--平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务增强-->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--事务的aop织入-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor>
</aop:config>
</beans>
spring-mvc
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--组件扫描 主要扫描controller-->
<context:component-scan base-package="cn.xxxx.controller"></context:component-scan>
<!--配置mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--内部资源视图解析器-->
<bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--开发静态资源访问权限-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
</beans>
mybatis-config
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--加载properties文件-->
<properties resource="jdbc.properties"></properties>
<!--定义别名-->
<typeAliases>
<!--<typeAlias type="com.itheima.domain.Account" alias="account"></typeAlias>-->
<package name="cn.xxxx.domain"></package>
</typeAliases>
<!--环境-->
<environments default="developement">
<environment id="developement">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!--加载映射-->
<mappers>
<mapper resource="mapper/AccountMapper.xml"></mapper>
<!-- <package name="cn.xxxx.mapper"></package>-->
</mappers>
</configuration>
mybatis-spring
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--设置myBatis日志输出到控制台-->
<settings>
<setting name="logImpl" value="StDOUT_LOGGING"/>
</settings>
<!--定义别名-->
<typeAliases>
<!--<typeAlias type="com.itheima.domain.Account" alias="account"></typeAlias>-->
<package name="cn.xxxx.domain"></package>
</typeAliases>
</configuration>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--spring 监听器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--springmvc的前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--乱码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
controller 层
package cn.xxxx.controller;/**
* @author:guang
* @Data:2022/2/28
* @apiNote
*/
import cn.xxxx.domain.Account;
import cn.xxxx.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* 描述
*
* @version 1.0
* @Title:
* @author: liyongguang
* @Description: asd
* @date 2022/02/28 10:38:22
*/
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping(value = "/save", produces = "text/html;charset=UTF-8")
@ResponseBody
public String save(Account account) {
accountService.save(account);
return "保存成功";
}
//查询
@RequestMapping("/findAll")
public ModelAndView findAll() {
List<Account> accountList = accountService.findAll();
ModelAndView modelAndView = new ModelAndView("index");
modelAndView.addObject("accountList", accountList);
modelAndView.setViewName("accountList");
return modelAndView;
}
}
service层
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public void save(Account account) {
accountMapper.save(account);
}
@Override
public List<Account> findAll() {
return accountMapper.findAll();
}
}
spring 整合mybatis的三种方式:
第一种:
<!--扫描mapper和service-->
<context:component-scan base-package="com.t2081.ch03">
<!--对controller放行 让spring-mvc扫描-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--加载proper配置文件-->
<context:property-placeholder location="classpath:/jdbc.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--创建sqlseciton工厂-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--指定数据源-->
<property name="dataSource" ref="dataSource"></property>
<!--指定mybatis文件路径-->
<property name="configLocation" value="classpath:mybatis_spring.xml"/>
<!-- 配置别名扫描 -->
<property name="typeAliasesPackage" value="com.t2081.ch03.entity"/>
<!--加载mapper文件 -->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
</bean>
<!-- 第一种方式-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能通过构造器注入sqlSessionFactory,因为没有set方法-->
<constructor-arg index="0" ref="sessionFactory"/>
</bean>
创建实现类:(实现dao接口)
@Repository("smbmsBillDaoMapper")
public class SmbmsBillDaoMapperImpl implements SmbmsBillDaoMapper {
//私有化sqlSessionTemplate
@Autowired
private SqlSessionTemplate sqlSession;
@Override
public List<SmbmsBill> selectAllBill() {
return sqlSession.getMapper(SmbmsBillDaoMapper.class).selectAllBill();
}
@Override
public List<SmbmsBill> selctByWhen(HashMap<String, Object> whens) {
return sqlSession.getMapper(SmbmsBillDaoMapper.class).selctByWhen(whens);
}
@Override
public SmbmsBill selectBillById(Integer id) {
return sqlSession.getMapper(SmbmsBillDaoMapper.class).selectBillById(id);
}
@Override
public int updataBill(SmbmsBill smbmsBill) {
return sqlSession.getMapper(SmbmsBillDaoMapper.class).updataBill(smbmsBill);
}
@Override
public int delectbath(List<Integer> ids) {
return sqlSession.getMapper(SmbmsBillDaoMapper.class).delectbath(ids);
}
}
service层调用:
//@Autowired
@Resource(name = "smbmsBillDaoMapper")
private SmbmsBillDaoMapperImpl smbmsBillDaoMapper;
public void setSmbmsBillDaoMapper(SmbmsBillDaoMapperImpl smbmsBillDaoMapper) {
this.smbmsBillDaoMapper = smbmsBillDaoMapper;
}
SpringBoot2
1.开发步骤:
- 导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 创建主程序类(固定写法)
@SpringBootApplication
public class FirstSpringboot {
public static void main(String[] args) {
SpringApplication.run(FirstSpringboot.class, args);
}
}
- 业务层
@RestController //requetbody+Controller
public class MyControl {
@RequestMapping("/hello")
public String home() {
return "Hello World!";
}
}
- 测试
直接运行main方法
- 简化配置
优先级:application.properties >
- 创建application.properties 核心配置文件所有配置都可修改
server.port=8089 //更改tomcat端口为8089
server.servlet.context-path=/springboot //设置上下文根
- 创建appliation.yml核心配置文件
##格式:冒号:后面默认有一个空格 不能删除 属性前面默认加一个tab制表符缩进
server:
port: 8081
servlet:
context-path:
- 简化部署
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.6.RELEASE</version>
</plugin>
</plugins>
1.2.依赖管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
</parent>
##他的父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.4</version>
</parent>
如果要修改版本:
1.先查看spring-boot-dependencies规定的版本
2.在当前项目重写
<properties>
<mysql.version>8.0.25</mysql.version>
</properties>
支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters
1.3 多环境下核心配置文件的使用
固定格式:application- 开头 .properties结尾
- 开发环境 application-dev.properties & application-dev.yml
- 测试环境 application-test.properties & application-test.yml
- 准生产环境 application-ready.properties & application-ready.yml
- 生产环境 application-prop.properties & application-poop.yml
#properties主配置文件
#激活的配置文件
spring.profiles.active=dev
#yml主配置文件
spring:
profiles:
active: dev
1.4 获取自定义配置
//在application 文件中自定义配置
school.name=guangge
//获取方式一:
@Value("${school.name}")
private String schoolName;
@RequestMapping("/say")
public String say() {
return schoolName;
}
//获取方式二:
//创建配置类
@Component //将该类交给spring容器
@ConfigurationProperties(prefix = "school") //需指定前缀
public class School {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//使用 @Autowired获取
@Autowired
private School school;
@RequestMapping("/printschool")
public String print() {
return "school.name" + school.getName();
}
2.自动配置
- 自动配好tomcat
- 自动配好spring-mvc
如果目标和主程序不在同一包或者主程序的子包,使用@SpringBootApplication(scanBasePackages = “cn.xxxx”)指定扫描;
@SpringBootApplication=
//等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
所有的自动配置都在:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.6.4</version>
</dependency>
2.2、容器功能
2.2.1 组件添加
@Configuration
@Configuration(proxyBeanMethods = true) //告诉spring_boot这是一个配置类
public class MyConfig {
//给容器添加组件,默认id为方法名,可以通过@Bean("")修改
@Bean("user")
public User user01() {
return new User("lucy", 18);
}
@Bean
public Pet pet01() {
return new Pet("tom");
}
}
//main主程序
@SpringBootApplication
public class FirstSpringboot {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(FirstSpringboot.class, args);
Pet tom = run.getBean("pet01", Pet.class);
System.out.println(tom);
}
}
3. springboot 集成jsp页面
- 导入依赖
<!--引入Springboot内嵌的tomcat对jsp的依赖,仅展示页面-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
-
创建webapp文件夹–>在项目结构中将其改为web目录
-
Springboot项目默认推荐使用的前端引擎是thymeleaf
要使用springboot集成jsp,手动指定jsp最后编译的路径
而且springboot集成jsp编译jsp的路径是springboot规定好的位
META- INF/ resources
<resources>
<resource>
<!--源文夹-->
<directory>src/main/webapp</directory>
<!--指定编译到META- INF/resources-->
<targetPath>META-INF/resources</targetPath>
<!--指定源文件夹中的哪个资源要编译进行-->
<includes>
<include>*.*</include>
</includes>
</resource>
</resources>
- 配置视图解析器
#配置视图解析器
#前缀
spring.mvc.view.prefix=/
#后缀
spring.mvc.view.suffix=.jsp
- 测试
@RequestMapping("/testjsp")
public String testjsp(Model model) {
//方法一:
//ModelAndView modelAndView =new ModelAndView();
//modelAndView.addObject("test","hello,jsp");
//modelAndView.setViewName("jsptest");
//return modelAndView;
model.addAttribute("test", "hello,jsp");
return "jsptest";
}
4. springboot集成mybatis
导入依赖:
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis整合springboot的起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
4.1 mybatis逆向工程
- 在resource下创建generatorConfig.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 -->
<classPathEntry location="F:\S2\Javaxx\mysql学习\JDBC学习\mysql-connector-java-8.0.25\mysql-connector-java-8.0.25.jar"/>
<!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
<context id="tables" targetRuntime="MyBatis3">
<!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 配置数据库连接信息 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://139.9.42.209:3306/spring"
userId="root"
password="123456">
</jdbcConnection>
<!-- 生成 model 实体类,targetPackage 指定 model 类的包名, targetProject 指定
生成的 model 放在 idea 的哪个工程下面-->
<javaModelGenerator targetPackage="com.guang.bootmybatis.domain"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="false"/>
</javaModelGenerator>
<!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
<sqlMapGenerator targetPackage="com.guang.bootmybatis.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.guang.bootmybatis.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!--tableName表对应的名字,domainObjectName 生成的实体类的名字-->
<table tableName="student" domainObjectName="Student"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
- 在pom.xml文件中添加插件
<!--mybatis逆向工程插件-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<configurationFile>generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
4.2、@Mapper 注解
扫描dao接口到spring容器,达到为其创建实现类的效果;
- application.properties
#配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://139.9.42.209:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456
- dao或者mapper层
@Mapper
public interface StudentMapper {
//自动生成
int deleteByPrimaryKey(Integer id);
int insert(Student record);
int insertSelective(Student record);
Student selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Student record);
int updateByPrimaryKey(Student record);
}
- service 层
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public Student selectById(Integer id) {
Student student = studentMapper.selectByPrimaryKey(id);
return student;
}
}
- controller 层
@Controller
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping("/select")
public @ResponseBody
Object selectById(Integer id) {
Student student = studentService.selectById(id);
return student;
}
}
4.3 @MapperScan
@MapperScan(basepakges="com.guang.mapper") //扫描该包下的所有mapper为其创建虚拟实现类
public class BootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(BootMybatisApplication.class, args);
}
}
附: mapper.xml 文件存放路径问题
第一种:
//存放在com.guang.boot.mapper下和dao接口一块
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
第二种:
#在resources资源文件下创建mapper文件夹,将xml文件放进去
#然后在指定mybatis映射文件的路径
mybatis.mapper-locations=classpath:mapper/*.xml
4.5 springboot事务
@Transactional //需要对哪个方法加上事务 直接在方法上加上该注解
@Transactional
@Override
public int updateStudentByidAndname(Student student) {
int result = studentMapper.updateByPrimaryKey(student);
int aa = 10 / 0;
return result;
}
5. 集成mvc常用注解
@RestController = @ResponseBody+@Controller
@GetMapping(“/select”)
//@RequestMapping(value = "/select",method = {RequestMethod.GET})
@GetMapping("/select") //只接受get请求,该注解一般在查询时使用-》查询
public Object show1() {
return "only get";
}
@Postmapping(“/inset”)
//@RequestMapping(value = "/insert",method = {RequestMethod.POST})
@PostMapping("/insert") //只接受post请求 该注解一般在新增时使用
public Object show2() {
return "only post";
}
@Deletemapping
@RequestMapping(value = "/delete", method = {RequestMethod.DELETE})
@DeleteMapping("/delete") //只接受DELETE请求 一般在删除请求时使用 -》删除
public Object show3() {
return "only delete";
}
@Putmapping
@RequestMapping(value = "/update", method = {RequestMethod.PUT})
@PutMapping("/update") //只接受put请求 一般在更新请求时使用 -》 更新
public Object show4() {
return "only post";
}
6.spring Boot 实现 RESTFul
例:
Http接口:Http://localhost:8080/student?id=1001&name=zhangsan
RESTFuld风格: Http://localhost:8080/student/1001/zhangsan
Spring boot 开发RESTFul主要是靠几个注解实现
@pathVariable
获取url中的数据,该注解时实现RESTFul最主要的一个注解
@GetMapping("/student/{id}/{age}")
public Object show(@PathVariable("id") Integer id, @PathVariable("age") Integer age) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("age", age);
return map;
}
@DeleteMapping("/student/{id}/{status}")
public Object show1(@PathVariable("id") Integer id, @PathVariable("status") Integer status) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("status", status);
return map;
}
//如遇以上两个方法请求参数类型一样时,应使用不同的注解请求方式区分开,
//如必须有两个相同操作类型,并且参数类型也一样时可以改变参数位置来区分
@GetMapping("/student/stu/{id}/{age}")
@GetMapping("/student/{id}/stu/{age}")
7. Spring Boot 集成redis
- 添加操作数据类型的依赖
<!--springboot集成redis所需依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 在springboot核心配置文件中添加redis的配置
#配置redis
spring.redis.host=139.9.42.209
spring.redis.port=6379
spring.redis.password=root123
示例: (往redis里存值)
@RestController
public class RedisController {
@Autowired
private RedisService redisService;
@RequestMapping("/put")
public Object show(String key,String value){
redisService.put(key,value);
return "值已经放进redis数据库";
}
}
@Service
public class RedisServiceImpl implements RedisService {
@Autowired //集成Redis模板对象 RedisTemplate<Object,Object> 源于spring-boot-starter-data-redis依赖
private RedisTemplate<Object,Object> redisTemplate;
@Override
public void put(String key, String value) {
redisTemplate.opsForValue().set(key,value); //插入普通值
}
}
示例: (从redis中取值)
Controller层
@RequestMapping("/get")
public Object get(String key){
String value= redisService.get(key);
return value;
}
service 层
@Override
public String get(String key) {
String value = (String) redisTemplate.opsForValue().get(key);
return value;
}
8. springboot 集成 Dubbo 分布式框架
-
接口工程:(interface)存放实体bean和业务接口
-
服务提供者: (provider) 业务接口的实现类并将服务暴露且注册到注册中心,调用数据持久层
-添加依赖(dubbo,注册中心,接口工程)<!--dubbo 集成spring-boot 起步依赖--> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!--注册中心依赖--> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <!--接口工程--> <dependency> <groupId>com.guang.boot</groupId> <artifactId>dubbo-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
-配置服务提供者核心配置文件
#设置内嵌tomcat端口号 server.port=8081 #设置上下文跟 server.servlet.context-path=/ # 设置dubbo的配置 spring.application.name=dubbo-provider #设置当前工程是一个 服务提供者 spring.dubbo.server=true #设置注册中心 spring.dubbo.registry=zookeeper:139.9.42.209:2181
-
服务消费者:(consumer) 处理浏览器客户端发送的请求,从注册中心调用服务提供者所提供的服务
-添加依赖(dubbo ,注册中心,接口工程)
-配置服务消费者核心配置文件
示例:
interface 模块:
public interface StudentService {
Integer selectStudentAll();
}
provider模块:
//提供者创建实现类
@Component //交给spring容器管理
//dubbo下的@service(interfaceClass="你要暴漏的接口")
@Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000)
public class StudentServiceImpl implements StudentService {
@Override
public Integer selectStudentAll() {
//操作数据库
return 2000;
}
}
//主程序设置开启springboot和 Dubbo注解
@SpringBootApplication //开启springboot 注解
@EnableDubboConfiguration //开启Dubbo 注解
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
}
}
consumer模块:
//使用者
@RestController
public class ConsumerController {
//同样是使用dubbo下的该注解
@Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false)
private StudentService studentService;
@RequestMapping("/student/count")
public Object count() {
Integer count = studentService.selectStudentAll();
return "总人数为"+count;
}
}
//主程序
@SpringBootApplication
@EnableDubboConfiguration
public class DubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}
}
9. Spring Boot 创建java项目
第一种方式:
@Service
public class StudentServiceImpl implements StudentService {
@Override
public String show() {
return "Say hello";
}
}
//主程序
@SpringBootApplication
public class SpringbootJavaApplication {
public static void main(String[] args) {
//springboot 启动后 返回值是ConfigurableApplicationContext,它也是一个容器
ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringbootJavaApplication.class, args);
//从容器中获取指定对象
StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
//调用方法
String show = studentService.show();
System.out.println(show);
}
}
第二种方式:
@SpringBootApplication
public class SpringbootJavaApplication implements CommandLineRunner {
@Autowired
private StudentService studentService;
public static void main(String[] args) {
SpringApplication.run(SpringbootJavaApplication.class,args);
}
//实现CommandLineRunner接口的run方法
@Override
public void run(String... args) throws Exception {
String show = studentService.show();
System.out.println(show);
}
}
10. spring boot 关闭 && 开启 控制台LOGO
关闭:
public class SpringbootJavaApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SpringbootJavaApplication.class);
//设置关闭控制台logo
springApplication.setBannerMode(Banner.Mode.OFF);
springApplication.run();
}
}
修改控制台LOGO 样式:
http://patorjk.com/software/taag/#p=display&f=Big&t=I%20%20LOVE%20%20J%20A%20V%20A
11. 拦截器
使用步骤:
//拦截器类
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入拦截器!!");
User user = (User) request.getSession().getAttribute("user");
System.out.println(user);
if(null==user){
//未登录
response.sendRedirect(request.getContextPath()+"/user/error");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
Controller
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public Object login(HttpServletRequest request) {
//将用户的信息存到session中
User user = new User();
user.setId(1001);
user.setName("张三");
request.getSession().setAttribute("user", user);
return "login success";
}
//登陆以后才可访问
@RequestMapping("/center")
public Object center() {
return "see cent message";
}
//不登陆就可访问
@RequestMapping("/out")
public Object out() {
return "see out message";
}
//没登陆却访问了需要登陆的路径
@RequestMapping("/error")
public Object error() {
return "error";
}
}
//配置类
@Configuration //表示该类是一个配置类 相当于之前的配置文件
public class InterceptorConfig implements WebMvcConfigurer {
//mvc:interceptors
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截哪些
String[] addPathPatterns ={
"/user/**"
};
//排除那些
String[] excludePathPatterns ={
"/user/out","/user/error", "/user/login"
};
registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
}
}
12.sprintboot 使用servlet
第一种方式:使用@WebServlet(urlPatterns = “/myServlet”)和@ServletComponentScan(“com.guang.boot.controller”) 注解
//servlet
@WebServlet(urlPatterns = "/myServlet")
public class SpringbootServletController extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("hello springboot&servlet");
response.getWriter().flush();
response.getWriter().close();
}
}
//主程序
@SpringBootApplication
@ServletComponentScan("com.guang.boot.controller") //扫描@Webservlet 注解
public class SpringBootServletApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootServletApplication.class, args);
}
}
第二种方式: 不用前两种注解,只需要@Bean
@Configuration //这是一个配置类
public class ServletConfig {
//@Bean 是一个方法级别的注解 相当于配置文件中的
// <beans>
// <bean id="" class=""></bean>
// </beans>
@Bean
public ServletRegistrationBean ServletRegistrationBean() {
ServletRegistrationBean sg =new ServletRegistrationBean(new Myservlet(),("/myServlet")); //new ...(我创建的servlet,"设置请求的路径")
return sg;
}
}
13.使用filter 过滤器
第一种: @WebFilter(“/myfilter”)
@WebFilter("/myfilter")
public class Myfilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("进入filter拦截器!!");
chain.doFilter(request,response);
}
}
//主程序
@ServletComponentScan("com.guang.boot.filter") //扫描@WebFilter
第二种:
//创建类继承HttpFilter
public class Myfilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("进入filter拦截器!!");
chain.doFilter(request,response);
}
}
//controller
@RestController
public class FilterControoler {
@RequestMapping("/user/detail")
public Object detail() {
return "/user/detail";
}
@RequestMapping("/center")
public Object center() {
return "center";
}
}
//创建配置类
@Configuration //配置类
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
//创建过滤器
FilterRegistrationBean filterRegistrationBean =new FilterRegistrationBean(new Myfilter());
//添加过滤路径
filterRegistrationBean.addUrlPatterns("/user/*");
return filterRegistrationBean;
}
}
14. 设置字符编码
第一种方式:
- 创建servlet
@WebServlet("/encoding")
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("你好世界!!");
resp.setContentType("text/html;character=utf-8");
resp.getWriter().flush();
resp.getWriter().close();
}
}
- 创建配置类
@Configuration
public class MyConfig {
@Bean
public FilterRegistrationBean characterEncodingFilterRegistrationBean(){
//创建字符编码过滤器
CharacterEncodingFilter characterEncodingFilter =new CharacterEncodingFilter();
//设置强制转换
characterEncodingFilter.setForceEncoding(true);
//设置字符类型
characterEncodingFilter.setEncoding("utf-8");
//创建FilterRegistrationBean对象
FilterRegistrationBean filter =new FilterRegistrationBean();
filter.setFilter(characterEncodingFilter);
filter.addUrlPatterns("/*");
return filter;
}
}
- 设置application.properties配置文件
#关闭springboot 的http字符编码支持
#关闭之后自己设置的才生效
server.servlet.encoding.enabled=false
第二种:
#开启springboot 的http字符编码支持
server.servlet.encoding.enabled=true
#开启强制使用指定字符编码
server.servlet.encoding.force=true
#设置格式
server.servlet.encoding.charset=utf-8
15. 打包
打war包:
<!--设置打包方式-->
<packaging>war</packaging>
<!--在bilud标签设置打war包的字符-->
<finalName>SpringBootWar</finalName>
<resources>
<resource>
<!--源文夹-->
<directory>src/main/webapp</directory>
<!--指定编译到META- INF/resources-->
<targetPath>META-INF/resources</targetPath>
<!--指定源文件夹中的哪个资源要编译进行-->
<includes>
<include>*.*</include>
</includes>
</resource>
<resource>
<!--源文夹-->
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
主程序:
@SpringBootApplication
//打包需继承SpringBootServletInitializer
public class BootDapakageApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(BootDapakageApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//参数为当前启动类
return builder.sources(BootDapakageApplication.class);
}
}
点击右侧maven–>Lifecycle–>选择打包的项目–>先clean–>再点击pakage–>将打包后的war包放到tomcat–>webapps目录下 -->在bin目录下启动tomcat–>在网页中输入请求路径要带上项目名
打jar包:
<!--打包后的项目名称-->
<finalName>SpringBootjar</finalName>
<resources>
<resource>
<!--源文夹-->
<directory>src/main/webapp</directory>
<!--指定编译到META- INF/resources-->
<targetPath>META-INF/resources</targetPath>
<!--指定源文件夹中的哪个资源要编译进行-->
<includes>
<include>*.*</include>
</includes>
</resource>
<resource>
<!--源文夹-->
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
#主配置文件
server.port=8088
server.servlet.context-path=/
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
点击右侧maven–>Lifecycle–>选择打包的项目–>先clean–>再点击pakage–>将打包后的jar包放到本地目录下–>打开cmd命令窗口–>输入 java -jar 打包后的项目名称 .jar -->进入浏览器访问
16. SpringBoot 集成logback日志
- 在resource目录下 创建logback-spring.xml文件:
</filter>
<encoder>
<Pattern>%date [%-5p] [%thread] %logger{60}
[%file : %line] %msg%n</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<File>/home/log/stdout.log</File>-->
<File>D:/log/stdout.log</File>
<encoder>
<pattern>%date [%-5p] %thread %logger{60}
[%file : %line] %msg%n</pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 添加.gz 历史日志会启用压缩 大大缩小日志文件所占空间 -->
<!--<fileNamePattern>/home/log/stdout.log.%d{yyyy-MM-dd}.log</fileNam
ePattern>-->
<fileNamePattern>D:/log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory><!-- 保留 30 天日志 -->
</rollingPolicy>
</appender>
<logger name="com.abc.springboot.mapper" level="DEBUG" />
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
- 添加依赖:
<!--logback日志依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- 使用注解 @Slf4j
@Slf4j
//类名
//方法
log.info("学生总人数查询:");