第1步:开启spring容器的自动扫描功能
第2步:引入外部的数据库配置描述文件
第3步:配置数据源连接池:C3P0,DBCP2,DRUID
第4步:配置SessionFactory
第5步:配置MapperScanner
第6步:配置事务管理器
第7步:配置spring管理事务的2种方式:编程式事务管理,声明式事务管理(一般用声明式)
第8步:开启切面动态代理支持
需要jar包(必须):aspectjrt、aspectjweaver、commons-dbcp2、mybatis-spring、mybatis、mysql-connector-java、spring-context、spring-jdbc
测试jar包(可选):spring-test、junit
日志jar包(可选):log4j
mysql.properties文件:(连接数据库要要用到的信息)
jdbc.driver=org.gjt.mm.mysql.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true
jdbc.username=root
jdbc.password=1234
这里配置有个注意的地方:
有个常见的场景:删除用户的时候需要先删除用户的外键关联数据,否则会触发规则报错。
解决办法不外乎有三个:1、多条sql分批执行;2、存储过程或函数调用;3、sql批量执行。
今天我要说的是MyBatis中如何一次执行多条语句(使用mysql数据库)。
1、修改数据库连接参数加上allowMultiQueries=true,如:
jdbc.url=jdbc:mysql://xx.xx.xx:3306/xxxxx?characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true
2、直接写多条语句,用“;”隔开即可
delete from sec_user_role where userId=#{id};
delete from sec_user where id=#{id};
applicationContext.xml文件配置:
第一种声明式方式中,
我更倾向于使用第一种声明式方式,如果用了第二种声明式@Transactional的方式,那么需要在业务层的方法上加上@Transactional注解,如下(我这里用了第二种):
/**
* @Service 表示该Java类是一个需要被spring容器管理起来的业务层的组件
* 默认情况下,spring容器扫描到该组件之后,将会将该类的类名 “首字母小写后的字符串”,作为该组件在容器中的ID
* 当然你也可以通过@Service("sb")这种方式去改
* @author Administrator
*
*/
@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
@Service
public class UserServiceImpl implements IUserService {
/**
* @Resource 约== @Autowired + @Qualifier
* 默认情况下,@Resource将先按照byName装配方式进行精准装配,如果装配失败,将回退到byType装配方式
*
* 如果你指定了name="userDaoImpl3" ,那么将严格按照byName的装配方式,不会回退
*/
@Resource
private IUserDao userDaoImpl;
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@MyLog(value="用户管理",type=LogEnum.ADD)
@Override
public UserBean saveUserBean(UserBean user) {
// TODO Auto-generated method stub
userDaoImpl.addUserBean(user);
return user;
}
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@MyLog(value="用户管理",type=LogEnum.ADD)
@Override
public int addBatchUserBean(List users) {
// TODO Auto-generated method stub
return userDaoImpl.addBatchUserBean(users);
}
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@MyLog(value="用户管理",type=LogEnum.UPDATE)
@Override
public int updateUserBean(UserBean user) {
// TODO Auto-generated method stub
return userDaoImpl.updateUserBean(user);
}
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@MyLog(value="用户管理",type=LogEnum.DELETE)
@Override
public int deleteUserBean(UserBean user) {
// TODO Auto-generated method stub
return userDaoImpl.deleteUserBean(user);
}
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@MyLog(value="用户管理",type=LogEnum.DELETE)
@Override
public int deleteBatchUserBean(int[] ids) {
// TODO Auto-generated method stub
return userDaoImpl.deleteBatchUserBean(ids);
}
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@MyLog(value="用户管理",type=LogEnum.DELETE)
@Override
public int deleteUserBean(Integer id) {
// TODO Auto-generated method stub
return userDaoImpl.deleteUserBean(id);
}
@Override
public UserBean getUserBeanById(Integer id) {
// TODO Auto-generated method stub
return userDaoImpl.getUserBeanById(id);
}
@Override
public Map queryUserBeanById(Integer id) {
// TODO Auto-generated method stub
return userDaoImpl.queryUserBeanById(id);
}
@Override
public List
@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 这个注解的几个属性含义:
readOnly:表示是否操作的数据库时是否只读
propagation:表示这些方法如何使用这些事务,有七种方式:
REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
rollbackFor:表示在什么时候进行回滚,这里是发生异常回滚
要做事务提交和回滚的只有增删改操作,所以查询我们就不用去加这个注解,那个@Mylog注解不用管,这个是我自己写的,主要是用AOP来做操作日志记录的,跟本次配置无关。
MyLog注解:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.gezhi.sm.enumration.LogEnum;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
/**
* value 代表着 具体的操作模块
* @return
*/
String value() default "";
/**
* 操作类型 0- 新增,1-修改,2-删除
* @return
*/
LogEnum type();
}
maven的pom.xml
4.0.0
com.ali
sm
1.0
jar
sm
http://maven.apache.org
UTF-8
4.12
1.2.17
4.3.14.RELEASE
1.8.9
3.3.0
5.1.38
2.4.0
org.aspectj
aspectjrt
${aspect.version}
org.aspectj
aspectjweaver
${aspect.version}
org.apache.commons
commons-dbcp2
${dbcp.version}
org.mybatis
mybatis-spring
1.3.2
org.mybatis
mybatis
${mybatis.version}
mysql
mysql-connector-java
${mysql.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-test
${spring.version}
test
junit
junit
${junit.version}
test
log4j
log4j
${log4j.version}
org.apache.maven.plugins
maven-compiler-plugin
3.8.0
1.8