前提基础
JDBC java数据库连接
Mysql 数据库
Java基础 代码基础
Maven 项目构建
Junit 测试功能包
基础 什么是 MyBatis
获取mybatis
1 2 3 4 5 6 <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.7</version > </dependency >
为什么需要mybatis
简化传统的JDBC代码。
简单易学
灵活
sql和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的orm字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql。
社区活跃
使用人群多,流行。
易于spring和springboot的整合。
示例代码 https://github.com/snmlm/study
环境搭建 数据库搭建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CREATE TABLE `mybatis` .`user` ( `id` int (11 ) NOT NULL AUTO_INCREMENT, `name` varchar (30 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL , `age` int (11 ) NULL DEFAULT NULL , `pwd` varchar (16 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL , `authorityid` int (11 ) NULL DEFAULT NULL , PRIMARY KEY (`id` ) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; INSERT INTO `mybatis` .`user` (`name` , `age` , `pwd` , `authorityId` ) VALUES ('snmlm' , 3 , 'snmlm' , 1 );INSERT INTO `mybatis` .`user` (`name` , `age` , `pwd` , `authorityId` ) VALUES ('张三' , 4 , 'zhangsan' , 2 );INSERT INTO `mybatis` .`user` (`name` , `age` , `pwd` , `authorityId` ) VALUES ('李四' , 3 , 'zhangsan' , 1 );CREATE TABLE `mybatis` .`authority` ( `id` int (11 ) NOT NULL AUTO_INCREMENT, `name` varchar (30 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL , PRIMARY KEY (`id` ) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; INSERT INTO `mybatis` .`authority` (`name` ) VALUES ('insert' );INSERT INTO `mybatis` .`authority` (`name` ) VALUES ('delete' );INSERT INTO `mybatis` .`authority` (`name` ) VALUES ('update' );INSERT INTO `mybatis` .`authority` (`name` ) VALUES ('select' );
创建一个maven项目 pom.xml配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > </properties > <dependencies > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.7</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.25</version > </dependency > <dependency > <groupId > org.apache.logging.log4j</groupId > <artifactId > log4j-core</artifactId > <version > 2.14.1</version > </dependency > <dependency > <groupId > org.apache.logging.log4j</groupId > <artifactId > log4j-api</artifactId > <version > 2.14.1</version > </dependency > <dependency > <groupId > com.github.pagehelper</groupId > <artifactId > pagehelper</artifactId > <version > 5.2.0</version > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.18.20</version > <scope > provided</scope > </dependency > <dependency > <groupId > org.mybatis.caches</groupId > <artifactId > mybatis-ehcache</artifactId > <version > 1.2.1</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.13.2</version > <scope > test</scope > </dependency > </dependencies > <build > <defaultGoal > package</defaultGoal > <sourceDirectory > ${basedir}/src/main/java</sourceDirectory > <outputDirectory > ${basedir}/target/classes</outputDirectory > <resources > <resource > <directory > src/main/java</directory > <includes > <include > **/*.hbm.xml</include > </includes > </resource > <resource > <directory > src/main/resources</directory > <filtering > true</filtering > <includes > <include > **/*.xml</include > <include > **/*.dtd</include > <include > **/*.properties</include > </includes > </resource > </resources > </build >
mybatis的配置文件mybatis-config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?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 > <properties resource ="./db.properties" /> <settings > <setting name ="logImpl" value ="LOG4J2" /> </settings > <typeAliases > <package name ="com.snmlm.dto" /> </typeAliases > <plugins > <plugin interceptor ="com.github.pagehelper.PageInterceptor" > <property name ="helperDialect" value ="mysql" /> <property name ="pageSizeZero" value ="true" /> </plugin > </plugins > <environments default ="development" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="${driver}" /> <property name ="url" value ="${url}" /> <property name ="username" value ="${username}" /> <property name ="password" value ="${password}" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="./mapper/UserMapper.xml" /> <mapper resource ="./mapper/AuthorityMapper.xml" /> </mappers > </configuration >
db.properties
1 2 3 4 driver =com.mysql.cj.jdbc.Driver url =jdbc:mysql://ip:prot/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8 username =username password =password
UserMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 <?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.snmlm.dao.UserMapper" > <cache type ="org.mybatis.caches.ehcache.EhcacheCache" /> <resultMap id ="BaseResultMap" type ="userDto" > <id column ="id" property ="id" jdbcType ="INTEGER" /> <result column ="name" property ="name" jdbcType ="VARCHAR" /> <result column ="age" property ="age" jdbcType ="INTEGER" /> <result column ="pwd" property ="pwd" jdbcType ="VARCHAR" /> <association property ="authorityDto" column ="authorityId" javaType ="authorityDto" select ="selectAuthority" /> </resultMap > <select id ="selectUserAuthority" resultMap ="BaseResultMap" > select * from mybatis.user where id = #{id} </select > <select id ="selectAuthority" resultType ="authorityDto" > select * from mybatis.authority where id = #{id} </select > <sql id ="Base_Column_List" > id,name,age,pwd </sql > <sql id ="WhereById" > <where > <if test ="id != null" > id = #{id,jdbcType=INTEGER} </if > </where > </sql > <insert id ="insert" parameterType ="userDto" > insert into mybatis.user <trim prefix ="(" suffix =")" suffixOverrides ="," > <if test ="name != null" > name, </if > <if test ="age != null" > age, </if > <if test ="pwd != null" > pwd, </if > </trim > VALUES <trim prefix ="(" suffix =")" suffixOverrides ="," > <if test ="name != null" > #{name,jdbcType=VARCHAR}, </if > <if test ="age != null" > #{age,jdbcType=INTEGER}, </if > <if test ="pwd != null" > #{pwd,jdbcType=VARCHAR}, </if > </trim > </insert > <delete id ="deleteByPrimary" parameterType ="java.lang.Integer" > delete from mybatis.user where id = #{id,jdbcType=INTEGER} </delete > <delete id ="deleteByObject" parameterType ="userDto" > delete from mybatis.user <where > <trim prefixOverrides ="and|or" > <if test ="id != null" > and id = #{id,jdbcType=INTEGER} </if > <if test ="name != null" > and name = #{name,jdbcType=VARCHAR} </if > <if test ="age != null" > and age = #{age,jdbcType=INTEGER} </if > <if test ="pwd != null" > and pwd = #{pwd,jdbcType=VARCHAR} </if > </trim > </where > </delete > <update id ="updateByObject" parameterType ="userDto" > update mybatis.user <set > <trim suffixOverrides ="," > <if test ="name != null" > name = #{name,jdbcType=VARCHAR}, </if > <if test ="age != null" > age = #{age,jdbcType=INTEGER}, </if > <if test ="pwd != null" > pwd = #{pwd,jdbcType=VARCHAR}, </if > </trim > </set > <include refid ="WhereById" /> </update > <select id ="findListByObject" resultType ="userDto" parameterType ="userDto" > select <include refid ="Base_Column_List" /> from mybatis.user <where > <if test ="id != null" > and id = #{id,jdbcType=INTEGER} </if > <if test ="name != null" > and name = #{name,jdbcType=VARCHAR} </if > <if test ="age != null" > and age = #{age,jdbcType=INTEGER} </if > <if test ="pwd != null" > and pwd = #{pwd,jdbcType=VARCHAR} </if > </where > </select > </mapper >
AuthorityMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?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.snmlm.dao.AuthorityMapper" > <resultMap id ="BaseResultMap" type ="authorityDto" > <id column ="id" property ="id" jdbcType ="INTEGER" /> <result column ="name" property ="name" jdbcType ="VARCHAR" /> <collection property ="userDtoList" column ="id" javaType ="java.util.ArrayList" ofType ="userDto" select ="selectUser" /> </resultMap > <select id ="selectAuthorityUser" resultMap ="BaseResultMap" > select * from mybatis.authority where id = #{id} </select > <select id ="selectUser" resultType ="userDto" > select * from mybatis.user where authorityId = #{id} </select > </mapper >
UserMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.snmlm.dao;import com.snmlm.dto.UserDto;import org.apache.ibatis.annotations.*;import java.util.List;public interface UserMapper { public void insert (UserDto userDto) ; public void deleteByPrimary (Integer id) ; public void deleteByObject (UserDto userDto) ; public void updateByObject (UserDto userDto) ; public List<UserDto> findListByObject (UserDto userDto) ; public List<UserDto> selectUserAuthority (Integer id) ; @Select("select * from mybatis.user where id = #{id}") public UserDto select (Integer id) ; @Select("select * from mybatis.user where id = #{id}") @Result(property = "authorityDto", column = "authorityId", one = @One(select = "com.snmlm.dao.AuthorityMapper.select") ) public List<UserDto> selectUserAuthorityAnnotation (Integer id) ; @Insert("insert into user(name,age,pwd) values (#{name},#{age},#{password})") public void insertAnnotation (UserDto userDto) ; @Insert("insert into user(name,age) values (#{name},#{age})") public void insertAnnotation1 (@Param("name") String name,@Param("age") Integer age) ; @Delete("delete from user where id = #{uid}") public void deleteByPrimaryAnnotation (@Param("id") Integer uid) ; @DeleteProvider(type = DeleteUserMapper.class, method = "getSql") public void deleteByObjectAnnotation (UserDto userDto) ; @Select("select * from user") public List<UserDto> findListAnnotation () ; }
AuthorityMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 public interface AuthorityMapper { public List<AuthorityDto> selectAuthorityUser (Integer id) ; @Select("select * from mybatis.authority where id = #{id}") @Result(property = "userDtoList", column = "id", many = @Many(select = "com.snmlm.dao.UserMapper.select") ) public List<UserDto> selectAuthorityUserAnnotation (Integer id) ; @Select("select * from mybatis.authority where id = #{id}") public AuthorityDto select (Integer id) ; }
DeleteUserMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class DeleteUserMapper { public String getSql (UserDto userDto) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("delete from mybatis.user " ); if (userDto == null ){ return stringBuilder.toString(); } StringBuilder whereSB = new StringBuilder(); if (userDto.getId() != null ){ whereSB.append(" and id = " ).append(userDto.getId()); } if (userDto.getName() != null ){ whereSB.append(" and name = '" ).append(userDto.getName()).append("'" ); } if (userDto.getAge() != null ){ whereSB.append(" and age = " ).append(userDto.getAge()); } if (userDto.getPwd() != null ){ whereSB.append(" and pwd = '" ).append(userDto.getPwd()).append("'" ); } if (userDto.getAddress() != null ){ whereSB.append(" and address = '" ).append(userDto.getAddress()).append("'" ); } if (whereSB.length()>0 ){ stringBuilder.append(" where " ).append(whereSB.substring(4 )); } return stringBuilder.toString(); } }
UserDto.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Data public class UserDto { private Integer id; private String name; private Integer age; private String pwd; private String address; private AuthorityDto authorityDto; private String authorityId; }
AuthorityDto.java
1 2 3 4 5 6 @Data public class AuthorityDto { private Integer id; private String name; private List<UserDto> userDtoList; }
MybatisUtils.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; static { try { String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession () { return sqlSessionFactory.openSession(true ); } }
测试用例,UserMapperTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 public class UserMapperTest { @Test public void insertTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); UserDto userDto = new UserDto(); userDto.setName("哈哈" ); userDto.setAge(1 ); userMapper.insert(userDto); for (UserDto dto : userMapper.findListByObject(null )) { System.out.println(dto.toString()); } } } @Test public void deleteTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.deleteByPrimary(3 ); UserDto userDto1 = new UserDto(); userDto1.setAge(1 ); userMapper.deleteByObject(userDto1); for (UserDto dto : userMapper.findListByObject(null )) { System.out.println(dto.toString()); } } } @Test public void updateTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); UserDto userDto = new UserDto(); userDto.setId(1 ); userDto.setPwd("2233" ); userMapper.updateByObject(userDto); for (UserDto dto : userMapper.findListByObject(null )) { System.out.println(dto.toString()); } } } @Test public void selectPageHelperTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); PageHelper.startPage(2 ,2 ); for (UserDto dto : userMapper.findListByObject(null )) { System.out.println(dto.toString()); } } } @Test public void deleteByPrimaryAnnotationTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); UserDto userDto = new UserDto(); userDto.setAge(1 ); userMapper.deleteByObjectAnnotation(userDto); for (UserDto dto : userMapper.findListAnnotation()) { System.out.println(dto.toString()); } } } @Test public void selectUserAutrity () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); for (UserDto dto : userMapper.selectUserAuthority(1 )) { System.out.println(dto.toString()); } } } @Test public void selectUserAuthorityAnnotationTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); for (UserDto dto : userMapper.selectUserAuthorityAnnotation(1 )) { System.out.println(dto.toString()); } } } }
AuthorityMapperTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class AuthorityMapperTest { @Test public void selectAuthorityUserTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ AuthorityMapper authorityMapper = sqlSession.getMapper(AuthorityMapper.class); for (AuthorityDto dto : authorityMapper.selectAuthorityUser(1 )) { System.out.println(dto.toString()); } } } @Test public void selectAuthorityUserAnnotationTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ AuthorityMapper authorityMapper = sqlSession.getMapper(AuthorityMapper.class); for (AuthorityDto dto : authorityMapper.selectAuthorityUser(1 )) { System.out.println(dto.toString()); } } } }
Map 在mybatis中map可以充当输入和输出的载体,直接根据key获取值。
模糊查询 1 2 List<User> userList = mapper.getUserLike("%李%" );
1 2 select * from mybatis.user where name like "%"#{value}"%"
配置解析 xml中有强制顺序,否则标签爆红。
configuration(配置)
properties(属性)
property的优先级低于导入,所以会被导入覆盖。代码中配置的优先级最高
settings(设置)
typeAliases(类型别名)
package 扫描包,默认根据类名来,小写开头,大写也能用。为了区别全类名限定,建议小写。
@Alias ibatis包下的注解,在类中使用,优先级高于配置文件
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置) default=environmentid 根据environment中的id进行加载,只能加载一个。
environment(环境变量)
transactionManager(事务管理器)JDBC(默认)|MANAGED,
dataSource(数据源) POOLED(默认)|UNPOOLED|JNDI(用于外部容器)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
配置导入源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 this .propertiesElement(root.evalNode("properties" ));private void propertiesElement (XNode context) throws Exception { if (context != null ) { Properties defaults = context.getChildrenAsProperties(); String resource = context.getStringAttribute("resource" ); String url = context.getStringAttribute("url" ); if (resource != null && url != null ) { throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other." ); } if (resource != null ) { defaults.putAll(Resources.getResourceAsProperties(resource)); } else if (url != null ) { defaults.putAll(Resources.getUrlAsProperties(url)); } Properties vars = this .configuration.getVariables(); if (vars != null ) { defaults.putAll(vars); } this .parser.setVariables(defaults); this .configuration.setVariables(defaults); } }
生命周期和作用域
SqlSessionFactoryBuilder
一旦创建了SqlSessionFactory,就不再需要它了
局部变量
SqlSessionFactory
一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
最佳作用域是应用作用域。
最简单的就是使用 单例模式 或者静态单例模式。
SqlSession
连接到连接池的一个请求!
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
用完之后需要赶紧关闭,否则会占用资源
resultMap
对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
在对于dto与数据库表的字段名不一致时,需要配置resultMap,建立字段的映射关系。
日志 mybatis中日志的配置。
1 2 3 <settings > <setting name ="logImpl" value ="STDOUT_LOGGING" /> </settings >
支持
SLF4J
LOG4J 可以单独配置
LOG4J2
JDK_LOGGING
COMMONS_LOGGING
STDOUT_LOGGING 通常的输出日志,在后台上
NO_LOGGING
log4j
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件。
可以控制每一条日志的输出格式。
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
导入maven依赖
1 2 3 4 5 <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > 1.2.17</version > </dependency >
mybatis-config.xml的日志修改为LOG4J
1 2 3 <settings > <setting name ="logImpl" value ="LOG4J" /> </settings >
添加log4j的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 log4j.rootLogger =DEBUG,console,file log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold =DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern =【%c】-%m%n log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File =./log/snmlm.log log4j.appender.file.MaxFileSize =10mb log4j.appender.file.Threshold =DEBUG log4j.appender.file.layout =org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern =【%p】【%d{yy-MM-dd}】【%c】%m%n log4j.logger.org.mybatis =DEBUG log4j.logger.java.sql =DEBUG
log4j2
跟log4j是同一作者
基于log4j 1.x和logback的有点,重构了log4j,支持异步输出,解决log4j同步输出时导致内存和cpu过大的瓶颈。
导入maven依赖
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > org.apache.logging.log4j</groupId > <artifactId > log4j-core</artifactId > <version > 2.14.1</version > </dependency > <dependency > <groupId > org.apache.logging.log4j</groupId > <artifactId > log4j-api</artifactId > <version > 2.14.1</version > </dependency >
mybatis-config.xml的日志修改为LOG4J
1 2 3 <settings > <setting name ="logImpl" value ="LOG4J2" /> </settings >
添加log4j的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?xml version="1.0" encoding="UTF-8"?> <Configuration status ="WARN" > <Appenders > <Console name ="Console" target ="SYSTEM_OUT" > <PatternLayout pattern ="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </Console > </Appenders > <Loggers > <Root level ="DEBUG" > <AppenderRef ref ="Console" /> </Root > <logger name ="java.sql" level ="DEBUG" /> <logger name ="org.apache.ibatis" level ="DEBUG" /> </Loggers > </Configuration >
分页 为了减轻查询压力,由于查询时,需要把所有数据加载内存中,那么查询的数据量过大,会导致内存不足,并且大数据量,查询也很慢。
手动分页,利用limit或rows 1 List<User> getUserByLimit (Map<String,Integer> map) ;
1 2 3 4 <select id ="getUserByLimit" parameterType ="map" resultMap ="UserMap" > select * from mybatis.user limit #{startIndex},#{pageSize} </select >
RowBounds 1 2 3 4 <select id ="getUserByRowBounds" resultMap ="UserMap" > select * from mybatis.user </select >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Test public void getUserByRowBounds () { SqlSession sqlSession = MyBatisUtils.getSqlSession(); RowBounds rowBounds = new RowBounds(1 , 2 ); List<User> userList = sqlSession.selectList("com.rui.dao.UserMapper.getUserByRowBounds" ,null ,rowBounds); for (User user : userList) { System.out.println(user); } sqlSession.close(); }
分页插件 导入插件包
1 2 3 4 5 <dependency > <groupId > com.github.pagehelper</groupId > <artifactId > pagehelper</artifactId > <version > 5.2.0</version > </dependency >
修改mybatis-config.xml
1 2 3 4 5 6 7 8 <plugins > <plugin interceptor ="com.github.pagehelper.PageInterceptor" > <property name ="helperDialect" value ="mysql" /> <property name ="pageSizeZero" value ="true" /> </plugin > </plugins >
测试
1 2 3 4 5 6 7 8 9 10 @Test public void selectPageHelperTest () { try (SqlSession sqlSession = MybatisUtils.getSqlSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); PageHelper.startPage(2 ,2 ); for (UserDto dto : userMapper.findListByObject(null )) { System.out.println(dto.toString()); } } }
注解 面向接口编程的根本原因:解耦,可拓展,提高复用,分层开发中、上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性好 UserMapper只留mapper指向的接口对象即可。
当然,在mybatis-config.xml配置mapper class也是一样的,要注意在同包下
1 <mapper namespace ="com.snmlm.dao.UserMapper" />
接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Insert("insert into user(name,age,pwd) values (#{name},#{age},#{password})") public void insertAnnotation (UserDto userDto) ;@Insert("insert into user(name,age) values (#{name},#{age})") public void insertAnnotation1 (@Param("name") String name,@Param("age") Integer age) ;@Delete("delete from user where id = #{uid}") public void deleteByPrimaryAnnotation (@Param("id") Integer uid) ;@DeleteProvider(type = DeleteUserMapper.class, method = "getSql") public void deleteByObjectAnnotation (UserDto userDto) ;@Select("select * from user") public List<UserDto> findListAnnotation () ;
复杂sql的映射DeleteUserMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class DeleteUserMapper { public String getSql (UserDto userDto) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("delete from mybatis.user " ); if (userDto == null ){ return stringBuilder.toString(); } StringBuilder whereSB = new StringBuilder(); if (userDto.getId() != null ){ whereSB.append(" and id = " ).append(userDto.getId()); } if (userDto.getName() != null ){ whereSB.append(" and name = '" ).append(userDto.getName()).append("'" ); } if (userDto.getAge() != null ){ whereSB.append(" and age = " ).append(userDto.getAge()); } if (userDto.getPwd() != null ){ whereSB.append(" and pwd = '" ).append(userDto.getPwd()).append("'" ); } if (userDto.getAddress() != null ){ whereSB.append(" and address = '" ).append(userDto.getAddress()).append("'" ); } if (whereSB.length()>0 ){ stringBuilder.append(" where " ).append(whereSB.substring(4 )); } return stringBuilder.toString(); } }
多对一,一对多 多对一和一对多是相对的,观察的角度不用而已。
例如用户与权限,一个用户可以有多种权限,这是一对多。多个用户有相同的权限,这就是多对一。
在代码中,一个对象下可以包含集合或对象来体现这种一对多,多对一的关系。
方法一,手动拼装 方法二,利用mybatis的配置,进行拼装 封装对象 UserMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <resultMap id ="BaseResultMap" type ="userDto" > <id column ="id" property ="id" jdbcType ="INTEGER" /> <result column ="name" property ="name" jdbcType ="VARCHAR" /> <result column ="age" property ="age" jdbcType ="INTEGER" /> <result column ="pwd" property ="pwd" jdbcType ="VARCHAR" /> <association property ="authorityDto" column ="authorityId" javaType ="authorityDto" select ="selectAuthority" /> </resultMap > <select id ="selectUserAuthority" resultMap ="BaseResultMap" > select * from mybatis.user where id = #{id} </select > <select id ="selectAuthority" resultType ="authorityDto" > select * from mybatis.authority where id = #{id} </select >
封装集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?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.snmlm.dao.AuthorityMapper" > <resultMap id ="BaseResultMap" type ="authorityDto" > <id column ="id" property ="id" jdbcType ="INTEGER" /> <result column ="name" property ="name" jdbcType ="VARCHAR" /> <collection property ="userDtoList" column ="id" javaType ="java.util.ArrayList" ofType ="userDto" select ="selectUser" /> </resultMap > <select id ="selectAuthorityUser" resultMap ="BaseResultMap" > select * from mybatis.authority where id = #{id} </select > <select id ="selectUser" resultType ="userDto" > select * from mybatis.user where authorityId = #{id} </select > </mapper >
方法三 注解形式 UserMapper.java
1 2 3 4 5 @Select("select * from mybatis.user where id = #{id}") @Result(property = "authorityDto", column = "authorityId", one = @One(select = "com.snmlm.dao.AuthorityMapper.select") ) public List<UserDto> selectUserAuthorityAnnotation (Integer id) ;
AuthorityMapper.java
1 2 3 4 5 @Select("select * from mybatis.authority where id = #{id}") @Result(property = "userDtoList", column = "id", many = @Many(select = "com.snmlm.dao.UserMapper.select") ) public List<UserDto> selectAuthorityUserAnnotation (Integer id) ;
缓存 查询 : 连接数据库,耗资源! 一次查询的结果,给他暂存在一个可以直接取到的地方!—>内存 : 缓存 我们再次查询相同数据的时候,直接走缓存,就不用走数据库了
什么事缓存[Cache]?
存在内存中的临时数据。
将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率。
什么样的数据能使用缓存?
mybatis缓存 MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 - 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)一级缓存就是一个Map。 - 二级缓存需要手动开启和配置。 - 全局缓存 - 基于namespace级别的缓存,一个名称空间,对应一个二级缓存 - 为了提扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
1 <setting name ="cacheEnabled" value ="true" />
*Mapper.xml
1 2 3 4 <cache eviction ="FIFO" flushInterval ="60000" size ="512" readOnly ="true" />
同时需注意,pojo对象需要实现序列化。不然会报错。
自定义缓存-encache EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。 导包
1 2 3 4 5 <dependency > <groupId > org.mybatis.caches</groupId > <artifactId > mybatis-ehcache</artifactId > <version > 1.2.1</version > </dependency >
配置缓存文件 ehcache.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemalOcation ="http://ehcache.org/encache.xsd" updateCheck ="false" > <diskStore path ="java.io.tmpdir/Tmp_EhCache" /> <defaultCache eternal ="false" maxElementsInMemory ="10000" overflowToDisk ="false" diskPersistent ="false" timeToIdleSeconds ="1800" timeToLiveSeconds ="259200" memoryStoreEvictionPolicy ="LRU" /> <cache name ="cloud_user" eternal ="false" maxElementsInMemory ="5000" overflowToDisk ="false" diskPersistent ="false" timeToIdleSeconds ="1800" timeToLiveSeconds ="1800" memoryStoreEvictionPolicy ="LRU" /> </ehcache >
mybatis执行顺序
Resources获取加载全局配置文件
实例化SqlSessionFactoryBuilder构造器
解析配置文件流XMLConfigBuilder
Configuration所有的配置信息
SqlSessionFactory实例化
transctional事务管理
创建exceutor执行器
创建SqlSession
执行CURD
是否执行成功