智勇! 你在吗?点个赞走吧!认真听讲!靠你了。别睡了…
言归正传,正片开始…
// 本章介绍:MyBatis和Spring整合,会有两种方法,这里使用了两个项目如有不明白的可以下载/资源—— 点击.
Spring框架提供了IOC机制,可以管理所有组件(Java类 )的创建工作,并进行依赖管理;
因此,整合的核心操作就是把:MyBatis框架所涉及的核心组件 匹配到Spring容器中,交给Spring创建;
业务逻辑对象依赖于MyBatis技术实现的 Dao对象;(业务逻辑的实现,需要对应Dao类的实现方法来实现…)
核心是获取SqlSession实例
,而 SqlSession 依赖于 SqlSessionFactory
(SqlSession工厂).
工厂又依赖于 SqlSessionBuilder
依据MyBatis配置文件中的数据源,Sql映射文件来构建的;
随着:Spring框架的引入,以上流程都将交给 Spring框架的Bean容器来完成的了… 管理生命周期,并对其之间的依赖关系进行解耦操作…
所以MyBatis的核心配置文件才会这么简介; 太棒了! 是不是学会这个又少写代码了!
Spring和Mybatis整合需要 mybatis-spring-1.2.0.jar
对于Spring的事务操作还需要加入:spring-jdbc-3.2.13.RELEASE.jar
和 spring-tx-3.2.13.RELEASE.jar
两个Jar文件
Myelicpse工具对一些Jar进行了整合:
在web项目上 ——右击项目——选择MyElicpse项——project facets [capabilities] 项—— 在选择:Install Spring Face(小绿叶标志)——next…勾选 —— Finish
图解:
并在项目中加入 Spring MyBatis相关的 jar文件;
开发环境:Mysql5.5.6 Myelicpse…
两种方法针对的数据库都是一样的:
cart.sql
/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.56 : Database - cart
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`cart` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `cart`;
/*Table structure for table `cart` */
DROP TABLE IF EXISTS `cart`;
CREATE TABLE `cart` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`brand` varchar(20) NOT NULL,
`price` float NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
/*Data for the table `cart` */
insert into `cart`(`id`,`name`,`brand`,`price`) values (1,'lala','las',12.5),(2,'aaa','as',12),(3,'sasa','sasaa',12),(4,'宏光','五菱',123),(9,'asda','保时捷',123);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
ok 数据库有了第一步,我通常喜欢创建 实体类:
cart.Java
//实体类:
public class Cart {
//注意与数据库匹配哦~
private int id;
private String name;
private String brand;
private double price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
实体类这种小ks ,就不说了; 智勇对不!
之后就是Dao的接口:
CartMapper .java
import java.util.List;
import com.wsm.entity.Cart;
public interface CartMapper {
//查看
public List<Cart> selcha();
//新增
public int insertadd(Cart c);
//删除
public int del(int id);
}
接口有了就是 MyBatis的文件映射来实现:之后就是 MyBatis的核心配置文件 mybatis-config.xml 来进行引用;
当前这里对应 MyBatis的一些代码就没有注释了,基础差的朋友可以 ,欢迎看我之前的文章, 欢迎点赞支持!
cartMapper.xml
<mapper namespace="com.wsm.dao.CartMapper" >
<select id="selcha" resultType="com.wsm.entity.Cart" >
SELECT * FROM `cart`
select>
<insert id="insertadd" parameterType="com.wsm.entity.Cart" >
INSERT `cart` VALUE(NULL,#{name},#{brand},#{price})
insert>
mapper>
mybatis-config.xml
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
<mappers>
<mapper resource="mapper/cartMapper.xml" />
mappers>
configuration>
lo4g配置文件: log4j.properties
其实我不想展示的但是可以让文章更长就加上吧,哈哈哈哈;
log4j.rootLogger=DEBUG,CONSOLE,file
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.cn.smbms.dao=debug
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug
log4j.logger.java.sql.ResultSet=debug
log4j.logger.org.tuckey.web.filters.urlrewrite.UrlRewriteFilter=debug
######################################################################################
# Console Appender \u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n
######################################################################################
# DailyRolling File \u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u683c\u5f0f:log2009-09-11
######################################################################################
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=error
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
log4j.logger.com.opensymphony.xwork2=error
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/cart" >property>
<property name="username" value="root" >property>
<property name="password" value="ok" >property>
bean>
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" >property>
<property name="configLocation" value="classpath:mybatis-config.xml" >property>
bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" >
<constructor-arg>
<ref bean="SqlSessionFactory"/>
constructor-arg>
bean>
<context:component-scan base-package="com." />
beans>
CartMapperImpl.java
通过 sqlSessionTemplate 来完成数据库访问操作;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.wsm.dao.CartMapper;
import com.wsm.entity.Cart;
@Repository
public class CartMapperImpl implements CartMapper {
@Autowired //自动找的Spring中对应的实例Bean引用;创建实例;
private SqlSessionTemplate sqlSessionTemplate;
@Override
public List<Cart> selcha() {
// TODO Auto-generated method stub
return sqlSessionTemplate.selectList("com.wsm.dao.CartMapper.selcha"); //sql映射文件 命名空间+id;找到对应sql
}
@Override
public int insertadd(Cart c) {
// TODO Auto-generated method stub
return sqlSessionTemplate.insert("com.wsm.dao.CartMapper.insertadd",c);
}
@Override
public int del(int id) {
// TODO Auto-generated method stub
return sqlSessionTemplate.insert("com.wsm.dao.CartMapper.del",id);
}
}
智勇你还在吗?
Service: 业务逻辑层,调用Dao的方法来实现实现操做;
接口**CartService.java
**
import java.util.List;
import com.wsm.entity.Cart;
public interface CartService {
public List<Cart> selcha();
public int insertadd(Cart c);
//删除
public boolean del(int id);
//增删
public void zs(Cart c,int id);
}
接口实现:CartSercviceImpl.java
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wsm.dao.CartMapper;
import com.wsm.entity.Cart;
import com.wsm.service.CartService;
@Service("csi") //实例Bean id="csi"
public class CartSercviceImpl implements CartService {
@Autowired //自动匹配对应接口的实现;
private CartMapper cartMapper;
@Override
public List<Cart> selcha() {
// TODO Auto-generated method stub
return cartMapper.selcha();
}
@Override
public int insertadd(Cart c) {
// TODO Auto-generated method stub
return cartMapper.insertadd(c);
}
@Override
public boolean del(int id) {
return cartMapper.del(id)==1;
}
@Override
public void zs(Cart c, int id) {
// TODO Auto-generated method stub
this.insertadd(c);
//System.out.println(1/0); //手动抛出异常;
this.del(id);
}
}
没错这就写完了!!!
Test.java
import java.util.List;
import java.util.Scanner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.wsm.entity.Cart;
import com.wsm.service.CartService;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
CartService cm = (CartService)context.getBean("csi");
Scanner inpScanner = new Scanner(System.in);
System.out.println("欢迎进入系统");
System.out.println("1.查询 \t 2.添加(请选择)");
int xuan = inpScanner.nextInt();
switch (xuan) {
case 1:
List<Cart> cs = cm.selcha();
System.out.println("编号\t名称\t品牌\t价格");
for (Cart c: cs) {
System.out.println(c.getId()+"\t"+c.getName()+"\t"+c.getBrand()+"\t"+c.getPrice());
}
break;
case 2:
System.out.println("新增车辆");
System.out.println("请输入车名");
String name = inpScanner.next();
System.out.println("请输入品牌");
String brand = inpScanner.next();
System.out.println("请输入价格");
double price = inpScanner.nextDouble();
Cart c = new Cart();
c.setBrand(brand);
c.setName(name);
c.setPrice(price);
System.out.println("请输入删除的ID");
int id = inpScanner.nextInt();
cm.zs(c, id); //调用增删方法来实现,注意要结合数据库查看验证哦; 增一个删一个!异常不增不删
System.out.println("完成");
break;
default:
break;
}
}
}
方式二很简单的; 比上面还要少代码哦!!
在上面基础上更改! 删除Dao的实现类Spirng 核心代码更改
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/cart" >property>
<property name="username" value="root" >property>
<property name="password" value="ok" >property>
bean>
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" >property>
<property name="configLocation" value="classpath:mybatis-config.xml" >property>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
<property name="basePackage" value="com.wsm.dao" >property>
bean>
<context:component-scan base-package="com." />
beans>
ok了! 就这! 智勇都惊呆了 0.0
添加事务主要, 在 Spring配置信息中增加 配置;
applicationContext.xml
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="zs*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true" />
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut expression="execution (* com.wsm.service.impl.*.*(..))" id="myprint"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myprint"/>
aop:config>
// 之后就可以看到 环绕的小图标; 运行代码主动抛出异常,查看事务是否成立! 事务回滚即可!!
// 事务增强 也是AOP增强的一种两者不相互影响; 可以公用!
介绍事务属性:
除了上面的事务处理,Spring还支持,使用注解完成事务操作;
又是一个 省写代码的操作 ! 只需要修改 applicationContext 和 CartSercviceImpl 一点点即可;
applicationContext.xml
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
bean>
<tx:annotation-driven transaction-manager="txManager" />
是的没错就是这么点代码! 当然 Service需要注解标识
CartSercviceImpl.java
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.wsm.dao.CartMapper;
import com.wsm.entity.Cart;
import com.wsm.service.CartService;
@Transactional //使用注解来配置事务; 我凑就一行!
@Service("csi") //实例Bean id="csi"
public class CartSercviceImpl implements CartService {
@Autowired //自动匹配对应接口的实现;
private CartMapper cartMapper;
@Transactional //如果有的事务,会有不同的操作可以单独进行设置;!我凑太方便了吧!
@Override
public List<Cart> selcha() {
// TODO Auto-generated method stub
return cartMapper.selcha();
}
@Override
public boolean insertadd(Cart c) {
// TODO Auto-generated method stub
return cartMapper.insertadd(c)==1; //新增
}
@Override
public boolean del(int id) {
return cartMapper.del(id)==1;
}
@Override
public void zs(Cart c, int id) {
// TODO Auto-generated method stub
this.insertadd(c);
System.out.println(1/0); //手动抛出异常;
this.del(id);
}
}
使用注解实现事务处理
属性 | 类型 | 说明 |
---|---|---|
propagation | 枚举型:Propagation | 可选的传播性设置。使用举例:@Transactional( propagation=Propagation.REQUIRES_NEW ) |
isolation | 枚举型:Isolation | 可选的隔离性级别。使用举例:@Transactional( isolation=Isolation.READ_COMMITTED) |
readOnly | 布尔型 | 是否为只读型事务。使用举例:@Transactional(readOnly=true) |
timeout | int型(以秒为单位) | 事务超时。使用举例:Transactional(timeout=10) |
rollbackFor | 一组 Class 类的实例,必须是Throwable的子类 | 一组异常类,遇到时 必须 回滚。使用举例:@Transactional(rollbackFor={SQLException.class}),多个异常用逗号隔开 |
rollbackForClassName | 一组 Class 类的名字,必须是Throwable的子类 | 一组异常类名,遇到时 必须 回滚。使用举例:@Transactional(rollbackForClassName={“SQLException”}),多个异常用逗号隔开 |
noRollbackFor | 一组 Class 类的实例,必须是Throwable的子类 | 一组异常类,遇到时 必须不 回滚 |
noRollbackForClassName | 一组 Class 类的名字,必须是Throwable的子类 | 一组异常类名,遇到时 必须不 回滚 |
首先说下,事务都明白是什么吧! 一致性 隔离性 持久性 原子性
非常简单就在这个代码基础上增加吧! 为了体现出事务. 加了一个新增 删除; 验证事务异常回滚~, 确保一致性;