SSM框架快速入门——笔记

文章目录

写在前面

以下内容是我在自学(小破站找的视频)ssm框架时记录的笔记,之前一直在电脑上保存,为了保存和分享现在把笔记整到csdn,如果有错误和不足的地方欢迎指正,暂时我只记录了这么多,日后我的知识储备多了也会不断补充和完善。

正文

一、SpringIOC(xml)

1.快速入门

①导入 Spring 开发的基本包坐标

在项目pom.xml文件中导入spring坐标

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>

②编写 Dao 接口和实现类

UserDao、UserDaoImpl。

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("save running....");
    }
}

③创建 Spring 核心配置文件

在resources目录下创建核心配置文件applicationContext.xml(名称任意,习惯性命名为applicationContext)。

④在 Spring 配置文件中配置 UserDaoImpl

其中id是唯一标识(任意名称),class为需要实例化bean的全限定名(包名.类名)。

<bean id="userDao" class="com.fbst.dao.impl.UserDaoImpl"></bean>

⑤使用 Spring 的 API 获得 Bean 实例

创建测试类UserDaoDemo,通过ApplicationContext对象的getBean()方法获得bean对象,从而调用对象中的方法。

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//指定配置文件名
        UserDao userDao = (UserDao) app.getBean("userDao");//通过<bean>标签中的id唯一标识获取指定的bean对象
        userDao.save();
    }
}

2.知识要点

①导入坐标

②创建Bean

③创建applicationContext.xml

④在配置文件中进行配置

⑤创建ApplicationContext对象getBean

3.配置文件

3.1Bean标签范围配置

<bean id="userDao" class="com.fbst.dao.impl.UserDaoImpl" scope=""></bean>

scope:指对象的作用范围,取值如下:

取值范围说明
singleton默认值,单例的
prototype多例的
requestWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
sessionWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
global sessionWEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当于 session

1)当scope的取值为singleton时

Bean的实例化个数:1个

Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例

Bean的生命周期:

对象创建:当应用加载,创建容器时,对象就被创建了

对象运行:只要容器在,对象一直活着

对象销毁:当应用卸载,销毁容器时,对象就被销毁了

2)当scope的取值为prototype时

Bean的实例化个数:多个

Bean的实例化时机:当调用getBean()方法时实例化Bean

对象创建:当使用对象时,创建新的对象实例

对象运行:只要对象在使用中,就一直活着

对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了

3.2Bean生命周期配置

在UserDaoImp添加以下两个方法:

public void init(){
	System.out.println("初始化方法....");
}

public void destory(){
	System.out.println("销毁方法....");
}

init-method:指定类中的初始化方法名称

destroy-method:指定类中销毁方法名称

<bean id="userDao" class="com.fbst.dao.impl.UserDaoImpl" 
      init-method="init" destory-method="destory">
</bean>

3.3Bean实例化的三种方式

1.无参构造方法实例化

2.工厂静态方法实例化

3.工厂实例方法实例化

1) 使用无参构造方法实例化

它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败

<bean id="userDao" class="com.fbst.dao.impl.UserDaoImpl"/>

2) 工厂静态方法实例化

工厂的静态方法返回Bean实例

public class StaticFactory {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
<bean id="userDao" class="com.fbst.factory.StaticFactory" factory-method="getUserDao" />

3) 工厂实例方法实例化

工厂的非静态方法返回Bean实例

public class DynamicFactory {
    public UserDao getUserDao() {
        return new UserDaoImpl();
    }
}
<bean id="factoryBean" class="com.fbst.factory.DynamicFactory"/>
<bean id="userDao" factory-bean="factoryBean" factory-method="getUserDao"/>

3.4 Bean的依赖注入方式

1.构造方法

2.set方法

1)构造方法方式注入:

①创建有参构造

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("save running....");
    }
}

public interface UserService {
    public void save();
}

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public UserServiceImpl() {
    }
    
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public void save() {
        userDao.save();
    }
}

②配置Spring容器调用有参构造时进行注入

<bean id="userDao" class="com.fbst.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.fbst.service.impl.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

2)set方法方式注入:

方式1:

①创建 UserService,UserService 内部在调用 UserDao的save() 方法

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
    }
    
    public void save() {
        userDao.save();
    }
}

②将 UserServiceImpl 的创建权交给 Spring

property标签中:

name属性值与UserServiceImpl中的setUserDao方法对应(setUserDao --> userDao)。

ref属性指定需要注入的对象id唯一表示。

<bean id="userDao" class="com.fbst.dao.impl.UserDaoImpl">

<bean id="userService" class="com.fbst.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"></property>
</bean>

③从 Spring 容器中获得 UserService 进行操作

方式2:P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:

首先,需要引入P命名空间:

xmlns:p="http://www.springframework.org/schema/p"

其次,需要修改注入方式:

<bean id="userService" class="com.fbst.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

3.5 引入其他配置文件(分模块开发)

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载

<import resource="文件名.xml"/>

3.6 知识要点

bean标签

id属性:在容器中Bean实例的唯一标识,不允许重复

class属性:要实例化的Bean的全限定名

scope属性:Bean的作用范围,常用是Singleton(默认)和prototype

property标签:属性注入

name属性:属性名称

value属性:注入的普通属性值

ref属性:注入的对象引用值

import标签:导入其他的Spring的分文件

4.Spring相关API

4.1ApplicationContext的实现类

1)ClassPathXmlApplicationContext

它是从类的根路径下加载配置文件,推荐使用这种

2)FileSystemXmlApplicationContext

它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

3)AnnotationConfigApplicationContext

当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

4.2 getBean()方法使用

public Object getBean(String name) throws BeansException {
	assertBeanFactoryActive();
	return getBeanFactory().getBean(name);
}

public <T> T getBean(Class<T> requiredType) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(requiredType);
}

其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。

当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = (UserService) applicationContext.getBean("userService");
UserService userService2 = applicationContext.getBean(UserService.class);

4.3知识要点

Spring的重点API

ApplicationContext app = new ClasspathXmlApplicationContext("xml文件")
app.getBean("id")
app.getBean(Class)

二、Spring IOC(注解)

1.Spring原始注解

注解说明
@Component使用在类上用于实例化Bean
@Controller使用在web层类上用于实例化Bean
@Service使用在service层类上用于实例化Bean
@Repository使用在dao层类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入
@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入
@Resource相当于@Autowired+@Qualifier,按照名称进行注入
@Value注入普通属性
@Scope标注Bean的作用范围
@PostConstruct使用在方法上标注该方法是Bean的初始化方法
@PreDestory使用在方法上标注该方法是Bean的销毁方法

2.Spring注解开发

首先创建UserDao、UserDaoImpl、UserServic、UserServicImpl

public interface UserDao {
    public void save();
}

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("save running...");
    }
}

public interface UserService {
    public void save();
}

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired //按照数据类型从Spring容器中进行匹配的
    private UserDao userDao;

    public void save() {
        userDao.save();
    }
}

其次分别在UserDaoImpl、UserServiceImpl、private UserDao userDao;上方添加@Repository(“userDao”)、@Service(“userService”)、@Autowired 等注解。
@Repository(“userDao”)
< bean id=“userDao” class=“com.fbst.dao.impl.UserDaoImpl”/>
@Service(“userService”)
< bean id=“userService” class=“com.fbst.service.impl.UserServiceImpl”/>
@Autowired
< property name=“userDao” ref=“userDao”/>

注意:使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。

<context:component-scan base-package="com.fbst"/>

代码测试:

public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

3.Spring新注解

注解说明
@Configuration用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定Spring在初始化容器时要扫描的包。作用和在Spring的xml配置文件中的<context:component-scan base-package=“com.fbst”/>一样
@bean使用在方法上,标注将该方法的返回值存储到Spring容器中
@PropertySource用于加载properties文件中的配置
@Important用于导入其他配置类

创建核心配置类:

@Configuration
@ComponentScan("com.fbst")
public class SpringCofiguration {

}

注解说明:

注解说明
@Configuration标志该类是Spring的核心配置类,相当于一个ApplicationContext.xml文件
@ComponentScan(“com.fbst”)相当于<context:component-scan base-package=“com.fbst”/>
@PropertySource(“classpath:jdbc.properties”)加载properties配置文件
@Import({DataSourceConfiguration.class})导入其他副配置文件(DataSourceConfiguration)类

三、Spring集成Junit

开发步骤

①导入spring集成Junit的坐标

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>5.0.5.RELEASE</version>
</dependency>

②使用@Runwith注解替换原来的运行期

③使用@ContextConfiguration指定配置文件或配置类

④使用@Autowired注 入需要测试的对象

⑤创建测试方法进行测试

代码实现

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml")
@ContextConfiguration(classes = {SpringCofiguration.class})
public class SpringJunitTest {

    @Autowired
    private UserService userService;

    @Autowired
    private DataSource dataSource;

    @Test
    public void test1() throws SQLException {
        userService.save();
        System.out.println(dataSource.getConnection());
    }
}

四、Spring配置数据源

1.数据源的开发步骤

①导入数据源的坐标和数据库驱动坐标

②创建数据源对象

③设置数据源的基本连接数据

④使用数据源获取连接资源和归还连接资源

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.32</version>
</dependency>
<dependency>
	<groupId>c3p0</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.1.2</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>1.1.10</version>
</dependency>
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>
public class DataSourceTest {

    @Test
    //测试手动创建 c3p0 数据源(加载properties配置文件)
    public void test3() throws Exception {
        //读取配置文件
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");
        String driver = rb.getString("jdbc.driver");
        String url = rb.getString("jdbc.url");
        String username = rb.getString("jdbc.username");
        String password = rb.getString("jdbc.password");
        //创建数据源对象  设置连接参数
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);

        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

    @Test
    //测试手动创建 druid 数据源
    public void test2() throws Exception {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        DruidPooledConnection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

    @Test
    //测试手动创建 c3p0 数据源
    public void test1() throws Exception {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }
}

jdbc.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

2.Spring配置

导入Spring坐标

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.0.5.RELEASE</version>
</dependency>

配置数据源:

其中class属性是使用的数据源的全限定名,name属性是指定数据源set方法名xxx(setXxx --> xxx)。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
    <property name="user" value="root"></property>
    <property name="password" value="root"></property>
</bean>

代码测试:

@Test
//测试Spring容器产生数据源对象
public void test4() throws Exception {
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    DataSource dataSource = app.getBean(DataSource.class);
    Connection connection = dataSource.getConnection();
    System.out.println(connection);
    connection.close();
}

3.抽取jdbc配置文件

applicationContext.xm加载jdbc.properties配置文件获得连接信息。
首先,需要引|入context命名空间和约束路径:
命名空间: xmIns:context=“http://www.springframework.org/schema/context”
约束路径: http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

<!--加载外部的properties文件-->
<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>

五、Spring MVC

1.Spring集成web环境

首先,创建service层和dao层,接下来按着下面步骤进行操作。

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("save running....");
    }
}

public interface UserService {
    public void save();
}

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save() {
        userDao.save();
    }
}

①在pom.xml中导入spring-web坐标、Servlet相关坐标。

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<version>3.0.1</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>javax.servlet.jsp</groupId>
	<artifactId>javax.servlet.jsp-api</artifactId>
	<version>2.2.1</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>5.0.5.RELEASE</version>
</dependency>

②在web.xml中配置ContextLoaderListener监听器和全局初始化参数。

<!--配置监听器-->
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--全局初始化参数-->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:applicationContext.xml</param-value>
</context-param>

③创建web层,使用WebApplicationContextUtils获得应用上下文对象ApplicationContext。

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

2.Spring MVC快速入门

开发步骤:

①在pom.xml导入Spring、SpringMVC、Servlet和jsp的坐标

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.2.1</version>
    <scope>provided</scope>
</dependency>

②在web.xml配置SpringMVC的核心控制器

<!--配置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>
	<!--参数为正数时,表示服务器启动时,创建servlet对象-->
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

③创建Controller和业务方法

public class UserController {
    public String save() {
        System.out.println("Controller save running...");
        return "success.jsp";
    }
}

④创建视图页面Success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
	<h>Success!</h1>
</body>
</html>

⑤使用注解配置Controller类中业务方法的映射地址

@Controller//把当前类放入Spring容器中
@RequestMapping("/user")//会和当前方法上的地址拼接在一起组成最终访问地址
public class UserController {
    
    @RequestMapping(value = "/quick")//设置请求路径
    public String save() {
        System.out.println("Controller save running...");
        return "success.jsp";//指定要跳转的视图界面
    }
}

⑥配置SpringMVC核心文件 spring-mvc.xml

​ 首先需要导入context命名空间。

xmlns:context="http://www.springframework.org/schema/context"
<!--在xsi:schemaLocation中添加-->
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
<!--Controller的组件扫描-->
<context:component-scan base-package="com.fbst.contorller"></context:component-scan>

在配置springmvc前端控制器时添加以下配置,告诉spring-mvc.xml文件位置。

<init-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:spring-mvc.xml</param-value>
</init-param>

⑦客户端发起请求测试

打开浏览器访问:localhost:8080/user/quick

结果:页面显示Success!

3.知识要点

①导入SpringMVC相关坐标

②配置SpringMVC核心控制器DispathcerServlet

③创建Controller类和视图页面

④使用注解配置Controller类中业务方法的映射地址

⑤配置SpringMVC核心文件 spring-mvc.xml

⑥客户端发起请求测试

六、Spring MVC视图解析器

在spring-mvc.xml中配置:

<!--配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--/jsp/success.jsp-->
	<property name="prefix" value="/jsp/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

现在刚才的测试代码可以优化为:

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping(value = "/quick")
    public String save() {
        System.out.println("Controller save running...");
        return "success";
    }
}

七、Spring AOP

1.基于XML的AOP开发

1.1快速入门

①导入 spring、AOP 相关坐标

<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.4</version>
</dependency>

②创建目标接口和目标类(内部有切点)

public interface TargetInterface {
    public void save();
}

public class Target implements TargetInterface {
    public void save() {
        System.out.println("save running.....");
    }
}

③创建切面类(内部有增强方法)

public class MyAspect {
    public void before(){
        System.out.println("前置增强..........");
    }

    public void afterReturning(){
        System.out.println("后置增强..........");
    }

    public void after(){
        System.out.println("最终增强..........");
    }
}

④将目标类和切面类的对象创建权交给 spring

<!--目标对象-->
<bean id="target" class="com.fbst.aop.Target"></bean>

<!--切面对象-->
<bean id="myAspect" class="com.fbst.aop.MyAspect"></bean>

⑤在 applicationContext.xml 中配置织入关系

首先需要引入aop命名空间

<!--引入aop命名空间-->
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

<!--配置织入:告诉spring框架 哪些方法(切点)需要进行哪些增强(前置、后置...)-->
<aop:config>
	<!--声明切面-->
	<aop:aspect ref="myAspect">
		<!--切面:切点+通知-->
        <aop:before method="before" pointcut="execution(public void com.fbst.aop.Target.save())"/>
	</aop:aspect>
</aop:config>

⑥导入spring-text、junit依赖坐标

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
	<groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {

    @Autowired
    private TargetInterface target;

    @Test
    public void test1(){
        target.save();
    }
}

1.2切点表达式的写法

表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

1.访问修饰符可以省略

2.返回值类型、包名、类名、方法名可以使用星号* 代表任意

3.包名与类名之间一个点 . 代表当前包下的类,两个点 … 表示当前包及其子包下的类

4.参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表

例如:

​ execution(public void com.fbst.aop.Target.method())

​ execution(void com.fbst.aop.Target.*(…))

​ execution(* com.fbst.aop. * . * (…)) (最常用的)

​ execution(* com.fbst.aop… * . * (…))

​ execution(* * . . *. *(…))

1.3通知的类型

通知的配置语法:

<aop:通知类型 method=“切面类中方法名” pointcut=“切点表达式"></aop:通知类型 >

名称标签说明
前置通知<aop:before >用于配置前置通知。指定增强的方法在切入点方法之前执行
后置通知<aop:after-returning >用于配置后置通知。指定增强的方法在切入点方法之后执行
环绕通知<aop:around >用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
异常抛出通知<aop:throwing >用于配置异常抛出通知。指定增强的方法在出现异常时执行
最终通知<aop:after >用于配置最终通知。无论增强方式执行是否有异常都会执行

1.4 切点表达式的抽取

当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用 pointcut-ref 属性代替 pointcut 属性来引用抽取后的切点表达式。

<aop:config>
    <!--抽取切点表达式-->
    <aop:pointcut id="myPointcut" expression="execution(* com.fbst.aop.*.*(..))"></aop:pointcut>
	<aop:aspect ref="myAspect">
        <aop:before method="before" pointcut-ref="myPointcut"/>
	</aop:aspect>
</aop:config>

1.5知识要点

aop织入的配置

<aop:config>
	<aop:aspect ref="切面类">
        <aop:after method="通知方法名" pointcut="切点表达式"/>
        <aop:after method="通知方法名" pointcut-ref="切点表达式对象引用(id)"/>
    </aop:aspect>
</aop:config>

通知的类型:前置通知、后置通知、环绕通知、异常抛出通知、最终通知

切点表达式的写法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

2.基于注解的AOP开发

2.1快速入门

基于注解的aop开发步骤:

①创建目标接口和目标类(内部有切点)

public interface TargetInterface {
    public void save();
}

public class Target implements TargetInterface {
    public void save() {
        System.out.println("save running.....");
    }
}

②创建切面类(内部有增强方法)

public class MyAspect {

    public void before(){
        System.out.println("前置增强..........");
    }

    public void afterReturning(){
        System.out.println("后置增强..........");
    }

    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前增强....");
        Object proceed = pjp.proceed();//切点方法
        System.out.println("环绕后增强....");
        return proceed;
    }

    public void afterThrowing(){
        System.out.println("异常抛出增强..........");
    }

    public void after(){
        System.out.println("最终增强..........");
    }
}

③将目标类和切面类的对象创建权交给 spring

@Component("target")
public class Target implements TargetInterface {
    ...
}

@Component("myAspect")
public class MyAspect {
	...
}

④在切面类中使用注解配置织入关系

@Component("myAspect")
@Aspect //标注当前MyAspect是一个切面类
public class MyAspect {
    
	//配置前置通知
    //@Before("execution(* com.fbst.anno.*.*(..))")
    public void before(){
        System.out.println("前置增强..........");
    }

    public void afterReturning(){
        System.out.println("后置增强..........");
    }

    //Proceeding JoinPoint:  正在执行的连接点===切点
    //@Around("execution(* com.fbst.anno.*.*(..))")
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前增强....");
        Object proceed = pjp.proceed();//切点方法
        System.out.println("环绕后增强....");
        return proceed;
    }

    public void afterThrowing(){
        System.out.println("异常抛出增强..........");
    }

    //@After("execution(* com.fbst.anno.*.*(..))")
    @After("MyAspect.pointcut()")
    public void after(){
        System.out.println("最终增强..........");
    }
    
}

⑤在配置文件中开启组件扫描和 AOP 的自动代理(applicationContext-anno.xml)

<!--组件扫描-->
<context:component-scan base-package="com.fbst.anno"/>

<!--aop自动代理-->
<aop:aspectj-autoproxy/>

⑥测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-anno.xml")
public class AnnoTest {

    @Autowired
    private TargetInterface target;

    @Test
    public void test1(){
        target.save();
    }
    
}

2.2注解配置详解

注解通知的类型

通知的配置语法:@通知注解(切点表达式)

名称注解说明
前置通知@Before用于配置前置通知。指定增强的方法在切入点方法之前执行
后置通知@AfterReturning用于配置后置通知。指定增强的方法在切入点方法之后执行
环绕通知@Around用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
异常抛出通知@AfterThrowing用于配置异常抛出通知。指定增强的方法在出现异常时执行
最终通知@After用于配置最终通知。无论增强方式执行是否有异常都会执行

切点表达式的抽取

同 xml 配置 aop 一样,我们可以将切点表达式抽取。抽取方式是在切面内定义方法,在该方法上使用@Pointcut注解定义切点表达式,然后在在增强注解中进行引用。具体如下:

@Component("myAspect")
@Aspectpublic class MyAspect {
    
    @Before("MyAspect.myPoint()")
    public void before(){
        System.out.println("前置代码增强.....");
    }
    
    @Pointcut("execution(* com.fbst.aop.*.*(..))")
    public void myPoint(){}
    
}

2.3知识要点

注解aop开发步骤:

①使用@Aspect标注切面类

②使用@通知注解标注通知方法

③在配置文件中配置aop自动代理<aop:aspectj-autoproxy/ >

3.基于XML的声明式事务控制

3.1.声明式事务控制的实现

①引入tx命名空间

xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd

②配置事务增强

<!--配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"/>
</bean>

<!--通知  事务的增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<!--设置事务的属性信息的-->
	<tx:attributes>    
		<tx:method name="*"/>
	</tx:attributes>
</tx:advice>

③配置事务 AOP 织入

<!--配置事务的aop织入-->
<aop:config>
    <aop:pointcut id="txPointcut" expression="execution(* com.fbst.service.impl.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

④测试事务控制转账业务代码

配置数据源、jdbcTemplate、accountDao及accountService

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="accountDao" class="com.fbst.dao.impl.AccountDaoImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

<!--目标对象  内部的方法就是切点-->
<bean id="accountService" class="com.fbst.service.impl.AccountServiceImpl">
    <property name="accountDao" ref="accountDao"/>
</bean>

创建web层、service层及dao层

public class Account {

    private String name;
    private double money;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

public interface AccountDao {
    public void out(String outMan, double money);
    public void in(String inMan, double money);
}

public class AccountDaoImpl implements AccountDao {

    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void out(String outMan, double money) {
        jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
    }

    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    }
}

public interface AccountService {
    public void transfer(String outMan,String inMan,double money);
}

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
        int i = 1/0;//自定义异常用于测试
        accountDao.in(inMan,money);
    }
}

public class AccountController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = app.getBean(AccountService.class);
        accountService.transfer("tom", "lucy", 500);
    }
}

3.2切点方法的事务参数的配置

<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<!--设置事务的属性信息的-->
	<tx:attributes> 
		<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
		<tx:method name="save" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
		<tx:method name="findAll" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
		<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
	</tx:attributes>
</tx:advice>

其中,<tx:method > 代表切点方法的事务参数的配置

例如:

name:切点方法名称

isolation:事务的隔离级别

propogation:事务的传播行为

timeout:超时时间

read-only:是否只读

3.3知识要点

声明式事务控制的配置要点

平台事务管理器配置

事务通知的配置

事务aop织入的配置

数据库表

CREATE TABLE `account` (
  `name` varchar(20) DEFAULT NULL,
  `money` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

4.基于注解的声明式事务控制

4.1使用注解配置声明式事务控制

①修改AccountDaoImpl

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void out(String outMan, double money) {
        jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
    }

    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    }
}

②修改AccountServiceImpl

@Service("accountService")
@Transactional(isolation = Isolation.REPEATABLE_READ)
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
        int i = 1/0;//自定义异常用于测试
        accountDao.in(inMan,money);
    }
}

③修改applicationContext.xml 配置文件

<!--组件扫描-->
<context:component-scan base-package="com.fbst"/>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="com.mysql.jdbc.Driver"/>
	<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
	<property name="user" value="root"/>
	<property name="password" value="root"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"/>
</bean>

<!--事物的注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>

​ 测试代码:

public class AccountController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = app.getBean(AccountService.class);
        accountService.transfer("tom","lucy",500);
    }
}

4.2注解配置声明式事务控制解析

①使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离级别、传播行为等。

②注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。

③使用在方法上,不同的方法可以采用不同的事务参数配置。

④Xml配置文件中要开启事务的注解驱动<tx:annotation-driven />

4.3知识要点

注解声明式事务控制的配置要点

平台事务管理器配置(xml方式)

事务通知的配置(@Transactional注解配置)

事务注解驱动的配置 <tx:annotation-driven/ >

八、Mybatis

1.Mybatis快速入门

1.1添加MyBatis坐标和其他相关坐标

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.32</version>
</dependency>
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.4.6</version>
</dependency>
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
</dependency>
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

1.2创建user数据表

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `uname` varchar(50) DEFAULT NULL,
  `passwd` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

1.3编写User实体类

public class User {

    private int id;
    private String uname;
    private String passwd;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", uname='" + uname + '\'' +
                ", passwd='" + passwd + '\'' +
                '}';
    }
}

1.4编写映射文件UserMapper.xml

(在resources目录下创建com/fbst/mapper/UserMapper.xml)

先引入dtd约束头

<?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="userMapper">
    <select id="findAll" resultType="com.fbst.domain.User">
        select * from user
    </select>
</mapper>

1.5编写核心文件SqlMapConfig.xml

同样先引入dtd约束头

<configuration>

    <!--数据源环境-->
    <environments default="developement">
        <environment id="developement">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--加载映射文件-->
    <mappers>
        <mapper resource="com/fbst/mapper/UserMapper.xml"></mapper>
    </mappers>
    
</configuration>

1.6编写测试代码

public class MyBatisTest {
    
	@Test
    //查询操作
    public void test1() throws IOException {
        //获得核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //获得session工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得session回话对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行操作  参数:namespace+id
        List<User> userList = sqlSession.selectList("userMapper.findAll");
        //打印数据
        System.out.println(userList);
        //释放资源
        sqlSession.close();
    }
}

1.7知识小结

MyBatis开发步骤:

①添加MyBatis的坐标

②创建user数据表

③编写User实体类

④编写映射文件UserMapper.xml

⑤编写核心文件SqlMapConfig.xml

⑥编写测试类

2.MyBatis核心配置文件概述

2.1MyBatis常用配置解析

environments标签

数据库环境的配置,支持多环境配置

<!--指定默认的环境名称-->
<environments default="developement">
    <!--指定当前环境的名称-->
    <environment id="developement">
        <!--指定事务管理类型是JDBC-->
        <transactionManager type="JDBC"></transactionManager>
        <!--指定当前数据源类型是连接池-->
        <dataSource type="POOLED">
            <!--数据源配置的基本参数-->
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </dataSource>
    </environment>
</environments>

mapper标签

该标签的作用是加载映射的,加载方式有如下几种:

使用相对于类路径的资源引用,例如:

<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

使用完全限定资源定位符(URL),例如:

<mapper url="file:///var/mappers/AuthorMapper.xml"/>

使用映射器接口实现类的完全限定类名,例如:

<mapper class="org.mybatis.builder.AuthorMapper"/>

将包内的映射器接口实现全部注册为映射器,例如:

<package name="org.mybatis.builder"/>

properties标签

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件

<properties resource="jdbc.properties"></properties>

<environments default="developement">
    <environment id="developement">
        <transactionManager type="JDBC"></transactionManager>
        <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </dataSource>
    </environment>
</environments>

typeAliases标签

类型别名是为Java 类型设置一个短的名字。原来的类型名称配置如下

<select id="findAll" resultType="com.fbst.domain.User">    select * from User</select>

配置typeAliases,为com.fbst.domain.User定义别名为user

<typeAliases>
    <typeAlias type="com.fbst.domain.User" alias="user"></typeAlias>
</typeAliases>

<select id="findAll" resultType="user">
	select * from User
</select>

上面我们是自定义的别名,mybatis框架已经为我们设置好的一些常用的类型的别名

别名数据类型
stringString
longLong
intInteger
doubleDouble
booleanBoolean

2.2知识小结

核心配置文件常用配置:

1、properties标签:该标签可以加载外部的properties文件

<properties resource="jdbc.properties"></properties>

2、typeAliases标签:设置类型别名

<typeAliases>
	<typeAlias type="com.fbst.domain.User" alias="user"></typeAlias>
</typeAliases>

3、mappers标签:加载映射配置

<mappers>
	<mapper resource="com/fbst/mapper/UserMapper.xml"></mapper>
</mappers>

3. MyBatis的映射文件概述

<?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="userMapper">
    <select id="findAll" resultType="user">
        select * from user
    </select>
</mapper>

3.1约束头

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

3.2根标签、命名空间

<mapper namespace="userMapper"></mapper>

< mapper>< /mapper>:根标签

namespace=“userMapper”:命名空间,与下面语句的id一起组成查询的标识

3.3业务操作以及返回的类型

<select id="findAll" resultType="com.fbst.domain.User">
	select * from user
</select>

<select>:查询操作,可选的还有insert、update、delete

id=“findAll”:语句的id标识,与上面的命名空间一起组成查询的标识

resultType=“com.fbst.domain.User”:查询结果对应的实体类型

select * from user:要执行的sql语句

4.MyBatis的增删改查操作

4.1 MyBatis的插入数据操作

编写UserMapper映射文件

insert into user values(#{id},#{uname},#{passwd})中的id、username、password对应实体类User的属性名称

<insert id="save" parameterType="com.fbst.domain.User">
	insert into user values(#{id},#{uname},#{passwd})
</insert>

编写插入实体User的代码

public void test2() throws IOException {
    //模拟user对象
    User user = new User();
    user.setUname("xxx");
    user.setPasswd("abc");
    //获得核心配置文件
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    //获得session工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //获得session回话对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    //执行操作  参数:namespace+id
    sqlSession.insert("userMapper.save", user);
    //mybatis执行更新操作  提交事务
    //sqlSession.commit();
    //释放资源
    sqlSession.close();
}

更新操作必须要提交事务,不提交失误信息是不会保存的

mybatis执行更新操作 提交事务:

方式一:sqlSession.insert(“userMapper.save”, user);

方式二:sqlSession.commit();

插入操作注意问题

插入语句使用insert标签

在映射文件中使用parameterType属性指定要插入的数据类型

Sql语句中使用#{实体属性名}方式引用实体中的属性值

插入操作使用的API是sqlSession.insert(“命名空间.id”,实体对象);

插入操作涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即sqlSession.commit()

4.2MyBatis的修改数据操作

编写UserMapper映射文件

<update id="update" parameterType="com.fbst.domain.User">
	update user set uname=#{uname},passwd=#{passwd} where id=#{id}
</update>

编写修改实体User的代码

public void test3() throws IOException {
    //模拟user对象
    User user = new User();
    user.setId(7);
    user.setUname("lucy");
    user.setPasswd("123");
    //获得核心配置文件
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    //获得session工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //获得session回话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行操作  参数:namespace+id
    sqlSession.update("userMapper.update", user);
    //mybatis执行更新操作  提交事务
    sqlSession.commit();
    //释放资源
    sqlSession.close();
}

修改操作注意问题

修改语句使用update标签

修改操作使用的API是sqlSession.update(“命名空间.id”,实体对象);

4.3MyBatis的删除数据操作

编写UserMapper映射文件

<delete id="delete" parameterType="int">
	delete from user where id=#{id}
</delete>

编写删除实体User的代码

public void test4() throws IOException {
    //获得核心配置文件
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    //获得session工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //获得session回话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行操作  参数:namespace+id
    sqlSession.delete("userMapper.delete", 3);
    //mybatis执行更新操作  提交事务
    sqlSession.commit();
    //释放资源
	sqlSession.close();
}

删除操作注意问题

删除语句使用delete标签

Sql语句中使用#{任意字符串}方式引用传递的单个参数

删除操作使用的API是sqlSession.delete(“命名空间.id”,Object);

4.4MyBatis的查询数据操作

编写UserMapper映射文件

<select id="findAll" resultType="user">
	select * from user
</select>

编写查询实体User的代码

public void test1() throws IOException {
    //获得核心配置文件
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    //获得session工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //获得session回话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行操作  参数:namespace+id
    List<User> userList = sqlSession.selectList("userMapper.findAll");
    //打印数据
    System.out.println(userList);
    //释放资源
    sqlSession.close();
}

查询操作注意问题

查询语句使用select标签

查询操作使用的API是sqlSession.selectXxx(“命名空间.id”);

查询结果和使用的API返回值类型相同

4.5知识小结

增删改查映射配置与API:

查询数据:List userList = sqlSession.selectList(“userMapper.findAll”);

<select id="findAll" resultType="user">
	select * from user
</select>

添加数据:sqlSession.insert(“userMapper.save”, user);

<insert id="save" parameterType="com.fbst.domain.User">
	insert into user values(#{id},#{uname},#{passwd})
</insert>

修改数据:sqlSession.update(“userMapper.update”, user);

<update id="update" parameterType="com.fbst.domain.User">
	update user set uname=#{uname},passwd=#{passwd} where id=#{id}
</update>

删除数据:sqlSession.delete(“userMapper.delete”, number);

<delete id="delete" parameterType="int">
	delete from user where id=#{id}
</delete>

5.MyBatis的Dao层实现方式

5.1传统开发方式

编写UserDao接口

public interface UserMapper {
    public List<User> findAll() throws IOException;
}

编写UserDaoImpl实现

public class UserDaoImpl implements UserDao {
    public List<User> findAll() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");        					SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);        		 SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> userList = sqlSession.selectList("userMapper.findAll");
        sqlSession.close();
        return userList;
    }
}

测试传统方式

@Test
public void testTraditionDao() throws IOException {
    UserDao userDao = new UserDaoImpl();
    List<User> all = userDao.findAll();
    System.out.println(all);
}

5.2代理开发方式

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。

Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper 接口开发需要遵循以下规范:

1、 Mapper.xml文件中的namespace与mapper接口的全限定名相同

<mapper namespace="com.fbst.dao.UserMapper"></mapper>

2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同(select等标签中的id属性)

3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同

4、 Mapper接口方法的输出参数类型(返回值)和mapper.xml中定义的每个sql的resultType的类型相同

public User findById(int id);
<select id="findById" parameterType="int" resultType="com.fbst.domain.User">
	select * from user where id=#{id}
</select>

5.3知识小结

MyBatis的Dao层实现的两种方式:

手动对Dao进行实现:

传统开发方式

代理方式对Dao进行实现:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

6.MyBatis映射文件深入

6.1动态sql语句

动态sql之if标签

我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

<select id="findByCondition" parameterType="user" resultType="user">
	<where>
		<if test="id!=0">
			and id=#{id}
		</if>
		<if test="username!=null">
			and username=#{username}
		</if>
		<if test="password!=null">
			and password=#{password}
		</if>
	</where>
</select>

测试代码:

@Test
public void test1() throws IOException {
    
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    //模拟条件user
    User condition = new User();
    condition.setId(1);
    condition.setUsername("zhangsan");
    condition.setPassword("123");

    List<User> userList = mapper.findByCondition(condition);
    System.out.println(userList);
}

动态sql之foreach标签

循环执行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2,5)。

<select id="findByIds" parameterType="list" resultType="user">
    <where>
        <foreach collection="list" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

测试代码:

@Test
public void test1() throws IOException {
    
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    //模拟ids的数据
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(2);

    List<User> userList = mapper.findByIds(ids);
    System.out.println(userList);
}

foreach标签的属性含义如下:

foreach标签用于遍历集合,它的属性:

collection:代表要遍历的集合元素,注意编写时不要写#{}

open:代表语句的开始部分

close:代表结束部分

item:代表遍历集合的每个元素,生成的变量名

sperator:代表分隔符

6.2SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的,所以上面映射文件可以优化为:

<!--sql语句抽取-->
<sql id="selectUser">select * from user</sql>

<select id="findByCondition" parameterType="user" resultType="user">
	<include refid="selectUser"></include>
	<where>
		<if test="id!=0">
			and id=#{id}
		</if>
		<if test="username!=null">
			and username=#{username}
		</if>
		<if test="password!=null">
			and password=#{password}
		</if>
	</where>
</select>

<select id="findByIds" parameterType="list" resultType="user">
	<include refid="selectUser"></include>
	<where>
		<foreach collection="list" open="id in(" close=")" item="id" separator=",">
			#{id}
		</foreach>
	</where>
</select>

6.3知识小结

MyBatis映射文件配置:

<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<where>:where条件
<if>:if判断
<foreach>:循环
<sql>:sql片段抽取
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值