关于mybatis
mybatis是支持SQL定制、存储过程以及高级映射的优秀持久层框架。避免了JDBC操作、设置参数、获取结果集的繁琐手动操作。通过对核心配置文件(mybatis-config.xml)、映射器配置文件(mapper.xml)、resultMap的编写和管理就可以完成从数据库访问、数据库操作、结果集映射的相关操作。
mybatis是一个基于SqlSessionFactory的持久化框架,sqlSessionFactory的作用是生成SqlSession接口对象(mybatis)操作核心。构建SqlSessionFactory的相关工作是通过配置类(Configuration)对相关参数进行配置。配置内容如下:

properties:配置数据库连接/连接池相关属性,整合后在springboot中进行配置。
settings:该配置将影响mybatis底层行为,可以配置映射规则、执行器、缓存、延迟加载相关内容。
typeAliases:类型别名。
typeHandler:类型处理器,通常用于jdbcType和javaType之间进行数据类型转换,大部分情况下不需要使用自定义类型处理器,在枚举类型和日期字符串转换时使用。
objectFactory:在mybatis执行查询返回查询结果映射到Pojo时调用的工厂类。一般使用默认的对象工厂类(DefaultObjectFactory),无需进行配置。
plugins:插件,通过动态代理和责任链模式完成,可影响mybatis底层功能,通常在分页功能中进行使用。
environments:数据库运行环境,可对数据库连接内容和事务相关信息进行配置。
databaseIdProvider:数据库厂商标识,允许mybatis配置多数据库支持。
mappers:映射器,mybatis核心组件,提供sql与pojo映射关系、数据库操作相关功能。
在整合springboot的过程中,通过引入mybatis-spring-boot-starter依赖,在application.properties中对mybatis-config.xml相关信息进行配置,无需提供mybatis-config.xml配置文件。
在pom.xml中添加mybatis依赖
<!--添加mybatis依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency>
在application.properties中配置mybatis相关配置信息
#配置mybatis内容#映射器扫描包mybatis.mapper-locations=classpath:/mappers/*Mapper.xml#接口扫描包mybatis.type-aliases-package=com.springboot.demo.mybatis.dao#类型转换器扫描包mybatis.type-handlers-package=com.springboot.demo.mybatis.typehandler
实体类
package com.springboot.demo.mybatis.pojo;import com.springboot.demo.jdbcTemplate.pojo.SexEnum;public class UserInfo {private int userId;private String userName;private String loginAccount;private String passWord;private int userAge;private String createDate;private String updateDate;private String userState;private SexEnum sexEnum;public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getLoginAccount() {return loginAccount;}public void setLoginAccount(String loginAccount) {this.loginAccount = loginAccount;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) {this.passWord = passWord;}public int getUserAge() {return userAge;}public void setUserAge(int userAge) {this.userAge = userAge;}public String getCreateDate() {return createDate;}public void setCreateDate(String createDate) {this.createDate = createDate;}public String getUpdateDate() {return updateDate;}public void setUpdateDate(String updateDate) {this.updateDate = updateDate;}public String getUserState() {return userState;}public void setUserState(String userState) {this.userState = userState;}public SexEnum getSexEnum() {return sexEnum;}public void setSexEnum(SexEnum sexEnum) {this.sexEnum = sexEnum;}}
自定义类型转换器(本示例中创建日期和更新日期数据库类型为datetime,实体为String;性别枚举中数据库存放的是性别标识,显示中需要转换为具体性别)
package com.springboot.demo.mybatis.typehandler;import com.springboot.demo.utils.DatetimeUtils;import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Date;public class DateTypeHandler extends BaseTypeHandler<Date> {/*** 设置参数* @param preparedStatement:预编译语句* @param i:下标* @param date:日期类型* @param jdbcType:jdbc类型* @throws SQLException*/@Overridepublic void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {String dateStr= DatetimeUtils.dateFormatStr(date);preparedStatement.setString(i,dateStr);}/*** 从结果集中根据列名取出日期* @param resultSet:结果集* @param s:列名* @return 日期* @throws SQLException*/@Overridepublic Date getNullableResult(ResultSet resultSet, String s) throws SQLException {return resultSet.getDate(s);}/*** 从结果集中根据索引取出日期* @param resultSet:结果集* @param i:索引* @return 日期* @throws SQLException*/@Overridepublic Date getNullableResult(ResultSet resultSet, int i) throws SQLException {return resultSet.getDate(i);}@Overridepublic Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {return null;}}
package com.springboot.demo.mybatis.typehandler;import com.springboot.demo.jdbcTemplate.pojo.SexEnum;import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import org.apache.ibatis.type.MappedJdbcTypes;import org.apache.ibatis.type.MappedTypes;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;@MappedJdbcTypes(JdbcType.INTEGER)@MappedTypes(value = SexEnum.class)public class SexTypeHandler extends BaseTypeHandler<SexEnum>{/*** 设置非空性别参数* @param preparedStatement:预编译语句* @param i:索引* @param sexEnum:性别枚举* @param jdbcType:jdbc数据类型* @throws SQLException*/@Overridepublic void setNonNullParameter(PreparedStatement preparedStatement, int i, SexEnum sexEnum, JdbcType jdbcType) throws SQLException {preparedStatement.setInt(i,sexEnum.getId());}/*** 通过列名读取性别* @param resultSet:结果集* @param s:列名* @return 性别枚举* @throws SQLException*/@Overridepublic SexEnum getNullableResult(ResultSet resultSet, String s) throws SQLException {int sex=resultSet.getInt(s);if(sex!=1 && sex!=2){return null;}return SexEnum.getSexById(sex);}/*** 通过下标读取性别* @param resultSet:结果集* @param i:下标* @return 性别枚举* @throws SQLException*/@Overridepublic SexEnum getNullableResult(ResultSet resultSet, int i) throws SQLException {int sex=resultSet.getInt(i);if(sex!=1 && sex!=2){return null;}return SexEnum.getSexById(sex);}/**** @param callableStatement:存储过程* @param i:下标* @return 性别枚举* @throws SQLException*/@Overridepublic SexEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {int sex=callableStatement.getInt(i);if(sex!=1 && sex!=2){return null;}return SexEnum.getSexById(sex);}}
数据库访问层接口
package com.springboot.demo.mybatis.dao;import com.springboot.demo.mybatis.pojo.UserInfo;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.type.Alias;import org.springframework.stereotype.Repository;import java.util.List;@Repositorypublic interface MyBatisUserInfoDao {/***根据用户名称查询用户集合信息* @param userName:用户名* @return用户集合信息*/public List<UserInfo> findUserInfoByUserName(String userName);/*** 根据登录账户查询用户集合信息* @param loginAccount:登录账户* @return用户集合信息*/public List<UserInfo> findUserInfoByLoginAccount(String loginAccount);/*** 根据用户标识查询用户详情信息* @param userId:用户标识* @return 用户详情*/public UserInfo findUserInfoByUserId(int userId);/*** 保存用户信息* @param userInfo:用户信息*/public void saveUserInfo(UserInfo userInfo);/*** 更新用户信息* @param userInfo:用户信息*/public void updateUserInfo(UserInfo userInfo);/*** 更新用户状态* @param userInfo:更新状态用户*/public void updateUserState(UserInfo userInfo);}
映射器文件
<?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.springboot.demo.mybatis.dao.MyBatisUserInfoDao"><!--自定义查询语句,便于复用--><sql id="selectSql">SELECT u.user_id,u.user_name,u.login_account,u.user_age,u.user_state,u.user_sex from t_user u</sql><!--定义查询结果集--><resultMap id="userInfo" type="com.springboot.demo.mybatis.pojo.UserInfo"><id column="user_id" property="userId" javaType="int" jdbcType="INTEGER"/><result column="user_name" property="userName" javaType="String" jdbcType="VARCHAR"/><result column="pass_word" property="passWord" javaType="String" jdbcType="VARCHAR"/><result column="login_account" property="loginAccount" javaType="String" jdbcType="VARCHAR"/><result column="user_age" property="userAge" jdbcType="INTEGER" javaType="int"/><result column="create_date" property="createDate" javaType="String" jdbcType="DATE" typeHandler="com.springboot.demo.mybatis.typehandler.DateTypeHandler"/><result column="update_date" property="updateDate" javaType="String" jdbcType="DATE" typeHandler="com.springboot.demo.mybatis.typehandler.DateTypeHandler"/><result column="user_state" property="userState" javaType="String" /><result column="user_sex" property="sexEnum" jdbcType="INTEGER" typeHandler="com.springboot.demo.mybatis.typehandler.SexTypeHandler"/></resultMap><!--根据用户名查询用户集合信息--><select id="findUserInfoByUserName" parameterType="String" resultMap="userInfo"><include refid="selectSql"/> where u.user_name LIKE CONCAT('%',#{userName},'%')</select><!--根据登录账号查询用户集合信息--><select id="findUserInfoByLoginAccount" parameterType="String" resultMap="userInfo"><include refid="selectSql"/> where u.login_account LIKE CONCAT('%',#{loginAccount},'%')</select><!--根据用户标识查询用户详情--><select id="findUserInfoByUserId" parameterType="int" resultMap="userInfo"><include refid="selectSql"/> where u.user_id=#{userId}</select><!--保存用户信息--><insert id="saveUserInfo" parameterType="com.springboot.demo.mybatis.pojo.UserInfo">insert into t_user(user_name,pass_word,login_account,user_age,create_date,update_date,user_state,user_sex)VALUES (#{userName},#{passWord},#{loginAccount},#{userAge},#{createDate},#{updateDate},#{userState},#{sexEnum});</insert><!--更新用户状态--><update id="updateUserState" parameterType="com.springboot.demo.mybatis.pojo.UserInfo">update t_user u set u.user_state=#{userState},u.update_date=#{updateDate} where u.user_id=#{userId}</update></mapper>
业务逻辑层接口
package com.springboot.demo.mybatis.service;import com.springboot.demo.mybatis.pojo.UserInfo;import java.util.List;public interface MyBatisUserInfoService {/***根据用户名称查询用户集合信息* @param userName:用户名* @return用户集合信息*/public List<UserInfo> findUserInfoByUserName(String userName);/*** 根据登录账户查询用户集合信息* @param loginAccount:登录账户* @return用户集合信息*/public List<UserInfo> findUserInfoByLoginAccount(String loginAccount);/*** 根据用户标识查询用户详情信息* @param userId:用户标识* @return 用户详情*/public UserInfo findUserInfoByUserId(int userId);/*** 保存用户信息* @param userInfo:用户信息*/public void saveUserInfo(UserInfo userInfo);/*** 更新用户信息* @param userInfo:用户信息*/public void updateUserInfo(UserInfo userInfo);/*** 更新用户状态* @param userInfo:更新状态用户*/public void updateUserState(UserInfo userInfo);}
业务逻辑层接口实现类
package com.springboot.demo.mybatis.service.impl;import com.springboot.demo.mybatis.dao.MyBatisUserInfoDao;import com.springboot.demo.mybatis.pojo.UserInfo;import com.springboot.demo.mybatis.service.MyBatisUserInfoService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class MyBatisUserInfoServiceImpl implements MyBatisUserInfoService {@Autowiredprivate MyBatisUserInfoDao userInfoDao;@Overridepublic List<UserInfo> findUserInfoByUserName(String userName) {return userInfoDao.findUserInfoByUserName(userName);}@Overridepublic List<UserInfo> findUserInfoByLoginAccount(String loginAccount) {return userInfoDao.findUserInfoByLoginAccount(loginAccount);}@Overridepublic UserInfo findUserInfoByUserId(int userId) {return userInfoDao.findUserInfoByUserId(userId);}@Overridepublic void saveUserInfo(UserInfo userInfo) {userInfoDao.saveUserInfo(userInfo);}@Overridepublic void updateUserInfo(UserInfo userInfo) {userInfoDao.updateUserInfo(userInfo);}@Overridepublic void updateUserState(UserInfo userInfo) {userInfoDao.updateUserState(userInfo);}}
在springboot整合mybatis的过程中,可以通过在数据访问层接口使用@Mapper注解的方式,将接口注入到spring容器中,也可以在springboot启动类上使用@MapperScan对数据访问层接口包路径进行扫描,包下所有接口注入到spring容器中。
@SpringBootApplication(exclude = MongoAutoConfiguration.class)@MapperScan("com.springboot.demo.mybatis.dao")public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}
测试用例
package com.springboot.demo;import com.springboot.demo.jdbcTemplate.pojo.SexEnum;import com.springboot.demo.mybatis.pojo.UserInfo;import com.springboot.demo.mybatis.service.MyBatisUserInfoService;import com.springboot.demo.utils.DatetimeUtils;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.Date;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTestpublic class MybatisTest {@Autowiredprivate MyBatisUserInfoService myBatisUserInfoServiceImpl;@Testpublic void testFindUserByUserName(){List<UserInfo> userInfos=myBatisUserInfoServiceImpl.findUserInfoByUserName("s");System.out.println("用户数量-----"+userInfos.size());for(UserInfo userInfo:userInfos){System.out.println("用户名分别为--------"+userInfo.getUserName());}}@Testpublic void testFindUserByLoginAccount(){List<UserInfo> userInfos=myBatisUserInfoServiceImpl.findUserInfoByLoginAccount("gas");System.out.println("用户数量-----"+userInfos.size());for(UserInfo userInfo:userInfos){System.out.println("用户名分别为--------"+userInfo.getUserName());}}@Testpublic void testFindUserByUserId(){UserInfo userInfo=myBatisUserInfoServiceImpl.findUserInfoByUserId(1);System.out.println("用户名为--------"+userInfo.getUserName());}@Testpublic void testSaveUser(){UserInfo userInfo=new UserInfo();userInfo.setUserName("testMybatis");userInfo.setLoginAccount("testMybatis");userInfo.setCreateDate(DatetimeUtils.dateFormatStr(new Date()));userInfo.setUpdateDate(DatetimeUtils.dateFormatStr(new Date()));userInfo.setUserAge(36);userInfo.setUserState("1");userInfo.setPassWord("123456");userInfo.setSexEnum(SexEnum.MALE);myBatisUserInfoServiceImpl.saveUserInfo(userInfo);}@Testpublic void testUpdateUserState(){UserInfo userInfo=myBatisUserInfoServiceImpl.findUserInfoByUserId(7);userInfo.setUserState("1");userInfo.setUpdateDate(DatetimeUtils.dateFormatStr(new Date()));myBatisUserInfoServiceImpl.updateUserState(userInfo);System.out.println("更新后的状态为------"+userInfo.getUserState()+",更新日期---------"+userInfo.getUpdateDate());}}




