提示:集成mybatis-plus要把mybatis坐标和mybatis-spring坐标去掉,避免冲突
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.woniu</groupId>
<artifactId>spring-mybatis-plus</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!--mybatisPlus 自动生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<!--mybatisPlus默认模板-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<build>
<!--配置maven编译插件-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source> <!-- 源代码使用的开发版本 -->
<target>1.8</target> <!-- 需要生成的目标class文件的编译版本 -->
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
MybatisPlusCodeUtils.java,运行后将帮助我们自动生成代码
package com.woniu.util;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
/**
* MyBatisPlusCode代码生成工具类
*/
public class MyBatisPlusCodeUtil {
private static final String XML_PATH="/resources/mapper/";
private static final String ENTITY_IGNORE_PREFIX="smbms_";
/**
* 启动方法
* @param args
*/
public static void main(String[] args) {
try {
generator("gp",//作者
"jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
"com.mysql.cj.jdbc.Driver",//数据库驱动
"root",//数据库帐号
"root",//数据库密码
"com.woniu",//项目最大的包名
"spring-mybatis-plus",//项目名或项目模块名
"smbms_user,smbms_role");//要操作的表名,多个表名用逗号隔开
System.out.println("mybaits代码生成成功");
}catch (Exception e){
e.printStackTrace();
}
}
/**
* Mybatis一键生成entity,mapper,mapper.xml,service,serviceImpl,controller
* @param author 开发人员
* @param url 驱动连接的URL
* @param driverName 驱动名称
* @param username 数据库连接用户名
* @param password 数据库连接密码
* @param parentPackage 父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
* @param projectModule 项目名
* @param tableName 表名,多个表名逗号隔开
*/
public static void generator(String author,
String url,
String driverName,
String username,
String password,
String parentPackage,
String projectModule,
String tableName) {
AutoGenerator mpg = new AutoGenerator();
mpg.setGlobalConfig(globalConfig(author,projectModule));//全局配置
mpg.setDataSource(dataSourceConfig(url,driverName,username,password));//数据源配置
mpg.setPackageInfo(packageConfig(parentPackage));//包配置
mpg.setStrategy(strategyConfig(tableName));//策略配置
mpg.setTemplate(templateConfig());//模板配置
mpg.execute();
}
/**
* 全局配置
* @param author 开发人员
* @param projectModule 项目模块名
* @return GlobalConfig
*/
private static GlobalConfig globalConfig (String author, String projectModule) {
String projectPath = System.getProperty("user.dir");
GlobalConfig globalConfig = new GlobalConfig();
// 文件输出目录
//如果要在项目中生成用这个
// globalConfig.setOutputDir(projectPath + "\\src\\main\\java");
//如果要在模块中生成用这个
globalConfig.setOutputDir(projectPath + "\\" + projectModule + "\\src\\main\\java");
// 添加作者信息
globalConfig.setAuthor(author);
//设置时间类型为Date
globalConfig.setDateType(DateType.TIME_PACK);
// 生成文件后不默认打开
globalConfig.setOpen(false);
// 自定义service生成的名字,用于删除自动生成的I前缀
globalConfig.setServiceName("%sService");
// 自定义dao生成的名字,如果不指定默认为%sMapper
//globalConfig.setMapperName("%sDao");
return globalConfig;
}
/**
* 数据源设置
* @param url 驱动连接的URL
* @param driverName 驱动名称
* @param username 数据库连接用户名
* @param password 数据库连接密码
* @return DataSourceConfig
*/
private static DataSourceConfig dataSourceConfig (String url,
String driverName,
String username,
String password) {
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl(url);
dataSourceConfig.setDriverName(driverName);
dataSourceConfig.setUsername(username);
dataSourceConfig.setPassword(password);
return dataSourceConfig;
}
/**
* 包配置
* @param parentPackage 父包名,最大的包名
* @return PackageConfig
*/
private static PackageConfig packageConfig(String parentPackage) {
// 包配置
PackageConfig packageConfig = new PackageConfig();
// 包名
packageConfig.setParent(parentPackage);
//各个包目录起名
packageConfig.setEntity("entity");
packageConfig.setMapper("mapper");
packageConfig.setXml("mapper");
packageConfig.setService("service");
return packageConfig;
}
/**
* 策略配置
* @param tableName 数据库表名称,多个用英文逗号隔开
* @return StrategyConfig
*/
private static StrategyConfig strategyConfig (String tableName) {
// 策略配置
StrategyConfig strategyConfig = new StrategyConfig();
// 表名驼峰命名
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
// 字段驼峰命名
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
// 设置去除表前缀
strategyConfig.setTablePrefix(ENTITY_IGNORE_PREFIX);
// 设置实体类的lombok(此处看个人使用,如果不使用lombok,那么在生成之后再去添加构造方法等等)
strategyConfig.setEntityLombokModel(true);
//strategyConfig.setRestControllerStyle(true);
// scanner("表名,多个英文逗号分割").split(",")
strategyConfig.setInclude((tableName).split(","));
// 驼峰生成方法
strategyConfig.setControllerMappingHyphenStyle(true);
return strategyConfig;
}
/**
* 模板配置项
* @return TemplateConfig
*/
private static TemplateConfig templateConfig () {
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(ConstVal.TEMPLATE_XML);
//不生成mapper.xml文件
templateConfig.setXml(null);
//不生成service
//templateConfig.setService(null);
//不生成service实现类
//templateConfig.setServiceImpl(null);
//不生成controller类
templateConfig.setController(null);
return templateConfig;
}
}
生成的实体类:
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("smbms_role")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 角色编码
*/
@TableField("roleCode")
private String roleCode;
/**
* 角色名称
*/
@TableField("roleName")
private String roleName;
...
}
生成 Mapper接口
public interface RoleMapper extends BaseMapper<Role> {
}
因为mapper接口继承了mybatis-plus 的接口,因此我们的接口中自然 “天生就有” 若干方法
mybatis-plus和spring整合步骤同spring整合mybatis,唯一的不同就是将Spring的SqlSessionFactoryBean,改为mybatis plus的MybatisSqlSessionFactoryBean对象
JdbcConfig.java
package com.woniu.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@PropertySource("db.properties")
public class JdbcConfig {
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.user}")
private String username;
@Value("${jdbc.pass}")
private String password;
//@Bean注解 调用此方法,将返回值对象以方法名为id存入spring容器中
@Bean("dataSource")
public DataSource createDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(4);
dataSource.setMaxActive(100);
dataSource.setMinIdle(2);
return dataSource;
}
}
完整的SpringConfiguration配置:
package com.woniu.config;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import javax.sql.DataSource;
import java.io.IOException;
/**
* Spring配置类
*/
@Configuration
@ComponentScan(basePackages = {"com.woniu"}) //扫描有spring注解的类所在的包
@Import(JdbcConfig.class)
public class SpringConfiguration {
@Bean("sqlSessionFactoryBean")
public MybatisSqlSessionFactoryBean createMybatisSqlSessionFactoryBean(DataSource dataSource) throws IOException {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
//向sqlSessionfactoryBean注入数据源
factoryBean.setDataSource(dataSource);
//设置类型别名
factoryBean.setTypeAliasesPackage("com.woniu.entity");
//将mybatis配置文件交给sqlSessionFactoryBean管理
//factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
//设置sqlMapper XML映射文件的路径
ResourcePatternResolver loader = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(
loader.getResources("classpath:com/woniu/mapper/*.xml"));
return factoryBean;
}
//用于生成Mapper接口代理子类对象,并存入spring容器中
@Bean
public MapperScannerConfigurer getMapperScannerConfigurer() {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
configurer.setBasePackage("com.woniu.mapper");
return configurer;
}
}
通用Service CRUD 封装get 查询单行
remove 删除``list 查询集合
page 分页
前缀命名方式区分 Mapper
selectList()方法需要传一个条件构造器,如果要查询所有,设置null即可
public interface UserService extends IService<User> {
List<User> findUserList();
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper userMapper;
//查询所有用户列表
public List<User> findUserList() {
return userMapper.selectList(null);
}
}
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= SpringConfiguration.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testFindUserList(){
// List<User> userList = userService.list(); //IService自带
List<User> userList = userService.findUserList(); //自定义业务方法
for (User user : userList) {
System.out.println(user);
}
}
}
测试类:
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper userMapper;
//根据主键查询
public User selectById(Integer id) {
return userMapper.selectById(id);
}
}
@Test
public void testGetById(){
User user = userService.getById(1); //IService自带
User user = userService.selectById(1);//自定义业务方法
System.out.println(user);
}
@Test
public void testSelectByIds(){
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
List<User> userList = userService.listByIds(ids);
for (User user : userList) {
System.out.println(user);
}
}
要想为sql语句添加where条件,需要使用mybatis plus的条件构造器对象Wrapper,该对象中提供了对sql条件操作的各种方法:
官网:https://baomidou.com/pages/10c804/#alleq
示例:查询性别为‘男’,根据生日降序排列
@Test
public void testSelectUserByCondition(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","熊");
queryWrapper.or().eq("gender",1);
queryWrapper.orderByDesc("birthday");
List<User> userList = userService.list(queryWrapper);
for (User user : userList) {
System.out.println(user);
}
}
SELECT id,userCode,user_name,userPassword,gender,birthday,phone,address,roleid,createdBy,creationDate,modifyBy,modifyDate,IDPICPATH FROM smbms_user WHERE (user_name LIKE ? OR gender = ?) ORDER BY birthday DESC
MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
在spring的配置类中添加mybatis plus的分页插件拦截器
@Bean("sqlSessionFactoryBean")
public MybatisSqlSessionFactoryBean createMybatisSqlSessionFactoryBean(DataSource dataSource) throws IOException {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
//向sqlSessionfactoryBean注入数据源
factoryBean.setDataSource(dataSource);
//设置类型别名
factoryBean.setTypeAliasesPackage("com.woniu.entity");
//将mybatis配置文件交给sqlSessionFactoryBean管理
//factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
//设置sqlMapper XML映射文件的路径
ResourcePatternResolver loader = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(
loader.getResources("classpath:com/woniu/mapper/*.xml"));
//配置mybatis plus分页插件
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//设置分页拦截器,指定 mysql数据库类型
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
factoryBean.setPlugins(mybatisPlusInterceptor);
return factoryBean;
}
业务层编写分页代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper userMapper;
//获取分页数据
public IPage<User> getPageInfo(int pageNum, int pageSize) {
IPage<User> page = new Page<>(pageNum,pageSize);
//参数1为分页参数,参数2为分页查询条件
IPage<User> pageInfo = userMapper.selectPage(page,null);
return pageInfo;
}
}
测试业务类,获取分页数据
@Test
public void testGetByPage(){
IPage<User> userPage = new Page<>(1,3);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//第二个参数为查询条件
IPage<User> page = userService.page(userPage,queryWrapper); //使用IService中的方法
//IPage<User> page = userService.getPageInfo(1,3);
for (User user : page.getRecords()) {
System.out.println(user);
}
System.out.println("page.getPages():"+page.getPages());
System.out.println("page.getCurrent():"+page.getCurrent());
System.out.println("page.getSize():"+page.getSize());
System.out.println("page.getTotal():"+page.getTotal());
}
逻辑条件的组合大体分为 2 种:
单纯的 ...与...与...
/ ...或...或...
与或
混用,由于 或
的优先级更高,因此可以改造成 (... and ...) or (... and ...) or ...
这样的统一形式。
...与...与...
情况:
如上例所示,QueryWrapper 的链式调用中,所表达的逻辑关系就是 and 的关系。
...或...或...
情况:
这种关系中,在 Wrapper 对象的链式调用中穿插调用 or()
方法即可。or()
方法前后的条件就是或的关系。
/**
* 条件查询
* @return
*/
public List<User> selectQuery(){
QueryWrapper<User> queryWrapper=new QueryWrapper<User>()
.like("username", "小") //根据姓名模糊查询
.or()
.eq("sex","男") //所有性别为男
.orderByDesc("money"); //根据金额倒序
return userMapper.selectList(queryWrapper);
}
与或混用的情况下,先要把你『心里』的 SQL 语句改造成通用形式:
(... and ...) or (... and ...) or ...
@Test
public void testDeleteById(){
boolean b = userService.removeById(46);
System.out.println(b);
}
@Test
public void testDeleteByIds(){
List<Integer> ids = new ArrayList<>();
ids.add(45);
ids.add(43);
userService.removeByIds(ids);
}
@Test
public void testDeleteByMap(){
Map<String,Object> map = new HashMap<>();
map.put("name","张三");
map.put("gender",1);
userService.removeByMap(map);
}
@Test
public void testDeleteByWrapper(){
Wrapper<User> wrapper = new QueryWrapper<User>()
.eq("name","张三")
.eq("gender",1);
userService.remove(wrapper);
}
@Test
public void testAdd(){
User user = new User();
user.setUserCode("Jack");
user.setUserName("杰克");
user.setUserPassword("111");
user.setGender(1);
user.setBirthday(LocalDateTime.of(2000,11,15,13,50));
user.setRoleid(1);
userService.save(user);
}
@Test
public void testUpdate(){
User user = new User();
user.setId(47);
user.setUserCode("Jenny");
user.setUserName("詹妮");
user.setUserPassword("999");
user.setGender(2);
user.setRoleid(2);
userService.updateById(user);
}
使用UpdateWrapper可以直接使用条件构造器封装设置的值,而无需new User对象进行设置
@Test
public void testUpdateByWrapper(){
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("userCode","Jenny");
updateWrapper.eq("id",47);
updateWrapper.like("userCode","e");
//User user = new User();
//user.setGender(1);
//user.setRoleid(1);
//userService.update(user,updateWrapper);
userService.update(updateWrapper);
}
${ew.customSqlSegment} 不是必须写的。当你自定义方法还想用条件构造器Wrapper的时候,才需要这样写。可以使用mybatis原生的方式。
UserMapper.xml
<mapper namespace="com.woniu.mapper.UserMapper">
<resultMap id="userResultMap" type="User">
<id column="id" property="id" />
<result column="userCode" property="userCode" />
<result column="user_name" property="userName" />
<result column="userPassword" property="userPassword" />
<result column="gender" property="gender" />
<result column="birthday" property="birthday" />
<result column="roleid" property="roleid" />
<association column="roleid" property="role" javaType="Role">
<id column="roleid" property="id" />
<result column="roleName" property="roleName" />
</association>
</resultMap>
<!--mybatis-plus多表联合查询,带上${ew.customSqlSegment就可以实现查询-->
<select id="queryUserAndRoleName" resultMap="userResultMap">
select u.id,u.userCode,u.user_name,u.userPassword,u.gender,u.birthday,u.roleid,r.roleName
from smbms_user u inner join smbms_role r on u.roleid=r.id
<!--<where>-->
<!-- <if test="user.userName != null and user.userName!=''">-->
<!-- u.user_name like concat('%',#{user.userName},'%')-->
<!-- </if>-->
<!--</where>-->
${ew.customSqlSegment}
</select>
</mapper>
UserMapper.java
public interface UserMapper extends BaseMapper<User> {
IPage<User> queryUserAndRoleName(@Param("page") IPage<User> page,
@Param(Constants.WRAPPER) QueryWrapper<User> wrapper);
}
UserService.java
public interface UserService extends IService<User> {
IPage<User> getUserAndRoleName(int pageNum, int pageSize, QueryWrapper<User> wrapper);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
//分页条件查询
public IPage<User> getUserAndRoleName(int pageNum, int pageSize, QueryWrapper<User> wrapper) {
//开启分页
Page<User> page = new Page<>(pageNum,pageSize);
//将获取到的 page对象和前台传递的参数传递到自己写的sql查询方法
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("user_name","熊");
//注意返回值类型一定要是IPage<User>
IPage<User> pageInfo = userMapper.queryUserAndRoleName(page, wrapper);
return pageInfo;
}
UserServiceTest测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class UserServiceTest {
@Test
public void testGetUserAndRoleName() {
User user = new User();
user.setUserName("熊");
IPage<User> page = userService.getUserAndRoleName(1, 3, user);
List<User> records = page.getRecords();
for (User record : records) {
System.out.println(record);
}
}
}