springboot集成mybatis/分页/transaction
pom.xml
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <!-- <version>4.1.6</version> --> <version>5.1.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
application.yml
spring: application: name: spring-cloud-api-mybatis datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8 username: password: mybatis: config-locations: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml type-aliases-package: com.daimeng
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias alias="Integer" type="java.lang.Integer" /> <typeAlias alias="Long" type="java.lang.Long" /> <typeAlias alias="HashMap" type="java.util.HashMap" /> <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /> <typeAlias alias="ArrayList" type="java.util.ArrayList" /> <typeAlias alias="LinkedList" type="java.util.LinkedList" /> </typeAliases> </configuration>
TransactionAdviceConfig.java
package com.daimeng.api.interceptor; import org.aspectj.lang.annotation.Aspect; import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.interceptor.DefaultTransactionAttribute; import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource; import org.springframework.transaction.interceptor.TransactionInterceptor; /** * 通过AOP切面设置全局事务,拦截service包下面所有方法 * AOP术语:通知(Advice)、连接点(Joinpoint)、切入点(Pointcut)、切面(Aspect)、目标(Target)、代理(Proxy)、织入(Weaving) * @author daimeng * */ @Aspect @Configuration public class TransactionAdviceConfig { /*定义切点变量:拦截com包下所有类的所有方法,返回值类型任意的方法*/ //private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.***.service.*.*(..))"; //..表示包含子路劲 private static final String AOP_POINTCUT_EXPRESSION = "execution (* com..service..*+.*(..))"; @Autowired private PlatformTransactionManager transactionManager; /** * springBoot事务配置 * @return */ @Bean public TransactionInterceptor txAdvice() { DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute(); //如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务 txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); //只读事物、不做更新删除等 DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute(); txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); txAttr_REQUIRED_READONLY.setReadOnly(true); //事务管理规则,声明具备事务管理的方法名 NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource(); source.addTransactionalMethod("add*", txAttr_REQUIRED); source.addTransactionalMethod("save*", txAttr_REQUIRED); source.addTransactionalMethod("delete*", txAttr_REQUIRED); source.addTransactionalMethod("update*", txAttr_REQUIRED); source.addTransactionalMethod("exec*", txAttr_REQUIRED); source.addTransactionalMethod("set*", txAttr_REQUIRED); source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY); return new TransactionInterceptor(transactionManager, source); } /** * 利用AspectJExpressionPointcut设置切面=切点+通知(写成内部bean的方式) * @return */ @Bean public Advisor txAdviceAdvisor() { /* 声明切点的面 * 切面(Aspect):切面就是通知和切入点的结合。通知和切入点共同定义了关于切面的全部内容——它的功能、在何时和何地完成其功能。 * */ AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); /*声明和设置需要拦截的方法,用切点语言描写*/ pointcut.setExpression(AOP_POINTCUT_EXPRESSION); /*设置切面=切点pointcut+通知TxAdvice*/ return new DefaultPointcutAdvisor(pointcut, txAdvice()); } }
Application.java
package com.daimeng.api; import java.util.Properties; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Bean; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInterceptor; @SpringBootApplication @EnableDiscoveryClient //声明成mybatis Dao层的Bean,也可以在DAO/Mapper类上加@Mapper注解声明 @MapperScan("com.daimeng.**.mapper") public class ApiServerApplication { @Value("${datasource.dialect}") private String dialect; @Value("${pagehelper.offsetAsPageNum}") private String offsetAsPageNum; @Value("${pagehelper.rowBoundsWithCount}") private String rowBoundsWithCount; @Value("${pagehelper.reasonable}") private String reasonable; public static void main(String[] args) { SpringApplication.run(ApiServerApplication.class, args); } /** * mysql 分页插件 * @return */ @Bean public PageHelper pageHelper() { PageHelper pageHelper = new PageHelper(); Properties properties = new Properties(); properties.setProperty("offsetAsPageNum", offsetAsPageNum); properties.setProperty("rowBoundsWithCount", rowBoundsWithCount); properties.setProperty("reasonable", reasonable); System.out.println("######################pageHelper#########################"); System.out.println(dialect); System.out.println(offsetAsPageNum); System.out.println(rowBoundsWithCount); System.out.println(reasonable); System.out.println("######################pageHelper#########################"); properties.setProperty("dialect", dialect); // 配置mysql数据库的方言 pageHelper.setProperties(properties); return pageHelper; } /** * mysql 分页插件 * @return */ @Bean public PageInterceptor pageInterceptor() { PageInterceptor pageInterceptor = new PageInterceptor(); Properties properties = new Properties(); System.out.println("######################pageInterceptor#########################"); System.out.println(dialect); System.out.println("######################pageInterceptor#########################"); properties.setProperty("helperDialect", dialect); // 配置mysql数据库的方言 pageInterceptor.setProperties(properties); return pageInterceptor; } }
UserMapper.java
package com.daimeng.api.user.mapper; import java.util.ArrayList; import com.daimeng.api.user.entity.UserEntity; public interface UserMapper { public ArrayList<UserEntity> getAll(); public ArrayList<UserEntity> getUserByLoginName(UserEntity user); public void saveUser(UserEntity user); public Long countUserByLoginName(String loginName); }
UserMapper.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="com.daimeng.api.user.mapper.UserMapper" > <select id="getAll" resultType="com.daimeng.api.user.entity.UserEntity" > SELECT id as id, login_name as loginName, password as password, realname as realName, email as email, phone as phone FROM sys_user <if test="loginName != null and loginName != ''"> and login_name = #{loginName} </if> order by id asc </select> <select id="getUserByLoginName" resultType="com.daimeng.api.user.entity.UserEntity" > SELECT id as id, login_name as loginName, password as password, realname as realName, email as email, phone as phone FROM sys_user where 1=1 <if test="loginName != null and loginName != ''"> and login_name = #{loginName} </if> order by id asc </select> <insert id="saveUser" > insert into sys_user(login_name,password) values(#{loginName},#{password}) </insert> <select id="countUserByLoginName" resultType="java.lang.Long" > SELECT count(id) FROM sys_user where 1=1 and login_name = #{0} </select> </mapper>
UserService.java
package com.daimeng.api.user.service; import java.util.ArrayList; import com.daimeng.api.user.entity.UserEntity; import com.github.pagehelper.PageInfo; public interface UserService { public ArrayList<UserEntity> getAll(); public PageInfo<UserEntity> getPage(Integer pageNum); public ArrayList<UserEntity> getUserByLoginName(UserEntity user); public void saveUser(UserEntity user); }
UserServiceImpl.java
package com.daimeng.api.user.service.impl; import java.util.ArrayList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.daimeng.api.user.entity.UserEntity; import com.daimeng.api.user.mapper.UserMapper; import com.daimeng.api.user.service.UserService; import com.daimeng.api.utils.Constants; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public ArrayList<UserEntity> getAll() { try { ArrayList<UserEntity> list = userMapper.getAll(); return list; } catch (Exception e) { System.out.println(e.getMessage()); } return null; } @Override public ArrayList<UserEntity> getUserByLoginName(UserEntity user) { try { ArrayList<UserEntity> list = userMapper.getUserByLoginName(user); return list; } catch (Exception e) { System.out.println(e.getMessage()); } return null; } /** * springboot实现事务只需要 在头上加上@Transactional注解 * @Transactional 默认只捕获RuntimeException.class * 对Exception异常得需要 @Transactional(rollbackFor = {Exception.class}) 捕获回滚 * 或者使用全局AOP配置 TransactionAdviceConfig */ //@Transactional @Override public void saveUser(UserEntity user) { userMapper.saveUser(user); if(user.getPassword() == null || "".equals(user.getPassword()) || user.getLoginName() == null || "".equals(user.getLoginName())){ throw new RuntimeException("发生异常,用户名或密码为空"); } Long count = userMapper.countUserByLoginName(user.getLoginName()); if(count != null && count > 1){ throw new RuntimeException("发生异常,用户名已存在"); } } @Override public PageInfo<UserEntity> getPage(Integer pageNum) { //设置分页信息,分别是当前页数和每页显示的总记录数【记住:必须在mapper/dao接口中的方法执行之前设置该分页信息】 PageHelper.startPage(pageNum, Constants.PAGE_SIZE); ArrayList<UserEntity> list = userMapper.getAll(); PageInfo<UserEntity> pageInfo = new PageInfo<UserEntity>(list); //System.out.println(pageInfo.getTotal()); return pageInfo; } }
UserController.java
package com.daimeng.api.user.action; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.daimeng.api.user.entity.UserEntity; import com.daimeng.api.user.service.UserService; import com.github.pagehelper.PageInfo; @RestController @RequestMapping("/user") public class UseController { @Autowired private UserService userService; @RequestMapping("/getList") public List<UserEntity> getUsers() { ArrayList<UserEntity> users = userService.getAll(); return users; } @RequestMapping("/getPage/{pageNum}") public PageInfo<UserEntity> getUserPage(@PathVariable("pageNum") Integer pageNum) { PageInfo<UserEntity> users = userService.getPage(pageNum); return users; } @RequestMapping("/get/{loginName}") public List<UserEntity> getUserByLoginName(@PathVariable("loginName") String loginName) { UserEntity user = new UserEntity(); user.setLoginName(loginName); ArrayList<UserEntity> users = userService.getUserByLoginName(user); return users; } @RequestMapping("/save") public String saveUser(String loginName,String password) { UserEntity user = new UserEntity(); user.setLoginName(loginName); user.setPassword(password); try { userService.saveUser(user); return "新增用户成功"; } catch (Exception e) { return e.getMessage(); } } }