├── README.MD ├── create_table.sql ├── pom.xml └── src ├── main ├── java │ └── com │ │ ├── Application.java │ │ └── github │ │ ├── mybatis │ │ ├── dao │ │ │ ├── DynamicSqlDao.java │ │ │ ├── OneManySqlDao.java │ │ │ └── SimpleSqlDao.java │ │ ├── domain │ │ │ ├── Identity.java │ │ │ ├── Login.java │ │ │ ├── User.java │ │ │ └── User2.java │ │ ├── providerDao │ │ │ ├── SimpleProviderDao.java │ │ │ └── sqlBuilder │ │ │ │ ├── UserBuilder.java │ │ │ │ └── UserBuilder2.java │ │ └── service │ │ │ └── TransactionalService.java │ │ └── redis │ │ ├── RedisCacheUserDao.java │ │ ├── RedisCacheUserService.java │ │ ├── RedisConfig.java │ │ └── UserDao.java └── resources │ └── application.properties └── test └── java └── com ├── ApplicationTestRoot.java └── github ├── mybatis ├── DynamicSqlDao.java ├── OneManySqlDao.java ├── SimpleProviderDao.java ├── SimpleSqlDao.java └── Transactional.java └── redis ├── RedisDaoCache.java ├── RedisServiceCache.java ├── RedisSysBean.java └── RedisUserBean.java /README.MD: -------------------------------------------------------------------------------- 1 | # SpringBoot + MyBatis + Redis的demo 2 | [MyBatis博客](https://www.cnblogs.com/caizhaokai/p/10982727.html) 3 | [Redis博客](https://www.cnblogs.com/caizhaokai/p/11037610.html) 4 | -------------------------------------------------------------------------------- /create_table.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `sys_identity`; 2 | DROP TABLE IF EXISTS `sys_login`; 3 | DROP TABLE IF EXISTS `sys_user`; 4 | 5 | CREATE TABLE `sys_identity` ( 6 | `t_id` varchar(32) NOT NULL COMMENT 'ID编号', 7 | `t_id_type` varchar(2) NOT NULL COMMENT '证件类型', 8 | `t_id_no` varchar(64) NOT NULL COMMENT '证件号码', 9 | PRIMARY KEY (`t_id`,`t_id_type`,`t_id_no`) 10 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 11 | 12 | CREATE TABLE `sys_login` ( 13 | `t_id` varchar(32) NOT NULL COMMENT 'ID编号', 14 | `t_username` varchar(400) DEFAULT NULL COMMENT '登录名', 15 | `t_password` varchar(400) DEFAULT NULL COMMENT '登录密码', 16 | PRIMARY KEY (`t_id`) 17 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 18 | 19 | CREATE TABLE `sys_user` ( 20 | `t_id` varchar(32) NOT NULL COMMENT 'ID编号', 21 | `t_name` varchar(300) DEFAULT NULL COMMENT '用户姓名', 22 | `t_age` int(11) DEFAULT NULL COMMENT '用户年龄', 23 | PRIMARY KEY (`t_id`) 24 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 25 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | com 12 | spring-boot-demo 13 | 1.0.0 14 | jar 15 | spring-boot-demo 16 | Demo project for Spring Boot 17 | 18 | 19 | 1.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-redis 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | org.mybatis.spring.boot 33 | mybatis-spring-boot-starter 34 | 2.0.1 35 | 36 | 37 | 38 | mysql 39 | mysql-connector-java 40 | runtime 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-test 45 | test 46 | 47 | 48 | com.google.code.gson 49 | gson 50 | 2.8.5 51 | test 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-maven-plugin 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/main/java/com/Application.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/dao/DynamicSqlDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.dao; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * MyBatis 动态sql 11 | */ 12 | @Mapper 13 | public interface DynamicSqlDao { 14 | /** 15 | * if 对内容进行判断 16 | * 在注解方法中,若要使用MyBatis的动态SQL,需要编写在标签内 17 | * 在 内使用特殊符号,则使用java的转义字符,如 双引号 "" 使用"" 代替 18 | * concat函数:mysql拼接字符串的函数 19 | */ 20 | @Select(" ") 32 | @Results(id = "userResults", value = { 33 | @Result(property = "id", column = "t_id"), 34 | @Result(property = "name", column = "t_name"), 35 | @Result(property = "age", column = "t_age"), 36 | }) 37 | List selectUserWithIf(User user); 38 | 39 | /** 40 | * choose when otherwise 类似Java的Switch,选择某一项 41 | * when...when...otherwise... == if... if...else... 42 | */ 43 | @Select(" ") 57 | @ResultMap("userResults") 58 | List selectUserWithChoose(User user); 59 | 60 | /** 61 | * set 动态更新语句,类似 62 | */ 63 | @Update(" ") 71 | int updateUserWithSet(User user); 72 | 73 | /** 74 | * foreach 遍历一个集合,常用于批量更新和条件语句中的 IN 75 | * foreach 批量更新 76 | */ 77 | @Insert(" ") 86 | int insertUserListWithForeach(List list); 87 | 88 | /** 89 | * foreach 条件语句中的 IN 90 | */ 91 | @Select(" ") 100 | @ResultMap("userResults") 101 | List selectUserByINName(List list); 102 | 103 | /** 104 | * bind 创建一个变量,绑定到上下文中 105 | */ 106 | @Select(" ") 112 | @ResultMap("userResults") 113 | List selectUserWithBind(@Param("name") String name); 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/dao/OneManySqlDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.dao; 2 | 3 | import com.github.mybatis.domain.Identity; 4 | import com.github.mybatis.domain.Login; 5 | import com.github.mybatis.domain.User2; 6 | import org.apache.ibatis.annotations.*; 7 | import org.apache.ibatis.mapping.FetchType; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Mybatis 对一,对多查询 13 | */ 14 | @Mapper 15 | public interface OneManySqlDao { 16 | /** 17 | * 对@Result的解释 18 | * property:java bean 的成员变量 19 | * column:对应查询的字段,也是传递到对应子查询的参数,传递多参数使用Map column = "{param1=SQL_COLUMN1,param2=SQL_COLUMN2}" 20 | * one=@One:对一查询 21 | * many=@Many:对多查询 22 | * 属性select:需要查询的方法,全称 23 | */ 24 | @Select("select t_id, t_name, t_age " 25 | + "from sys_user " 26 | + "where t_id = #{id} ") 27 | @Results({ 28 | @Result(property = "id", column = "t_id"), 29 | @Result(property = "name", column = "t_name"), 30 | @Result(property = "age", column = "t_age"), 31 | @Result(property = "login", column = "t_id", 32 | one = @One(select = "selectLoginById", fetchType = FetchType.EAGER)), 33 | @Result(property = "identityList", column = "t_id", 34 | many = @Many(select = "selectIdentityById", fetchType = FetchType.EAGER)), 35 | }) 36 | User2 selectUser(@Param("id") String id); 37 | 38 | /** 39 | * 对一 子查询 40 | */ 41 | @Select("select t_username, t_password " 42 | + "from sys_login " 43 | + "where t_id = #{id} ") 44 | @Results(id = "loginResults", value = { 45 | @Result(property = "username", column = "t_username"), 46 | @Result(property = "password", column = "t_password"), 47 | }) 48 | Login selectLoginById(@Param("id") String id); 49 | 50 | /** 51 | * 对多 子查询 52 | */ 53 | @Select("select t_id_type, t_id_no " 54 | + "from sys_identity " 55 | + "where t_id = #{id} ") 56 | @Results(id = "identityResults", value = { 57 | @Result(property = "idType", column = "t_id_type"), 58 | @Result(property = "idNo", column = "t_id_no"), 59 | }) 60 | List selectIdentityById(@Param("id") String id); 61 | 62 | @Delete("delete from sys_login where t_id = #{id} ") 63 | int deleteLogin(@Param("id") String id); 64 | 65 | @Delete("delete from sys_identity where t_id = #{id} ") 66 | int deleteIdentity(@Param("id") String id); 67 | 68 | @Insert("insert into sys_login " 69 | + "(t_id, t_username, t_password ) " 70 | + "values " 71 | + "(#{id}, #{username}, #{password}) ") 72 | int insertLogin(@Param("id") String id, 73 | @Param("username") String username, 74 | @Param("password") String password); 75 | 76 | @Insert("insert into sys_identity " 77 | + "(t_id, t_id_type, t_id_no ) " 78 | + "values " 79 | + "(#{id}, #{idType}, #{idNo}) ") 80 | int insertIdentity(@Param("id") String id, 81 | @Param("idType") String idType, 82 | @Param("idNo") String idNo); 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/dao/SimpleSqlDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.dao; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * 最基本的增删改查 11 | */ 12 | @Mapper 13 | public interface SimpleSqlDao { 14 | /** 15 | * 测试连接 16 | */ 17 | @Select("select 1 from dual") 18 | int testSqlConnent(); 19 | 20 | /** 21 | * 新增,参数是一个bean 22 | */ 23 | @Insert("insert into sys_user " 24 | + "(t_id, t_name, t_age) " 25 | + "values " 26 | + "(#{id}, #{name}, ${age}) ") 27 | int insertUser(User bean); 28 | 29 | /** 30 | * 新增,参数是一个Map 31 | */ 32 | @Insert("insert into sys_user " 33 | + "(t_id, t_name, t_age) " 34 | + "values " 35 | + "(#{id}, #{name}, ${age}) ") 36 | int insertUserByMap(Map map); 37 | 38 | /** 39 | * 新增,参数是多个值,需要使用@Param来修饰 40 | * MyBatis 的参数使用的@Param的字符串,一般@Param的字符串与参数相同 41 | */ 42 | @Insert("insert into sys_user " 43 | + "(t_id, t_name, t_age) " 44 | + "values " 45 | + "(#{id}, #{name}, ${age}) ") 46 | int insertUserByParam(@Param("id") String id, 47 | @Param("name") String name, 48 | @Param("age") int age); 49 | 50 | /** 51 | * 修改 52 | */ 53 | @Update("update sys_user set " 54 | + "t_name = #{name}, " 55 | + "t_age = #{age} " 56 | + "where t_id = #{id} ") 57 | int updateUser(User bean); 58 | 59 | /** 60 | * 删除 61 | */ 62 | @Delete("delete from sys_user " 63 | + "where t_id = #{id} ") 64 | int deleteUserById(@Param("id") String id); 65 | 66 | /** 67 | * 删除 68 | */ 69 | @Delete("delete from sys_user ") 70 | int deleteUserAll(); 71 | 72 | /** 73 | * truncate 返回值为0 74 | */ 75 | @Delete("truncate table sys_user ") 76 | void truncateUser(); 77 | 78 | /** 79 | * 查询bean 80 | * 映射关系@Results 81 | * 82 | * @Result(property="java Bean name", column="DB column name"), 83 | */ 84 | @Select("select t_id, t_age, t_name " 85 | + "from sys_user " 86 | + "where t_id = #{id} ") 87 | @Results(id = "userResults", value = { 88 | @Result(property = "id", column = "t_id"), 89 | @Result(property = "age", column = "t_age"), 90 | @Result(property = "name", column = "t_name"), 91 | }) 92 | User selectUserById(@Param("id") String id); 93 | 94 | /** 95 | * 查询List 96 | */ 97 | @ResultMap("userResults") 98 | @Select("select t_id, t_name, t_age " 99 | + "from sys_user ") 100 | List selectUser(); 101 | 102 | @Select("select count(*) from sys_user ") 103 | int selectCountUser(); 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/domain/Identity.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.domain; 2 | 3 | public class Identity { 4 | @Override 5 | public String toString() { 6 | return "Identity [idType=" + idType + ", idNo=" + idNo + "]"; 7 | } 8 | 9 | private String idType; 10 | private String idNo; 11 | 12 | public String getIdType() { 13 | return idType; 14 | } 15 | 16 | public void setIdType(String idType) { 17 | this.idType = idType; 18 | } 19 | 20 | public String getIdNo() { 21 | return idNo; 22 | } 23 | 24 | public void setIdNo(String idNo) { 25 | this.idNo = idNo; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/domain/Login.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.domain; 2 | 3 | public class Login { 4 | @Override 5 | public String toString() { 6 | return "Login [username=" + username + ", password=" + password + "]"; 7 | } 8 | 9 | private String username; 10 | private String password; 11 | 12 | public String getUsername() { 13 | return username; 14 | } 15 | 16 | public void setUsername(String username) { 17 | this.username = username; 18 | } 19 | 20 | public String getPassword() { 21 | return password; 22 | } 23 | 24 | public void setPassword(String password) { 25 | this.password = password; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.domain; 2 | 3 | /** 4 | * 简单的bean,对应DB的表 5 | */ 6 | public class User { 7 | public User() {} 8 | 9 | public User(String id, String name, int age) { 10 | this.id = id; 11 | this.name = name; 12 | this.age = age; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "User [id=" + id + ", name=" + name + ", age=" + age + "]"; 18 | } 19 | 20 | private String id; 21 | private String name; 22 | private int age; 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | 28 | public void setId(String id) { 29 | this.id = id; 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public int getAge() { 41 | return age; 42 | } 43 | 44 | public void setAge(int age) { 45 | this.age = age; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/domain/User2.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.domain; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 简单的bean,对应DB的表 7 | */ 8 | public class User2 { 9 | @Override 10 | public String toString() { 11 | return "User2 [id=" + id + ", name=" + name + ", age=" + age + "]"; 12 | } 13 | 14 | private String id; 15 | private String name; 16 | private int age; 17 | private Login login; 18 | private List identityList; 19 | 20 | public String getId() { 21 | return id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | } 35 | 36 | public int getAge() { 37 | return age; 38 | } 39 | 40 | public void setAge(int age) { 41 | this.age = age; 42 | } 43 | 44 | public Login getLogin() { 45 | return login; 46 | } 47 | 48 | public void setLogin(Login login) { 49 | this.login = login; 50 | } 51 | 52 | public List getIdentityList() { 53 | return identityList; 54 | } 55 | 56 | public void setIdentityList(List identityList) { 57 | this.identityList = identityList; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/providerDao/SimpleProviderDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.providerDao; 2 | 3 | import com.github.mybatis.domain.User; 4 | import com.github.mybatis.providerDao.sqlBuilder.UserBuilder; 5 | import org.apache.ibatis.annotations.*; 6 | 7 | import java.util.List; 8 | 9 | @Mapper 10 | public interface SimpleProviderDao { 11 | /** 12 | * @see UserBuilder#selectUserById() 13 | */ 14 | @Results(id = "userResults", value = { 15 | @Result(property = "id", column = "t_id"), 16 | @Result(property = "name", column = "t_name"), 17 | @Result(property = "age", column = "t_age"), 18 | }) 19 | @SelectProvider(type = UserBuilder.class) 20 | User selectUserById(String id); 21 | 22 | /** 23 | * @see UserBuilder#selectUser(String) 24 | */ 25 | @ResultMap("userResults") 26 | @SelectProvider(type = UserBuilder.class) 27 | List selectUser(String name); 28 | 29 | /** 30 | * @see UserBuilder#insertUser() 31 | */ 32 | @InsertProvider(type = UserBuilder.class) 33 | int insertUser(User user); 34 | 35 | /** 36 | * @see UserBuilder#insertUserList(List) 37 | */ 38 | @InsertProvider(type = UserBuilder.class) 39 | int insertUserList(List list); 40 | 41 | /** 42 | * @see UserBuilder#updateUser() 43 | */ 44 | @UpdateProvider(type = UserBuilder.class) 45 | int updateUser(User user); 46 | 47 | /** 48 | * @see UserBuilder#deleteUser() 49 | */ 50 | @DeleteProvider(type = UserBuilder.class) 51 | int deleteUser(String id); 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/providerDao/sqlBuilder/UserBuilder.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.providerDao.sqlBuilder; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.apache.ibatis.builder.annotation.ProviderMethodResolver; 5 | import org.apache.ibatis.jdbc.SQL; 6 | 7 | import java.util.List; 8 | 9 | 10 | /* 11 | * ProviderMethodResolver接口属于比较新的api,如果找不到这个接口,更新你的mybatis的版本 12 | * 继承ProviderMethodResolver接口,Mapper中可以直接指定该类即可, 13 | * 但对应的Mapper的方法名要更Builder的方法名相同 14 | * 15 | * Mapper: 16 | * @SelectProvider(type = UserBuilder.class) 17 | * public User selectUserById(String id); 18 | * 19 | * UserBuilder: 20 | * public static String selectUserById(final String id)... 21 | */ 22 | public class UserBuilder implements ProviderMethodResolver { 23 | 24 | private final static String TABLE_NAME = "sys_user"; 25 | 26 | public static String selectUserById() { 27 | return new SQL() 28 | .SELECT("t_id, t_name, t_age") 29 | .FROM(TABLE_NAME) 30 | .WHERE("t_id = #{id}") 31 | .toString(); 32 | } 33 | 34 | public static String selectUser(String name) { 35 | SQL sql = new SQL() 36 | .SELECT("t_id, t_name, t_age") 37 | .FROM(TABLE_NAME); 38 | if (name != null && name != "") { 39 | sql.WHERE("t_name like CONCAT('%', #{name}, '%')"); 40 | } 41 | return sql.toString(); 42 | } 43 | 44 | public static String insertUser() { 45 | return new SQL() 46 | .INSERT_INTO(TABLE_NAME) 47 | .INTO_COLUMNS("t_id, t_name, t_age") 48 | .INTO_VALUES("#{id}, #{name}, #{age}") 49 | .toString(); 50 | } 51 | 52 | /** 53 | * 使用SQL Builder进行批量插入 54 | * 关键是sql语句中的values格式书写和访问参数 55 | * values格式:values (?, ?, ?) , (?, ?, ?) , (?, ?, ?) ... 56 | * 访问参数:MyBatis只能读取到list参数,所有使用list[i].Filed访问变量,如 #{list[0].id} 57 | */ 58 | public static String insertUserList(List list) { 59 | SQL sql = new SQL() 60 | .INSERT_INTO(TABLE_NAME) 61 | .INTO_COLUMNS("t_id, t_name, t_age"); 62 | StringBuilder sb = new StringBuilder(); 63 | for (int i = 0; i < list.size(); i++) { 64 | if (i > 0) { 65 | sb.append(") , ("); 66 | } 67 | sb.append("#{list["); 68 | sb.append(i); 69 | sb.append("].id}, "); 70 | sb.append("#{list["); 71 | sb.append(i); 72 | sb.append("].name}, "); 73 | sb.append("#{list["); 74 | sb.append(i); 75 | sb.append("].age}"); 76 | } 77 | sql.INTO_VALUES(sb.toString()); 78 | return sql.toString(); 79 | } 80 | 81 | public static String updateUser() { 82 | return new SQL() 83 | .UPDATE(TABLE_NAME) 84 | .SET("t_name = #{name}", "t_age = #{age}") 85 | .WHERE("t_id = #{id}") 86 | .toString(); 87 | } 88 | 89 | public static String deleteUser() { 90 | return new SQL() 91 | .DELETE_FROM(TABLE_NAME) 92 | .WHERE("t_id = #{id}") 93 | .toString(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/providerDao/sqlBuilder/UserBuilder2.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.providerDao.sqlBuilder; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.apache.ibatis.builder.annotation.ProviderMethodResolver; 5 | import org.apache.ibatis.jdbc.SQL; 6 | 7 | 8 | public class UserBuilder2 implements ProviderMethodResolver { 9 | 10 | private final static String TABLE_NAME = "sys_user"; 11 | 12 | public static String selectUserById() { 13 | return new SQL() {{ 14 | SELECT("t_id, t_name, t_age"); 15 | FROM(TABLE_NAME); 16 | WHERE("t_id = #{id}"); 17 | }}.toString(); 18 | } 19 | 20 | public static String selectUser(String name) { 21 | return new SQL() {{ 22 | SELECT("t_id, t_name, t_age"); 23 | FROM(TABLE_NAME); 24 | if (name != null && name != "") { 25 | WHERE("t_name like CONCAT('%', #{name}, '%')"); 26 | } 27 | }}.toString(); 28 | } 29 | 30 | public static String insertUser() { 31 | return new SQL() {{ 32 | INSERT_INTO(TABLE_NAME); 33 | INTO_COLUMNS("t_id, t_name, t_age"); 34 | INTO_VALUES("#{id}, #{name}, #{age}"); 35 | }}.toString(); 36 | } 37 | 38 | public static String updateUser(User user) { 39 | return new SQL() {{ 40 | UPDATE(TABLE_NAME); 41 | SET("t_name = #{name}", "t_age = #{age}"); 42 | WHERE("t_id = #{id}"); 43 | }}.toString(); 44 | } 45 | 46 | public static String deleteUser(final String id) { 47 | return new SQL() {{ 48 | DELETE_FROM(TABLE_NAME); 49 | WHERE("t_id = #{id}"); 50 | }}.toString(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/github/mybatis/service/TransactionalService.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis.service; 2 | 3 | import com.github.mybatis.dao.SimpleSqlDao; 4 | import com.github.mybatis.domain.User; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.TransactionDefinition; 9 | import org.springframework.transaction.TransactionStatus; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | /** 13 | * SpringBoot + MyBatis事务管理 14 | */ 15 | @Service 16 | public class TransactionalService { 17 | 18 | @Autowired 19 | private SimpleSqlDao dao; 20 | 21 | // 手动控制事务 22 | @Autowired 23 | private DataSourceTransactionManager dataSourceTransactionManager; 24 | 25 | @Autowired 26 | private TransactionDefinition transactionDefinition; 27 | 28 | /** 29 | * 测试DB执行sql语句时出现异常的事务控制 30 | * 31 | * @Transactional 的事务都是自动提交的(commit),遇到异常时回滚(rollback) 32 | */ 33 | @Transactional 34 | public void testTransactional(boolean exceptionFlag) { 35 | dao.deleteUserById("10010"); 36 | User user = new User("10010", "first_data", 11); 37 | dao.insertUser(user); 38 | // 重复的主键,DB会报主键冲突的异常 39 | if (exceptionFlag) { 40 | user.setName("doublePrimaryKey"); 41 | dao.insertUser(user); 42 | } 43 | } 44 | 45 | /** 46 | * @Transactional 的参数 47 | * value |String | 可选的限定描述符,指定使用的事务管理器 48 | * propagation |Enum: Propagation | 可选的事务传播行为设置 49 | * isolation |Enum: Isolation | 可选的事务隔离级别设置 50 | * readOnly |boolean | 读写或只读事务,默认读写 51 | * timeout |int (seconds) | 事务超时时间设置 52 | * rollbackFor |Class[] | 导致事务回滚的异常类数组 53 | * rollbackForClassName |String[] | 导致事务回滚的异常类名字数组 54 | * noRollbackFor |Class[] | 不会导致事务回滚的异常类数组 55 | * noRollbackForClassName |String[] | 不会导致事务回滚的异常类名字数组 56 | */ 57 | @Transactional(timeout = 4) 58 | public void testTSTimeout() { 59 | System.out.println(dao.selectUserById("10010")); 60 | User user = new User("10010", "timeout_name", 12); 61 | dao.updateUser(user); 62 | try { 63 | Thread.sleep(10 * 1000); 64 | } catch (InterruptedException e) { 65 | e.printStackTrace(); 66 | } 67 | System.out.println(dao.selectUserById("10010")); 68 | } 69 | 70 | /** 71 | * 测试手动提交事务 72 | */ 73 | public void testHandleCommitTS(boolean exceptionFlag) { 74 | // DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); 75 | // transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 76 | // 开启事务 77 | TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); 78 | try { 79 | dao.deleteUserById("10010"); 80 | User user = new User("10010", "first_data", 11); 81 | dao.insertUser(user); 82 | // 重复的主键,DB会报主键冲突的异常 83 | if (exceptionFlag) { 84 | user.setName("doublePrimaryKey"); 85 | dao.insertUser(user); 86 | } 87 | // 提交事务 88 | dataSourceTransactionManager.commit(transactionStatus); 89 | } catch (Exception e) { 90 | // 回滚事务 91 | dataSourceTransactionManager.rollback(transactionStatus); 92 | throw e; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/github/redis/RedisCacheUserDao.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.apache.ibatis.annotations.*; 5 | import org.springframework.cache.annotation.CacheConfig; 6 | import org.springframework.cache.annotation.CacheEvict; 7 | import org.springframework.cache.annotation.CachePut; 8 | import org.springframework.cache.annotation.Cacheable; 9 | 10 | import java.util.List; 11 | 12 | @Mapper 13 | @CacheConfig(cacheNames = "users") 14 | public interface RedisCacheUserDao { 15 | @Cacheable(key ="#id") 16 | @Select("select t_id, t_age, t_name " 17 | + "from sys_user " 18 | + "where t_id = #{id} ") 19 | @Results(id = "redisUserDaoResults", value = { 20 | @Result(property = "id", column = "t_id"), 21 | @Result(property = "age", column = "t_age"), 22 | @Result(property = "name", column = "t_name"), 23 | }) 24 | User selectUserById(@Param("id") String id); 25 | 26 | @Cacheable(key ="'list'") 27 | @ResultMap("redisUserDaoResults") 28 | @Select("select t_id, t_name, t_age " 29 | + "from sys_user ") 30 | List selectUser(); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/redis/RedisCacheUserService.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.cache.annotation.CacheConfig; 6 | import org.springframework.cache.annotation.CacheEvict; 7 | import org.springframework.cache.annotation.CachePut; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | /** 13 | * 指定默认缓存区 14 | * 缓存区:key的前缀,与指定的key构成redis的key,如 user::10001 15 | */ 16 | @CacheConfig(cacheNames = "user") 17 | @Service 18 | public class RedisCacheUserService { 19 | 20 | @Autowired 21 | private UserDao dao; 22 | 23 | /** 24 | * @Cacheable 缓存有数据时,从缓存获取;没有数据时,将返回值保存到缓存中 25 | * @Cacheable 一般在查询中使用 26 | * 1) cacheNames 指定缓存区,没有配置使用@CacheConfig指定的缓存区 27 | * 2) key 指定缓存区的key 28 | * 3) 注解的值使用SpEL表达式 29 | * eq == 30 | * lt < 31 | * le <= 32 | * gt > 33 | * ge >= 34 | */ 35 | @Cacheable(cacheNames = "user", key = "#id") 36 | public User selectUserById(String id) { 37 | return dao.selectUserById(id); 38 | } 39 | 40 | @Cacheable(key="'list'") 41 | public List selectUser() { 42 | return dao.selectUser(); 43 | } 44 | 45 | /** 46 | * condition 满足条件缓存数据 47 | */ 48 | @Cacheable(key = "#id", condition = "#number ge 20") // >= 20 49 | public User selectUserByIdWithCondition(String id, int number) { 50 | return dao.selectUserById(id); 51 | } 52 | 53 | /** 54 | * unless 满足条件时否决缓存数据 55 | */ 56 | @Cacheable(key = "#id", unless = "#number lt 20") // < 20 57 | public User selectUserByIdWithUnless(String id, int number) { 58 | return dao.selectUserById(id); 59 | } 60 | 61 | /** 62 | * @CachePut 将返回值保存到缓存中 63 | * @CachePut 一般在新增和修改中使用 64 | */ 65 | @CachePut(key = "#user.id") 66 | public User insertUser(User user) { 67 | dao.insertUser(user); 68 | return user; 69 | } 70 | 71 | @CachePut(key = "#user.id", condition = "#user.age ge 20") 72 | public User insertUserWithCondition(User user) { 73 | dao.insertUser(user); 74 | return user; 75 | } 76 | 77 | @CachePut(key = "#user.id") 78 | public User updateUser(User user) { 79 | dao.updateUser(user); 80 | return user; 81 | } 82 | 83 | /** 84 | * 根据key删除缓存区中的数据 85 | */ 86 | @CacheEvict(key = "#id") 87 | public void deleteUserById(String id) { 88 | dao.deleteUserById(id); 89 | } 90 | 91 | /** 92 | * allEntries = true :删除整个缓存区的所有值,此时指定的key无效 93 | * beforeInvocation = true :默认false,表示调用方法之后删除缓存数据;true时,在调用之前删除缓存数据(如方法出现异常) 94 | */ 95 | @CacheEvict(key = "#id", allEntries = true) 96 | public void deleteUserByIdAndCleanCache(String id) { 97 | dao.deleteUserById(id); 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /src/main/java/com/github/redis/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.cache.CacheManager; 7 | import org.springframework.cache.annotation.EnableCaching; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.data.redis.cache.RedisCacheConfiguration; 11 | import org.springframework.data.redis.cache.RedisCacheManager; 12 | import org.springframework.data.redis.cache.RedisCacheManager.RedisCacheManagerBuilder; 13 | import org.springframework.data.redis.connection.RedisConnectionFactory; 14 | import org.springframework.data.redis.core.*; 15 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 16 | import org.springframework.data.redis.serializer.RedisSerializationContext; 17 | import org.springframework.data.redis.serializer.StringRedisSerializer; 18 | 19 | import java.time.Duration; 20 | 21 | /** 22 | *

StringBoot 封装了 RedisTemplate 对象来操作 Redis, 并在RedisAutoConfiguration下配置的两个RedisTemplate

23 | *

RedisTemplate: key(Object) --> value(Object)

24 | *

StringRedisTemplate: key(String) --> value(Object)

25 | *

RedisTemplate, key, value需要实现Serializable接口,redis数据格式比较难懂

26 | *

StringRedisTemplate: 即RedisTemplate, 若value存储对象时,需要转为string,一般转为JSON格式的字符串

27 | *

可以配置一个 RedisTemplate 的bean,key设置为String格式,value设置自动转为JSON格式

28 | * 29 | * @see org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration 30 | */ 31 | @Configuration 32 | @EnableCaching 33 | public class RedisConfig { 34 | /** 35 | *

SpringBoot配置redis作为默认缓存工具

36 | *

SpringBoot 2.0 以上版本的配置

37 | */ 38 | @Bean 39 | public CacheManager cacheManager(RedisTemplate template) { 40 | RedisCacheConfiguration defaultCacheConfiguration = 41 | RedisCacheConfiguration 42 | .defaultCacheConfig() 43 | // 设置key为String 44 | .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer())) 45 | // 设置value 为自动转Json的Object 46 | .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer())) 47 | // 不缓存null 48 | .disableCachingNullValues() 49 | // 缓存数据保存1小时 50 | .entryTtl(Duration.ofHours(1)); 51 | RedisCacheManager redisCacheManager = 52 | RedisCacheManagerBuilder 53 | // Redis 连接工厂 54 | .fromConnectionFactory(template.getConnectionFactory()) 55 | // 缓存配置 56 | .cacheDefaults(defaultCacheConfiguration) 57 | // 配置同步修改或删除 put/evict 58 | .transactionAware() 59 | .build(); 60 | return redisCacheManager; 61 | } 62 | 63 | /** 64 | * retemplate 65 | */ 66 | @Bean(name = "template") 67 | public RedisTemplate template(RedisConnectionFactory factory) { 68 | // 创建RedisTemplate对象 69 | RedisTemplate template = new RedisTemplate<>(); 70 | // 配置连接工厂 71 | template.setConnectionFactory(factory); 72 | // 定义Jackson2JsonRedisSerializer序列化对象 73 | Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class); 74 | ObjectMapper om = new ObjectMapper(); 75 | // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public 76 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 77 | // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常 78 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 79 | jacksonSeial.setObjectMapper(om); 80 | StringRedisSerializer stringSerial = new StringRedisSerializer(); 81 | // redis key 序列化方式使用stringSerial 82 | template.setKeySerializer(stringSerial); 83 | // redis value 序列化方式使用jackson 84 | template.setValueSerializer(jacksonSeial); 85 | // redis hash key 序列化方式使用stringSerial 86 | template.setHashKeySerializer(stringSerial); 87 | // redis hash value 序列化方式使用jackson 88 | template.setHashValueSerializer(jacksonSeial); 89 | template.afterPropertiesSet(); 90 | return template; 91 | } 92 | 93 | /** 94 | * redis string 95 | */ 96 | @Bean 97 | public ValueOperations valueOperations(RedisTemplate redisTemplate) { 98 | return redisTemplate.opsForValue(); 99 | } 100 | 101 | /** 102 | * redis hash 103 | */ 104 | @Bean 105 | public HashOperations hashOperations(RedisTemplate redisTemplate) { 106 | return redisTemplate.opsForHash(); 107 | } 108 | 109 | /** 110 | * redis list 111 | */ 112 | @Bean 113 | public ListOperations listOperations(RedisTemplate redisTemplate) { 114 | return redisTemplate.opsForList(); 115 | } 116 | 117 | /** 118 | * redis set 119 | */ 120 | @Bean 121 | public SetOperations setOperations(RedisTemplate redisTemplate) { 122 | return redisTemplate.opsForSet(); 123 | } 124 | 125 | /** 126 | * redis zset 127 | */ 128 | @Bean 129 | public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { 130 | return redisTemplate.opsForZSet(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/com/github/redis/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.github.mybatis.domain.User; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | @Mapper 9 | public interface UserDao { 10 | @Insert("insert into sys_user " 11 | + "(t_id, t_name, t_age) " 12 | + "values " 13 | + "(#{id}, #{name}, ${age}) ") 14 | int insertUser(User bean); 15 | 16 | @ResultMap("redisUserDaoResults") 17 | @Select("select t_id, t_name, t_age " 18 | + "from sys_user ") 19 | List selectUser(); 20 | 21 | @Select("select t_id, t_age, t_name " 22 | + "from sys_user " 23 | + "where t_id = #{id} ") 24 | @Results(id = "redisUserDaoResults", value = { 25 | @Result(property = "id", column = "t_id"), 26 | @Result(property = "age", column = "t_age"), 27 | @Result(property = "name", column = "t_name"), 28 | }) 29 | User selectUserById(@Param("id") String id); 30 | 31 | @Update("update sys_user set " 32 | + "t_name = #{name}, " 33 | + "t_age = #{age} " 34 | + "where t_id = #{id} ") 35 | int updateUser(User user); 36 | 37 | @Delete("delete from sys_user " 38 | + "where t_id = #{id} ") 39 | int deleteUserById(@Param("id") String id); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caizhaokai/spring-boot-demo/2cc01c9ed41c56f64ede55a9307604919d1ab006/src/main/resources/application.properties -------------------------------------------------------------------------------- /src/test/java/com/ApplicationTestRoot.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | /** 10 | * 新的测试类继承该类 11 | * 12 | * @author 蔡昭凯 13 | */ 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | // @WebAppConfiguration// web测试 17 | public class ApplicationTestRoot { 18 | @Before 19 | public void init() { 20 | System.out.println(this.getClass().getName() + " start test."); 21 | } 22 | 23 | @After 24 | public void after() { 25 | System.out.println(this.getClass().getName() + " finished test."); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/github/mybatis/DynamicSqlDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.dao.SimpleSqlDao; 5 | import com.github.mybatis.domain.User; 6 | import org.junit.FixMethodOrder; 7 | import org.junit.Test; 8 | import org.junit.runners.MethodSorters; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * 测试动态sql 16 | */ 17 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 18 | public class DynamicSqlDao extends ApplicationTestRoot { 19 | 20 | @Autowired 21 | private com.github.mybatis.dao.DynamicSqlDao dao; 22 | 23 | @Autowired 24 | private SimpleSqlDao sdao; 25 | 26 | /** 27 | * 测试使用 foreach 遍历 list ,进行批量新增 28 | */ 29 | @Test 30 | public void test001() { 31 | List list = new ArrayList<>(); 32 | for (int i = 1; i <= 20; i++) { 33 | User user = new User(); 34 | user.setId("ID" + String.format("%04d", i)); 35 | user.setName("name_" + i); 36 | user.setAge(i % 100); 37 | list.add(user); 38 | } 39 | System.out.println(dao.insertUserListWithForeach(list)); 40 | System.out.println(sdao.selectCountUser()); 41 | } 42 | 43 | /** 44 | * 测试使用 foreach 遍历 list ,in (list) 45 | */ 46 | @Test 47 | public void test002() { 48 | List nameList = new ArrayList<>(); 49 | nameList.add("name_1"); 50 | nameList.add("name_2"); 51 | nameList.add("name_3"); 52 | List userList = dao.selectUserByINName(nameList); 53 | System.out.println("list size is : " + userList.size()); 54 | for (User bean : userList) { 55 | System.out.println(bean); 56 | } 57 | } 58 | 59 | /** 60 | * 测试 if 61 | */ 62 | @Test 63 | public void test003() { 64 | User user = new User("ID0002", "name_2", 11); 65 | List list = dao.selectUserWithIf(user); 66 | for (User bean : list) { 67 | System.out.println(bean); 68 | } 69 | System.out.println("========================="); 70 | user = new User("", "name_2", 11); 71 | list = dao.selectUserWithIf(user); 72 | for (User bean : list) { 73 | System.out.println(bean); 74 | } 75 | } 76 | 77 | /** 78 | * 测试 choose 79 | */ 80 | @Test 81 | public void test004() { 82 | User user = new User("ID0002", "name_2", 11); 83 | List list = dao.selectUserWithChoose(user); 84 | for (User bean : list) { 85 | System.out.println(bean); 86 | } 87 | System.out.println("========================="); 88 | user = new User("", "name_2", 11); 89 | list = dao.selectUserWithChoose(user); 90 | for (User bean : list) { 91 | System.out.println(bean); 92 | } 93 | } 94 | 95 | /** 96 | * 测试 set 97 | */ 98 | @Test 99 | public void test005() { 100 | User user = new User("ID0002", null, 22); 101 | System.out.println(sdao.selectUserById("ID0002")); 102 | System.out.println(dao.updateUserWithSet(user)); 103 | System.out.println(sdao.selectUserById("ID0002")); 104 | } 105 | 106 | /** 107 | * 测试 bind 108 | */ 109 | @Test 110 | public void test006() { 111 | List list = dao.selectUserWithBind("name_2"); 112 | for (User bean : list) { 113 | System.out.println(bean); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/test/java/com/github/mybatis/OneManySqlDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.domain.User2; 5 | import org.junit.FixMethodOrder; 6 | import org.junit.Test; 7 | import org.junit.runners.MethodSorters; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | 10 | /** 11 | * 测试一对一,一对多查询 12 | */ 13 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 14 | public class OneManySqlDao extends ApplicationTestRoot { 15 | @Autowired 16 | private com.github.mybatis.dao.OneManySqlDao dao; 17 | 18 | /** 19 | * 插入测试数据 20 | */ 21 | @Test 22 | public void test001() { 23 | dao.deleteLogin("ID0001"); 24 | dao.deleteIdentity("ID0001"); 25 | dao.insertLogin("ID0001", "myName", "myPassword"); 26 | dao.insertIdentity("ID0001", "01", "12345678"); 27 | dao.insertIdentity("ID0001", "02", "1234567890"); 28 | } 29 | 30 | /** 31 | * 测试一对一,一对多查询 32 | */ 33 | @Test 34 | public void test002() { 35 | User2 user = dao.selectUser("ID0001"); 36 | System.out.println(user); 37 | System.out.println(user.getLogin()); 38 | System.out.println(user.getIdentityList()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/github/mybatis/SimpleProviderDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.domain.User; 5 | import org.junit.FixMethodOrder; 6 | import org.junit.Test; 7 | import org.junit.runners.MethodSorters; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * 测试sql语句构建器 15 | */ 16 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 17 | public class SimpleProviderDao extends ApplicationTestRoot { 18 | 19 | @Autowired 20 | private com.github.mybatis.providerDao.SimpleProviderDao dao; 21 | 22 | /** 23 | * 测试查询 24 | */ 25 | @Test 26 | public void test001() { 27 | User user = dao.selectUserById("ID0001"); 28 | System.out.println(user); 29 | } 30 | 31 | /** 32 | * 测试条件查询 33 | */ 34 | @Test 35 | public void test002() { 36 | List list = dao.selectUser("name_2"); 37 | for (User user : list) { 38 | System.out.println(user); 39 | } 40 | System.out.println("====================="); 41 | list = dao.selectUser(""); 42 | for (User user : list) { 43 | System.out.println(user); 44 | } 45 | } 46 | 47 | /** 48 | * 测试新增 49 | */ 50 | @Test 51 | public void test003() { 52 | User user = new User("10005", "provider insert name", 11); 53 | System.out.println(dao.insertUser(user)); 54 | System.out.println(dao.selectUserById("10005")); 55 | } 56 | 57 | /** 58 | * 测试批量新增 59 | */ 60 | @Test 61 | public void test004() { 62 | List list = new ArrayList<>(); 63 | list.add(new User("10006", "name_6", 16)); 64 | list.add(new User("10007", "name_7", 17)); 65 | list.add(new User("10008", "name_8", 18)); 66 | System.out.println(dao.insertUserList(list)); 67 | System.out.println(dao.selectUserById("10006")); 68 | System.out.println(dao.selectUserById("10007")); 69 | System.out.println(dao.selectUserById("10008")); 70 | } 71 | 72 | /** 73 | * 测试修改 74 | */ 75 | @Test 76 | public void test005() { 77 | User user = new User("10005", "updateName", 11); 78 | System.out.println(dao.selectUserById("10005")); 79 | System.out.println(dao.updateUser(user)); 80 | System.out.println(dao.selectUserById("10005")); 81 | } 82 | 83 | /** 84 | * 测试删除 85 | */ 86 | @Test 87 | public void test006() { 88 | System.out.println(dao.deleteUser("10005")); 89 | System.out.println(dao.deleteUser("10006")); 90 | System.out.println(dao.deleteUser("10007")); 91 | System.out.println(dao.deleteUser("10008")); 92 | System.out.println(dao.selectUserById("10005")); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/com/github/mybatis/SimpleSqlDao.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.domain.User; 5 | import org.junit.FixMethodOrder; 6 | import org.junit.Test; 7 | import org.junit.runners.MethodSorters; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * 测试简单sql语句 16 | */ 17 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 18 | public class SimpleSqlDao extends ApplicationTestRoot { 19 | @Autowired 20 | private com.github.mybatis.dao.SimpleSqlDao dao; 21 | 22 | /** 23 | * 测试连接 24 | */ 25 | @Test 26 | public void test001() { 27 | System.out.println(dao.testSqlConnent()); 28 | } 29 | 30 | /** 31 | * 测试新增 bean 32 | */ 33 | @Test 34 | public void test002() { 35 | User user = new User("10001", "helloworld", 11); 36 | System.out.println("success insert user by bean: " + dao.insertUser(user)); 37 | System.out.println(dao.selectUserById("10001")); 38 | } 39 | 40 | /** 41 | * 测试新增 map 42 | */ 43 | @Test 44 | public void test003() { 45 | Map map = new HashMap<>(); 46 | map.put("id", "10002"); 47 | map.put("name", "helloworld2"); 48 | map.put("age", 12); 49 | System.out.println("success insert user by map: " + dao.insertUserByMap(map)); 50 | System.out.println(dao.selectUserById("10002")); 51 | } 52 | 53 | /** 54 | * 测试新增 param 55 | */ 56 | @Test 57 | public void test004() { 58 | int n = dao.insertUserByParam("10003", "helloworld3", 13); 59 | System.out.println("success insert user by param: " + n); 60 | System.out.println(dao.selectUserById("10003")); 61 | } 62 | 63 | /** 64 | * 测试修改 65 | */ 66 | @Test 67 | public void test005() { 68 | User user = new User("10003", "updateName", 23); 69 | System.out.println(dao.updateUser(user)); 70 | System.out.println(dao.selectUserById("10003")); 71 | } 72 | 73 | /** 74 | * 测试删除 75 | */ 76 | @Test 77 | public void test006() { 78 | System.out.println(dao.deleteUserById("10003")); 79 | System.out.println(dao.selectUserById("10003")); 80 | } 81 | 82 | /** 83 | * 测试查询 bean 84 | */ 85 | @Test 86 | public void test007() { 87 | User user = dao.selectUserById("10001"); 88 | System.out.println(user); 89 | } 90 | 91 | /** 92 | * 测试查询 list 93 | */ 94 | @Test 95 | public void test008() { 96 | List list = dao.selectUser(); 97 | for (User bean : list) { 98 | System.out.println(bean); 99 | } 100 | } 101 | 102 | /** 103 | * 测试 truncate 104 | */ 105 | @Test 106 | public void test009() { 107 | dao.truncateUser(); 108 | System.out.println("user table num is : " + dao.selectCountUser()); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/test/java/com/github/mybatis/Transactional.java: -------------------------------------------------------------------------------- 1 | package com.github.mybatis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.service.TransactionalService; 5 | import org.junit.Ignore; 6 | import org.junit.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | /** 10 | * 事务测试 11 | */ 12 | public class Transactional extends ApplicationTestRoot { 13 | @Autowired 14 | private TransactionalService service; 15 | 16 | /** 17 | * 测试 @Transactional 注解,正常情况 18 | */ 19 | @Test 20 | public void test001() { 21 | service.testTransactional(false); 22 | } 23 | 24 | /** 25 | * 测试 @Transactional 注解,异常情况 26 | */ 27 | @Test 28 | public void test002() { 29 | service.testTransactional(true); 30 | } 31 | 32 | /** 33 | * 测试 @Transactional 注解参数, timeout参数 34 | */ 35 | @Test 36 | public void test003() { 37 | long start = System.currentTimeMillis(); 38 | try { 39 | service.testTSTimeout(); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } 43 | long end = System.currentTimeMillis(); 44 | System.out.println(end - start); 45 | } 46 | 47 | /** 48 | * 测试spring 数据库事务类,正常情况 49 | */ 50 | @Test 51 | public void test004() { 52 | service.testHandleCommitTS(false); 53 | } 54 | 55 | /** 56 | * 测试spring 数据库事务类,异常情况 57 | */ 58 | @Test 59 | public void test005() { 60 | service.testHandleCommitTS(true); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/com/github/redis/RedisDaoCache.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.domain.User; 5 | import org.junit.Ignore; 6 | import org.junit.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.redis.core.ValueOperations; 9 | 10 | import java.util.List; 11 | 12 | public class RedisDaoCache extends ApplicationTestRoot { 13 | @Autowired 14 | private RedisCacheUserDao dao; 15 | 16 | @Autowired 17 | private ValueOperations redisString; 18 | 19 | @Test 20 | public void test001() { 21 | System.out.println("redis before use : " + redisString.get("users::ID0001")); 22 | System.out.println(dao.selectUserById("ID0001")); 23 | System.out.println("redis after use : " + redisString.get("users::ID0001")); 24 | System.out.println(); 25 | 26 | System.out.println(redisString.get("users::list")); 27 | List list = dao.selectUser(); 28 | System.out.println(list.size()); 29 | System.out.println(redisString.get("users::list")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/redis/RedisServiceCache.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | 4 | import com.ApplicationTestRoot; 5 | import com.github.mybatis.domain.User; 6 | import org.junit.FixMethodOrder; 7 | import org.junit.Ignore; 8 | import org.junit.Test; 9 | import org.junit.runners.MethodSorters; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.data.redis.core.ValueOperations; 12 | 13 | import java.util.List; 14 | import java.util.Set; 15 | 16 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 17 | public class RedisServiceCache extends ApplicationTestRoot { 18 | @Autowired 19 | private RedisCacheUserService service; 20 | 21 | @Autowired 22 | private ValueOperations redisString; 23 | 24 | /** 25 | * 测试 @Cacheable 注解,缓存bean 26 | */ 27 | @Test 28 | public void test001() { 29 | System.out.println("redis before use : " + redisString.get("user::ID0001")); 30 | System.out.println(service.selectUserById("ID0001")); 31 | System.out.println("redis after use : " + redisString.get("user::ID0001")); 32 | System.out.println(); 33 | 34 | System.out.println("redis before use : " + redisString.get("user::ID0001")); 35 | System.out.println(service.selectUserById("ID0001")); 36 | System.out.println("redis after use : " + redisString.get("user::ID0001")); 37 | System.out.println(); 38 | } 39 | 40 | /** 41 | * 测试 @Cacheable 注解,缓存list 42 | * 'list':指定 list字符串作为key 43 | */ 44 | @Test 45 | public void test002() { 46 | System.out.println(redisString.get("user::list")); 47 | List list = service.selectUser(); 48 | System.out.println(list.size()); 49 | System.out.println(redisString.get("user::list")); 50 | } 51 | 52 | /** 53 | * 测试 @Cacheable 注解的 condition : 满足条件时缓存数据 54 | */ 55 | @Test 56 | public void test003() { 57 | User user1 = service.selectUserByIdWithCondition("ID0002", 19); 58 | System.out.println(user1); 59 | System.out.println("redis data[ID0002] : " + redisString.get("user::ID0002")); 60 | 61 | User user2 = service.selectUserByIdWithCondition("ID0003", 20); 62 | System.out.println(user2); 63 | System.out.println("redis data[ID0003]: " + redisString.get("user::ID0003")); 64 | } 65 | 66 | /** 67 | * 测试 @Cacheable 注解的 unless : 满足条件时不缓存数据 68 | */ 69 | @Test 70 | public void test004() { 71 | User user1 = service.selectUserByIdWithUnless("ID0004", 19); 72 | System.out.println(user1); 73 | System.out.println("redis data[ID0004] : " + redisString.get("user::ID0004")); 74 | 75 | User user2 = service.selectUserByIdWithUnless("ID0005", 20); 76 | System.out.println(user2); 77 | System.out.println("redis data[ID0005]: " + redisString.get("user::ID0005")); 78 | } 79 | 80 | /** 81 | * 测试 @CachePut 注解 82 | */ 83 | @Test 84 | public void test005() { 85 | User user = new User("10086", "insert_name", 11); 86 | service.insertUser(user); 87 | System.out.println(redisString.get("user::10086")); 88 | 89 | User user2 = new User("10087", "insert_name", 22); 90 | service.insertUserWithCondition(user2); 91 | System.out.println(redisString.get("user::10087")); 92 | 93 | User user3 = new User("10086", "update_name", 12); 94 | service.updateUser(user3); 95 | System.out.println(redisString.get("user::10086")); 96 | } 97 | 98 | /** 99 | * 测试 @CacheEvict 注解 100 | */ 101 | @Test 102 | public void test006() { 103 | System.out.println(redisString.getOperations().keys("user::*")); 104 | service.deleteUserById("10086"); 105 | System.out.println(redisString.getOperations().keys("user::*")); 106 | service.deleteUserByIdAndCleanCache("10087"); 107 | System.out.println(redisString.getOperations().keys("user::*")); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/com/github/redis/RedisSysBean.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.google.gson.Gson; 5 | import org.junit.FixMethodOrder; 6 | import org.junit.Test; 7 | import org.junit.runners.MethodSorters; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.redis.connection.RedisConnectionFactory; 10 | import org.springframework.data.redis.core.RedisTemplate; 11 | import org.springframework.data.redis.core.StringRedisTemplate; 12 | import org.springframework.data.redis.core.ValueOperations; 13 | 14 | import java.io.Serializable; 15 | 16 | /** 17 | * 测试redis org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration 类配置的bean 18 | */ 19 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 20 | public class RedisSysBean extends ApplicationTestRoot { 21 | @Autowired 22 | private RedisConnectionFactory factory; 23 | 24 | @Autowired 25 | private RedisTemplate objectTemplate; 26 | 27 | @Autowired 28 | private StringRedisTemplate stringTemplate; 29 | 30 | /** 31 | * 测试ping命令 32 | */ 33 | @Test 34 | public void test001() { 35 | String callback = factory.getConnection().ping(); 36 | System.out.println(callback); 37 | } 38 | 39 | /** 40 | * 测试SpringBoot 配置的RedisTemplate 对象 41 | */ 42 | @Test 43 | public void test002() { 44 | System.out.println(objectTemplate);// not null 45 | System.out.println(stringTemplate);// not null 46 | } 47 | 48 | /** 49 | * objectTemplate:key和value需要实现Serializable 接口 50 | */ 51 | @Test 52 | public void test003() { 53 | ValueOperations valueTemplate = objectTemplate.opsForValue(); 54 | 55 | valueTemplate.set("ObjectKey1", "hello spring boot redis, Object Redis"); 56 | String value = (String) valueTemplate.get("ObjectKey1"); 57 | System.out.println(value); 58 | 59 | valueTemplate.set("ObjectKey2", new Person("theName", 11)); 60 | Person person = (Person) valueTemplate.get("ObjectKey2"); 61 | System.out.println(person); 62 | } 63 | 64 | /** 65 | * stringTemplate: key和value都是string 66 | * 当需要保存bean时,可以转为json格式的字符串 67 | */ 68 | @Test 69 | public void test004() { 70 | ValueOperations valueTemplate = stringTemplate.opsForValue(); 71 | Gson gson = new Gson(); 72 | 73 | valueTemplate.set("StringKey1", "hello spring boot redis, String Redis"); 74 | String value = valueTemplate.get("StringKey1"); 75 | System.out.println(value); 76 | 77 | valueTemplate.set("StringKey2", gson.toJson(new Person("theName", 11))); 78 | Person person = gson.fromJson(valueTemplate.get("StringKey2"), Person.class); 79 | System.out.println(person); 80 | } 81 | } 82 | 83 | class Person implements Serializable { 84 | @Override 85 | public String toString() { 86 | return "Persion [name=" + name + ", age=" + age + "]"; 87 | } 88 | 89 | public Person(String name, int age) { 90 | this.name = name; 91 | this.age = age; 92 | } 93 | 94 | private static final long serialVersionUID = 1L; 95 | private String name; 96 | private int age; 97 | 98 | public static long getSerialVersionUID() { 99 | return serialVersionUID; 100 | } 101 | 102 | public String getName() { 103 | return name; 104 | } 105 | 106 | public void setName(String name) { 107 | this.name = name; 108 | } 109 | 110 | public int getAge() { 111 | return age; 112 | } 113 | 114 | public void setAge(int age) { 115 | this.age = age; 116 | } 117 | } -------------------------------------------------------------------------------- /src/test/java/com/github/redis/RedisUserBean.java: -------------------------------------------------------------------------------- 1 | package com.github.redis; 2 | 3 | import com.ApplicationTestRoot; 4 | import com.github.mybatis.domain.User; 5 | import org.junit.FixMethodOrder; 6 | import org.junit.Test; 7 | import org.junit.runners.MethodSorters; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.redis.core.*; 10 | 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.Set; 15 | 16 | /** 17 | * 测试配置的 com.github.redis.RedisConfig 配置的 RedisTemplate 18 | */ 19 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 20 | public class RedisUserBean extends ApplicationTestRoot { 21 | @Autowired 22 | private RedisTemplate template; 23 | 24 | @Autowired 25 | private ValueOperations redisString; 26 | 27 | @Autowired 28 | private HashOperations redisHash; 29 | 30 | @Autowired 31 | private ListOperations redisList; 32 | 33 | @Autowired 34 | private SetOperations redisSet; 35 | 36 | @Autowired 37 | private ZSetOperations redisZSet; 38 | 39 | @Test 40 | public void test001() { 41 | System.out.println(template);// not null 42 | } 43 | 44 | /** 45 | * 测试 Redis String 46 | */ 47 | @Test 48 | public void test002() { 49 | // SET key value: 设置指定 key 的值 50 | redisString.set("strKey1", "hello spring boot redis"); 51 | // GET key: 获取指定 key 的值 52 | String value = (String) redisString.get("strKey1"); 53 | System.out.println(value); 54 | 55 | redisString.set("strKey2", new User("ID10086", "theName", 11)); 56 | User user = (User) redisString.get("strKey2"); 57 | System.out.println(user); 58 | } 59 | 60 | /** 61 | * 测试 Redis Hash 62 | */ 63 | @Test 64 | public void test003() { 65 | Map map = new HashMap<>(); 66 | map.put("id", "10010"); 67 | map.put("name", "redis_name"); 68 | map.put("amount", 12.34D); 69 | map.put("age", 11); 70 | redisHash.putAll("hashKey", map); 71 | // HGET key field 获取存储在哈希表中指定字段的值 72 | String name = (String) redisHash.get("hashKey", "name"); 73 | System.out.println(name); 74 | // HGET key field 75 | Double amount = (Double) redisHash.get("hashKey", "amount"); 76 | System.out.println(amount); 77 | // HGETALL key 获取在哈希表中指定 key 的所有字段和值 78 | Map map2 = redisHash.entries("hashKey"); 79 | System.out.println(map2); 80 | // HKEYS key 获取在哈希表中指定 key 的所有字段 81 | Set keySet = redisHash.keys("hashKey"); 82 | System.out.println(keySet); 83 | // HVALS key 获取在哈希表中指定 key 的所有值 84 | List valueList = redisHash.values("hashKey"); 85 | System.out.println(valueList); 86 | } 87 | 88 | /** 89 | * 测试 Redis List 90 | */ 91 | @Test 92 | public void test004() { 93 | redisList.leftPush("listKey", "aaa"); 94 | redisList.leftPush("listKey", "bbb"); 95 | redisList.rightPush("listKey", "ccc"); 96 | // LLEN key: 获取列表长度 97 | Long size = redisList.size("listKey"); 98 | // LRANGE key start stop: 获取列表指定范围内的元素 99 | if (size != null) { 100 | List list = redisList.range("listKey", 0, size); 101 | System.out.println(size); 102 | System.out.println(list); 103 | } 104 | } 105 | 106 | /** 107 | * 测试 Redis Set 108 | */ 109 | @Test 110 | public void test005() { 111 | redisSet.add("setKey", "aSet"); 112 | redisSet.add("setKey", "bSet"); 113 | redisSet.add("setKey", "bSet"); 114 | // SMEMBERS key: 返回集合中的所有成员 115 | Set set = redisSet.members("setKey"); 116 | System.out.println(set); 117 | } 118 | 119 | /** 120 | * 测试 Redis ZSet 121 | */ 122 | @Test 123 | public void test006() { 124 | // ZADD key score1 member1 [score2 member2] 125 | // 向有序集合添加一个或多个成员,或者更新已存在成员的分数, 126 | // 注意score位置,redisZSet 和 ZADD 命令不同 127 | redisZSet.add("zSetKey", "aZSet", 11); 128 | redisZSet.add("zSetKey", "bZSet", 12); 129 | redisZSet.add("zSetKey", "cZSet", 13); 130 | redisZSet.add("zSetKey", "dZSet", 14); 131 | // ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 132 | // 通过分数返回有序集合指定区间内的成员 133 | Set set = redisZSet.rangeByScore("zSetKey", 11, 13); 134 | System.out.println(set); 135 | } 136 | } 137 | --------------------------------------------------------------------------------