SSM框架快速入门——笔记

文章目录

  • 写在前面
  • 正文
  • 一、SpringIOC(xml)
    • 1.快速入门
    • 2.知识要点
    • 3.配置文件
      • 3.1Bean标签范围配置
      • 3.2Bean生命周期配置
      • 3.3Bean实例化的三种方式
      • 3.4 Bean的依赖注入方式
      • 3.5 引入其他配置文件(分模块开发)
      • 3.6 知识要点
    • 4.Spring相关API
      • 4.1ApplicationContext的实现类
      • 4.2 getBean()方法使用
      • 4.3知识要点
  • 二、Spring IOC(注解)
    • 1.Spring原始注解
    • 2.Spring注解开发
    • 3.Spring新注解
  • 三、Spring集成Junit
  • 四、Spring配置数据源
    • 1.数据源的开发步骤
    • 2.Spring配置
    • 3.抽取jdbc配置文件
  • 五、Spring MVC
    • 1.Spring集成web环境
    • 2.Spring MVC快速入门
    • 3.知识要点
  • 六、Spring MVC视图解析器
  • 七、Spring AOP
    • 1.基于XML的AOP开发
      • 1.1快速入门
      • 1.2切点表达式的写法
      • 1.3通知的类型
      • 1.4 切点表达式的抽取
      • 1.5知识要点
    • 2.基于注解的AOP开发
      • 2.1快速入门
      • 2.2注解配置详解
      • 2.3知识要点
    • 3.基于XML的声明式事务控制
      • 3.1.声明式事务控制的实现
      • 3.2切点方法的事务参数的配置
      • 3.3知识要点
    • 4.基于注解的声明式事务控制
      • 4.1使用注解配置声明式事务控制
      • 4.2注解配置声明式事务控制解析
      • 4.3知识要点
  • 八、Mybatis
    • 1.Mybatis快速入门
      • 1.1添加MyBatis坐标和其他相关坐标
      • 1.2创建user数据表
      • 1.3编写User实体类
      • 1.4编写映射文件UserMapper.xml
      • 1.5编写核心文件SqlMapConfig.xml
      • 1.6编写测试代码
      • 1.7知识小结
    • 2.MyBatis核心配置文件概述
      • 2.1MyBatis常用配置解析
      • 2.2知识小结
    • 3. MyBatis的映射文件概述
      • 3.1约束头
      • 3.2根标签、命名空间
      • 3.3业务操作以及返回的类型
    • 4.MyBatis的增删改查操作
      • 4.1 MyBatis的插入数据操作
      • 4.2MyBatis的修改数据操作
      • 4.3MyBatis的删除数据操作
      • 4.4MyBatis的查询数据操作
      • 4.5知识小结
    • 5.MyBatis的Dao层实现方式
      • 5.1传统开发方式
      • 5.2代理开发方式
      • 5.3知识小结
    • 6.MyBatis映射文件深入
      • 6.1动态sql语句
      • 6.2SQL片段抽取
      • 6.3知识小结

写在前面

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

正文

一、SpringIOC(xml)

1.快速入门

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

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

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-contextartifactId>
  <version>5.0.5.RELEASEversion>
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");//通过标签中的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 多例的
request WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
session WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
global session WEB 项目中,应用在 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配置文件中的一样
@bean 使用在方法上,标注将该方法的返回值存储到Spring容器中
@PropertySource 用于加载properties文件中的配置
@Important 用于导入其他配置类

创建核心配置类:

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

}

注解说明:

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

三、Spring集成Junit

开发步骤

①导入spring集成Junit的坐标

<dependency>
   <groupId>org.springframeworkgroupId>
   <artifactId>spring-testartifactId>
   <version>5.0.5.RELEASEversion>
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>mysqlgroupId>
	<artifactId>mysql-connector-javaartifactId>
	<version>5.1.32version>
dependency>
<dependency>
	<groupId>c3p0groupId>
	<artifactId>c3p0artifactId>
	<version>0.9.1.2version>
dependency>
<dependency>
	<groupId>com.alibabagroupId>
	<artifactId>druidartifactId>
	<version>1.1.10version>
dependency>
<dependency>
	<groupId>junitgroupId>
	<artifactId>junitartifactId>
	<version>4.12version>
	<scope>testscope>
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.springframeworkgroupId>
	<artifactId>spring-contextartifactId>
	<version>5.0.5.RELEASEversion>
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


<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.servletgroupId>
	<artifactId>javax.servlet-apiartifactId>
	<version>3.0.1version>
	<scope>providedscope>
dependency>
<dependency>
	<groupId>javax.servlet.jspgroupId>
	<artifactId>javax.servlet.jsp-apiartifactId>
	<version>2.2.1version>
	<scope>providedscope>
dependency>
<dependency>
	<groupId>org.springframeworkgroupId>
	<artifactId>spring-webartifactId>
	<version>5.0.5.RELEASEversion>
dependency>

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


<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>


<context-param>
	<param-name>contextConfigLocationparam-name>
	<param-value>classpath:applicationContext.xmlparam-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.springframeworkgroupId>
    <artifactId>spring-contextartifactId>
    <version>5.0.5.RELEASEversion>
dependency>
<dependency>
	<groupId>org.springframeworkgroupId>
	<artifactId>spring-webmvcartifactId>
	<version>5.0.5.RELEASEversion>
dependency>
<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>3.0.1version>
    <scope>providedscope>
dependency>
<dependency>
    <groupId>javax.servlet.jspgroupId>
    <artifactId>javax.servlet.jsp-apiartifactId>
    <version>2.2.1version>
    <scope>providedscope>
dependency>

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


<servlet>
	<servlet-name>DispatcherServletservlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
		<param-name>contextConfigLocationparam-name>
		<param-value>classpath:spring-mvc.xmlparam-value>
	init-param>
	
	<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
	<servlet-name>DispatcherServletservlet-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" %>


    Title


	Success!


⑤使用注解配置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"

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

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

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

<init-param>
	<param-name>contextConfigLocationparam-name>
	<param-value>classpath:spring-mvc.xmlparam-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">
    
	<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.springframeworkgroupId>
	<artifactId>spring-contextartifactId>
	<version>5.0.5.RELEASEversion>
dependency>
<dependency>
	<groupId>org.aspectjgroupId>
	<artifactId>aspectjweaverartifactId>
	<version>1.8.4version>
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命名空间


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


<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.springframeworkgroupId>
	<artifactId>spring-testartifactId>
	<version>5.0.5.RELEASEversion>
dependency>
<dependency>
	<groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
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通知的类型

通知的配置语法:

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

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: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自动代理

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: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>

其中, 代表切点方法的事务参数的配置

例如:

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配置文件中要开启事务的注解驱动

4.3知识要点

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

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

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

事务注解驱动的配置

八、Mybatis

1.Mybatis快速入门

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

<dependency>
	<groupId>mysqlgroupId>
	<artifactId>mysql-connector-javaartifactId>
	<version>5.1.32version>
dependency>
<dependency>
	<groupId>org.mybatisgroupId>
	<artifactId>mybatisartifactId>
	<version>3.4.6version>
dependency>
<dependency>
	<groupId>junitgroupId>
	<artifactId>junitartifactId>
	<version>4.12version>
dependency>
<dependency>
	<groupId>log4jgroupId>
	<artifactId>log4jartifactId>
	<version>1.2.17version>
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约束头



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

配置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框架已经为我们设置好的一些常用的类型的别名

别名 数据类型
string String
long Long
int Integer
double Double
boolean Boolean

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的映射文件概述



<mapper namespace="userMapper">
    <select id="findAll" resultType="user">
        select * from user
    select>
mapper>

3.1约束头



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 id="selectUser">select * from usersql>

<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片段抽取

你可能感兴趣的:(笔记,SSM)