springboot 集成 mybatis
引入依赖
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --> <!-- 用于事务 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.1.0</version> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
编写实体类
@Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Integer id; private String name; private String address; private Date birth; }
编写mapper
package cn.taotao.demo.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import cn.taotao.demo.domain.User; @Mapper //指定扫描,或者在启动类加入扫描基类包的注解,见下面代码 public interface UserMapper { int deleteUserById(Integer id); int insertUser(User user); User selectById(Integer id); int updateUserById(Integer id); List<User> queryAllUser(); }
编写mybatis的映射xml文件 /src/main/resources/mapper/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="cn.taotao.demo.mapper.UserMapper"> <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache> <delete id="deleteUserById" parameterType="java.lang.Integer"> delete * from user where id = #{id,jdbcType=INTEGER} </delete> <select id="selectById" resultType="cn.taotao.demo.domain.User"> select * from user where id =#{id,jdbcType=INTEGER} </select> <insert id="insertUser" parameterType="java.lang.Integer"> insert into user (name,address,birth) values (#{name},#{address},#{birth}) </insert> <update id="updateUserById" parameterType="cn.taotao.demo.domain.User"> update user set name = #{name} ,address=#{address},birth =#{birth} </update> <select id= "queryAllUser" resultType="cn.taotao.demo.domain.User"> select * from user </select> </mapper>
编写测试类
@SpringBootTest class DruidApplicationTests { @Autowired private UserMapper mapper; @Test void contextLoads() { /* * List<User> queryAllUser = mapper.queryAllUser(); for (User user : * queryAllUser) { * System.out.println(user.getId()+user.getName()+user.getAddress()+user. * getBirth()); } */ Page<Object> startPage = PageHelper.startPage(1, 5); List<User> queryAllUser = mapper.queryAllUser(); System.out.println("total size:"+ startPage.getTotal() + "cur page:"+ startPage.getPageNum()); for (User user : queryAllUser) { System.out.println(user.getId()+user.getName()+user.getAddress()+user.getBirth()); } }
yml文件
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: xxxx initial-size: 1 min-idle: 2 max-active: 50 max-wait: 15000 enable: true test-on-borrow: true test-on-return: true test-while-idle: true #validation-query: select 1 # db-type: mysql #async-init: true #db-type: mysql #type: com.alibaba.druid.pool.DruidDataSource #监控配置 filters: stat #上面的filter是查看sql监控的。 stat-view-servlet: allow: 112.38.46.177 deny: url-pattern: /druid/* enabled: true login-username: system login-password: 123456 # init-variants: true # async-init: true # cache: # type: EHCACHE # ehcache: # config: classpath:ehcache.xml mybatis: mapper-locations: - classpath:mapper/*Mapper.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl server: port: 80
结论:
ehcache的引入,不需要全局springboot做缓存,只要pom把类引入即可
接口文件会自动诸如装配,只需要在接口上加入@autowire。
ehcache.xml /druid/src/main/resources/ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false"> <!-- xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" --> <!-- 磁盘保存路径 --> <diskStore path="D:\55\ehcache" /> <defaultCache maxElementsInMemory="10000" maxElementsOnDisk="10000000" eternal="false" overflowToDisk="true" timeToIdleSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <cache name="passwordRetryCache" eternal="false" maxEntriesLocalHeap="2000" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> </ehcache> <!-- 属性说明: l diskStore:指定数据在磁盘中的存储位置。 l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略 以下属性是必须的: l maxElementsInMemory - 在内存中缓存的element的最大数目 l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大 l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断 l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上 以下属性是可选的: l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大 l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大 diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区. l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。 l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作 l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出) -->
log4j.properties /druid/src/main/resources/log4j.properties
### \u8BBE\u7F6E###
log4j.rootLogger = debug,stdout,D,E
### \u8F93\u51FA\u4FE1\u606F\u5230\u63A7\u5236\u62AC ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### \u8F93\u51FADEBUG \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### \u8F93\u51FAERROR \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
-----------------------------------------------------------------------
加入事务
引入aop依赖,见前段pom
新建service类
/druid/src/main/java/cn/taotao/demo/service/UserService.java
package cn.taotao.demo.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import cn.taotao.demo.domain.User; import cn.taotao.demo.mapper.UserMapper; @Service @Transactional //标注开启事务 public class UserService implements UserMapper { @Autowired private UserMapper userMapper; @Override public int deleteUserById(Integer id) { // TODO Auto-generated method stub return userMapper.deleteUserById(id); } @Override public int insertUser(User user) { // TODO Auto-generated method stub return userMapper.insertUser(user); } @Override @Transactional(readOnly = true) //事务只读属性 public User selectById(Integer id) { // TODO Auto-generated method stub return userMapper.selectById(id); } @Override public int updateUserById(Integer id) { // TODO Auto-generated method stub return userMapper.updateUserById(id); } @Override public List<User> queryAllUser() { // TODO Auto-generated method stub return userMapper.queryAllUser(); } }
启动类加入开启事务注解
@SpringBootApplication @EnableTransactionManagement //启用事务
@MapperScan(basePackages = "cn.taotao.demo.mapper") //如果在mapper不指定@Mapper注解,可以在启动类配置mapper的默认扫描包。 public class DruidApplication { public static void main(String[] args) { SpringApplication.run(DruidApplication.class, args); } }
测试
@RestController public class UserController { @Autowired private UserService userService; @RequestMapping("/hello") public List<User> getUser() { return userService.queryAllUser(); } }
测试2
@RestController public class UserController { @Autowired private UserService userService; @RequestMapping("/hello") public List<User> getUser() { Page<Object> page = PageHelper.startPage(1, 5); List<User> queryAllUser = userService.queryAllUser(); return queryAllUser; } }
在测试的时候,
@Autowire
private UserMapper mapper //接口
需要改为
private UserService mapper //服务类
否则junit报告找不到合适的bean,因为注入2次。