spring与mybatis集成的步骤:
1、创建java工程
2、导入jar
spring 4.2
core,beans,context,expression,aop,aspects
增加: jdbc(与数据库进行操作),orm(对象关系映射),tx(事务)
spring 3.0.2
logging,aop联盟,织入包
数据库相关的
mysql,druid(阿里巴巴提供的数据库连接池的jar)
mybatis:
mybatis.jar, mybatis-spring.jar, log4j.jar ,cglib-nodep-2.1_3.jar
3、创建db.properties文件,用于封装数据库的连接信息
4、导入log4j.properties
log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
5、编写spring的主配置文件 applicationContext.xml
<!--组件扫描-->
<context:component-scan base-package="org.java"/>
<!--加载属性文件-->
<context:property-placeholder location="db.properties"/>
<!--配置数据源DataSource-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${url}"/>
<property name="driverClassName" value="${driver}"/>
<property name="username" value="${user}"/>
<property name="password" value="${pwd}"/>
</bean>
<!--配置sqlsession的工厂类,用于产生sqlsession-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引用数据源-->
<property name="dataSource" ref="dataSource"/>
<!--给包下面的实体类指定别名-->
<property name="typeAliasesPackage" value="org.java.entity"/>
</bean>
<!--扫描所有的Mapper接口-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.java.dao"/>
</bean>
6、编写实体类
package org.java.entity;
import java.io.Serializable;
public class Inf implements Serializable {
private Integer id;
private String name;
private Integer score;
@Override
public String toString() {
return "Inf{" +
"id=" + id +
", name='" + name + '\'' +
", score=" + score +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
}
7、编写Mapper接口(Dao接口)
8、编写Mapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.java.dao.InfMapper">
<insert id="add" parameterType="inf">
insert into inf values(null,#{name},#{score})
</insert>
</mapper>
9、编写Service接口
10、编写Service实现类
package org.java.service.impl;
import org.java.dao.InfMapper;
import org.java.entity.Inf;
import org.java.service.InfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("infService")
public class InfServiceImpl implements InfService {
@Autowired
private InfMapper infMapper;
@Override
public void add(Inf f) {
infMapper.add(f);
}
}
11、编写Demo类进行测试
package org.java.demo;
import org.java.entity.Inf;
import org.java.service.InfService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
public static void main(String[] args) {
ApplicationContext cxf = new ClassPathXmlApplicationContext("applicationContext.xml");
InfService service = (InfService) cxf.getBean("infService");
Inf f = new Inf();
f.setName("mariah");
f.setScore(92);
service.add(f);
}
}
问题:以前如何连接数据库?
答:以前没有数据库连接池时,要连接数据库,需要自己创建数据库连接,用完以后,关闭资源时,又会将连接销毁掉,
这样频繁的创建、销毁连接是需要消耗更多系统资源
配置数据库连接池以后,程序在启动时,将会创建一定数量的连接,放入连接池中,当用户需要连接数据库,系统会从
连接池中取得一个连接,有了该连接就可以连接上数据库,当用完以后,关闭资源时,连接并不会真正的释放,它只是将
用的连接,放回到连接池中,其他用户可以继续使用
连接池中可以设置下面几个参数:
- 最小闲置连接数:系统要保证连接池中随时都有一定数量的闲置连接,保证用户可以随时取到连接,如果闲置连接数低于
- 这个值,系统就会自动创建连接,放入到连接池中
- 最大闲置连接数: 设置连接池中闲置连接的上限,超过上限,系统就会将多余的闲置连接销毁
事务的特性: ACID
- 原子性
- 一致性
- 隔离性
- 持久性
spring中的事务:在业务层的一个方法对数据库执行了相关操作,方法中的所有代码都成功,才进行提交,如果有一个
代码操作失败,整个操作要全部回滚
- 基本要求是:一个方法中的代码,要么都成功,要么都失败
@@@@@@@@@@:在spring应用中,只要涉及到对数据库的操作,都要求要进行事务控制
在spring中处理事务的步骤:
1、在applicationContext.xml文件中,配置事务管理器 TransactionManager
- 作用:它负责执行事务
<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2、配置事务拦器
<!--配置事务拦截器 -->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!--事务管理器-->
<property name="transactionManager" ref="transactionManager"/>
<!--事务属性-->
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">readOnly</prop>
</props>
</property>
</bean>
@@@:事务拦截器的作用: 用于指定,对于业务类中的方法,如何进行事务处理
- transactionManager: 指定,通过哪一个事务管理器来执行事务
- transactionAttributes:事务属性,用于指定,访问的业务类中的每一个方法,如何执行事务
<prop key="add*">PROPAGATION_REQUIRED</prop>
PROPAGATION_REQUIRED:它表示该方法必须在事务的环境下运行,方法中所有代码都运行成功,才会进行提交,如果有一个代码运行失败,整个方法的操作要全部回滚
- add*:当前类,所有以add开头的方法
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">readOnly</prop>
业务类中的方法,如果是以add,del,update开头,都要在事务的环境下运行,都成功才提交,有一个失败就回滚除了add,del,update之外的其他方法,只能执行查询操作,不允许执行增、删、改
事务的几种配置方式:
方式1:自动代理
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--事务拦截器-->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!--事务拦截器-->
<property name="transactionManager" ref="transactionManager"/>
<!--事务属性-->
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">readOnly</prop>
</props>
</property>
</bean>
<!--自动代理-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--要代理的业务类的名称-->
<property name="beanNames">
<list>
<value>infService</value>
</list>
</property>
<!--要调用的事务拦截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
方式2:声明式事务 (对包进行代理)
<!--事务管理器-->
<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="save*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<!--切入点(触发的条件)-->
<aop:pointcut id="beanNames" expression="execution(* org.java.service.*.*(..))"/>
<!--切入点条件满足,通知执行事务操作-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="beanNames"/>
</aop:config>
方式3:注解的方式配置事务
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--启用注解事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional(readOnly = true)
public void find(){
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void save(Inf f) {
infMapper.add(f);//成功-------------相当于成都的账户扣钱
int a = 2/0; //失败-----------------相当于重庆的帐户加钱
}