SSM Chapter 13 MyBatis-Plus

SSM Chapter 13 MyBatis-Plus笔记

本章目标

前言:

MyBatis在持久层框架中还是比较火的,一般项目都是基于ssm。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但是操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。mybatis-plus就很好的解决了这个问题。

1. MyBatis-Plus简介:

在这里插入图片描述
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

官网地址:https://mp.baomidou.com/

愿景

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
在这里插入图片描述
特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

返回顶部

2. Spring整合MyBatis-Plus

正如官网所说:MyBatis-Plus在MyBatis的基础上只做增强不做改变,因此与Spring的整合也非常简单。只需把MyBatis的依赖换成MyBatis-Plus的依赖,再把SqlSessionFactory换成MyBatis-Plus的SqlSessionFactory即可。

现有一张 User 表,其表结构如下:

idnameageemail
1Jone18test1@baomidou.com
2Jack20test2@baomidou.com
3Tom28test3@baomidou.com
4Sandy21test4@baomidou.com
5Billie24test5@baomidou.com

创建数据库mpdemo,其对应的数据库 Schema 脚本如下:

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

其对应的数据库 Data 脚本如下:

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

以此表为例,演示Spring与MyBatis-Plus的集成,具体操作如下:

安装:

<!--spring-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<!--mp-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.3.0</version>
</dependency>

<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<!--slf4j-nop或者logback-classic任选其一即可-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>1.7.29</version>
</dependency>

全新的 MyBatis-Plus 3.0 版本基于 JDK8,提供了 lambda 形式的调用,所以安装集成 MP3.0 要求如下:

  • JDK 8+
  • Maven or Gradle

JDK7 以及下的请参考 MP2.0 版本,地址:2.0 文档

备注:引入 MyBatis-Plus 之后请不要再次引入 MyBatis 以及 MyBatis-Spring,以避免因版本差异导致的问题。

配置:

  • 配置 MapperScan

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.smbms.mapper"/>
    </bean>
    
  • 调整 SqlSessionFactory 为 MyBatis-Plus 的 SqlSessionFactory

    <!--省略数据源的配置-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath*:mappers/**/*.xml"/>
        <property name="typeAliasesPackage" value="cn.smbms.pojo"/>
        <property name="configuration" ref="configuration"/>
    </bean>
    
    
    <bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
        <!--将java中的驼峰命名法的属性自动映射为数据库表中带下划线的列名:
        如:java:userCode MySQL:user_code,在mybatis中为false,
        但是在mybatis-plus中默认为true,因此需要修改为false-->
        <property name="mapUnderscoreToCamelCase" value="false"/>
        <!--配置日志输出-->
        <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
    </bean>
    

编码:

编写实体类User.java,代码如下:

public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    //省略getter setter 以及 toString
}    

编写Mapper接口UserMapper.java,代码如下:

//在对应的Mapper上面继承基本的接口 BaseMapper
public interface UserMapper extends BaseMapper<User> {
    // 所有的CRUD操作都已经编写完成了
}

测试:

添加测试类,进行功能测试,代码如下:

@ContextConfiguration("classpath:applicationContext.xml")
@RunWith(SpringRunner.class)
public class TestUserMapper {
    @Autowired
    UserMapper userMapper;

    @Test
    public void testSelectList(){
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }
}

UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件

控制台输出如图所示:
在这里插入图片描述

小结:

通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!

从以上步骤中,我们可以看到集成MyBatis-Plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。

但 MyBatis-Plus 的强大远不止这些功能,想要详细了解 MyBatis-Plus 的强大功能?可以参考官网:https://mp.baomidou.com/

返回顶部

3. ActiveRecord

ActioveRecord简介

ActiveRecord(简称AR)一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以我们也在 AR 道路上进行了一定的探索,喜欢大家能够喜欢。

什么是ActiveRecord?

ActiveRecord也属于ORM(对象关系映射)层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而 且简洁易懂。

ActiveRecord的主要思想是:

  • 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段 在类中都有相应的Field;
  • ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;
  • ActiveRecord是一种领域模型(Domain Model),封装了部分业务逻辑;

ActiveRecord适用场合

  1. 业务逻辑比较简单,当你的类基本上和数据库中的表一一对应时, ActiveRecord是非常方便的,即你的业务逻辑大多数是对单表操作;
  2. 当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script),把跨表事务提升到事务脚本中;
  3. ActiveRecord最大优点是简单, 直观。 一个类就包括了数据访问和业务逻辑. 如果配合代码生成器使用就更方便了;这些优点使ActiveRecord特别适合WEB快速开发。

ActiveRecord不适合于:

  1. ActiveRecord虽然有业务逻辑, 但基本上都是基于单表的. 跨表逻辑一般会放到当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script)中. 如果对象间的关联越来越多, 你的事务脚本越来越庞大, 重复的代码越来越多, 你就要考虑Domain Model + O/R Mapper了;
  2. ActiveRecord保存了数据, 使它有时候看上去像数据传输对象(DTO). 但是ActiveRecord有数据库访问能力, 不要把它当DTO用. 尤其在跨越进程边界调用的时候, 不能传递ActiveRecord对象。

开启AR之旅

在MP中,开启AR非常简单,只需要将实体对象继承Model即可,同时将该实体注入到Spring的Bean容器中。

@Component
public class User extends Model<User> {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    //省略getter setter 以及toString()
}    

根据主键查询

代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestAR {
    @Autowired
    User user;
   	@Test
    public void testSelectById(){
        user.setId(2L);
        user = this.user.selectById();
        System.out.println(user);
    }
} 

新增数据

代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestAR {
    @Autowired
    User user;
    @Test
    public void testInsert(){
        user.setName("Jerry");
        user.setAge(31);
        user.setEmail("jerry@test.com");
        boolean insert = user.insert();
        System.out.println(insert);
    }
}    

更新操作

代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {
    @Autowired
    User user;
    @Test
    public void testUpdate(){
        user.setId(6L);
        user.setName("Frank");
        user.setAge(28);
        boolean update = user.updateById();
        System.out.println(update);
    }
} 

删除操作

代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {
    @Autowired
    User user;
    @Test
    public void testDelete(){
//        user.setId(6L);
        boolean delete = user.deleteById(6L);
        System.out.println(delete);
    }
} 

根据条件查询

代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {
    @Autowired
    User user;
    @Test
    public void testGetByName(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        QueryWrapper<User> queryWrapper = wrapper.like("name", "o");
        List<User> list = user.selectList(queryWrapper);
        list.forEach(System.out::println);
    }
} 

4. SpringMVC+Spring+MyBatis-Plus

需求:Spring整合SpringMVC,以及MyBatis-Plus改造超市订单管理系统

操作步骤如下:

安装:

pom.xml文件中添加如下依赖:

<!--Spring start-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.1.RELEASE</version>
    <scope>test</scope>
</dependency>
<!--Spring end-->

<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>
<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
    <scope>runtime</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.3.0</version>
</dependency>
<!--junit-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<!--slf4j-nop或者logback-classic任选其一即可-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>1.7.29</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
</dependency>
<!--logback-classic -->
<!--<dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>-->
<!--jstl-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<!--jackson-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>
<!-- commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

配置:

  • applicationContext.xml配置如下:

    <context:property-placeholder location="classpath:database.properties"/>
    <!--数据源的配置-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${jdbc_url}" />
        <property name="username" value="${jdbc_user}" />
        <property name="password" value="${jdbc_password}" />
    
        <property name="filters" value="stat" />
    
        <property name="maxActive" value="20" />
        <property name="initialSize" value="1" />
        <property name="maxWait" value="60000" />
        <property name="minIdle" value="1" />
    
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <property name="minEvictableIdleTimeMillis" value="300000" />
    
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
    
        <property name="poolPreparedStatements" value="true" />
        <property name="maxOpenPreparedStatements" value="20" />
    
        <property name="asyncInit" value="true" />
    </bean>
    
    
    
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath*:mappers/**/*.xml"/>
        <property name="typeAliasesPackage" value="cn.smbms.pojo"/>
        <property name="configuration" ref="configuration"/>
    </bean>
    
    
    <bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
        <!--将java中的驼峰命名法的属性自动映射为数据库表中带下划线的列名:
        如:java:userCode MySQL:user_code,在mybatis中为false,
        但是在mybatis-plus中默认为true,因此需要修改为false-->
        <property name="mapUnderscoreToCamelCase" value="false"/>
        <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
    </bean>
    
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.smbms.mapper"/>
    </bean>
    
    <context:component-scan base-package="cn.smbms.service"/>
    <!--省略事务的配置-->
    
  • database.properties配置如下:

    jdbc_url=jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8&useSSL=false
    jdbc_user=root
    jdbc_password=root
    
  • springmvc-servlet.xml配置如下:

    <context:component-scan base-package="cn.smbms.controller"/>
    <!--过滤静态资源-->
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
        <mvc:message-converters>
            <!--引用jackson的消息转换器 解决json字符串中的日期格式问题-->
            <ref bean="jackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
    
    <!--配置jackson日期格式问题-->
    <bean id="jackson2HttpMessageConverter"
          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="objectMapper" ref="objectMapper"/>
        <property name="supportedMediaTypes">
            <list>
                <value>text/html</value>
                <value>application/json</value>
                <value>application/xml</value>
            </list>
         </property>
    </bean>
    
    <bean id="objectMapper"
          class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
          p:indentOutput="true"
          p:simpleDateFormat="yyyy-MM-dd HH:mm:ss"/>
    <!--jackson end-->
    
    <!--配置多视图解析器-->
    <bean id="contentNegotiationManager"
          class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            <value>
                json=application/json
                xml=application/xml
                html=text/html
            </value>
        </property>
    </bean>
    
    <mvc:view-resolvers>
        <mvc:jsp prefix="/WEB-INF/jsp/" suffix=".jsp"/>
    </mvc:view-resolvers>
    
    <!--文件上传解析器-->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
        <property name="maxUploadSize" value="5000000"/>
    </bean>
    <!--省略拦截器的配置-->
    
  • web.xml配置如下:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <welcome-file-list>
        <welcome-file>/WEB-INF/jsp/login.jsp</welcome-file>
    </welcome-file-list>
    

编码:

编写实体类User.java,代码如下:

/**
 * 用户类
 */
@TableName("smbms_user")
public class User implements Serializable {
    private Integer id; //id
    private String userCode; //用户编码
    private String userName; //用户名称
    private String userPassword; //用户密码
    private Integer gender;  //性别
    private Date birthday;  //出生日期
    private String phone;   //电话
    private String address; //地址
    private Integer userRole;    //用户角色
    private Integer createdBy;   //创建者
    private Date creationDate; //创建时间
    private Integer modifyBy;     //更新者
    private Date modifyDate;   //更新时间
    @TableField(exist = false)
    private Integer age;//年龄
    @TableField(exist = false)
    private String userRoleName;    //用户角色名称
    /**证件照*/
    private String idPicPath;
    private String workPicPath;
    //省略其他属性的getter,setter 以及toString()
    public Integer getAge() {
//        Date date = new Date();
//        Integer age = date.getYear()-birthday.getYear();
        //使用默认时区获取当前的日历
        Calendar now = Calendar.getInstance();
        Calendar birthday = Calendar.getInstance();
        //设置日历为生日的日期
        birthday.setTime(this.birthday);
        //获取现在的年份-生日的年份
        return now.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
    }
}

编写Mapper接口UserMapper.java,代码如下:

public interface UserMapper extends BaseMapper<User> {
    
}

编写Service接口UserService.java,代码如下:

public interface UserService extends IService<User> {
    
}

编写Service接口的实现类UserServiceImpl.java,代码如下:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
	
}

编写Controller类UserController.java,代码如下:

@Controller
public class UserController {
    @RequestMapping("/login")
    public String login(){
        return "login";
    }
    @Autowired
    private UserService userService;
    @RequestMapping("/doLogin")
    public String doLogin(@RequestParam String userCode,
                          @RequestParam String userPassword,
                          HttpServletRequest request, HttpSession session){
        User user = userService.getOne(new QueryWrapper<User>().eq("userCode",userCode));
        if (user != null && userPassword.equals(user.getUserPassword())){
            session.setAttribute(Constants.USER_SESSION,user);
            return "redirect:main";
        }
        request.setAttribute("error","用户名或者密码有误!!");
        return "login";
    }
    
    @RequestMapping("/main")
    public String main(){
        return "frame";
    }
    //省略其他代码
    
}

测试:

pom.xml文件中添加tomcat插件,代码如下:

<build>
    <plugins>
         <!--定义tomcat插件-->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <!--端口号-->
                <port>8888</port>
                <!-- 路径 -->
                <path>/</path>
            </configuration>
        </plugin>
    </plugins>
</build>

使用maven插件的方式运行,加入以下命令:

clean tomcat7:run

浏览器中输入路径:http://localhost:8888/,效果如图所示:
在这里插入图片描述
测试登录功能,如果所示:
在这里插入图片描述
返回顶部

5. SpringBoot整合MyBatis-Plus

以数据库mpdemo中的表User为例,演示SpringBoot整合MyBatis-plus,具体操作如下:

首先,创建一个空的 Spring Boot 工程

可以使用 Spring Initializer 快速初始化一个 Spring Boot 工程

idea中使用Spring Initializer初始化一个工程,如图所示:
在这里插入图片描述

安装:

引入 Spring Boot Starter 父工程:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
    <relativePath/>
</parent>

引入 spring-boot-starterspring-boot-starter-testmybatis-plus-boot-starterlombokmysql 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

配置:

application.yml 配置文件中添加 MySQL数据库的相关配置:

# DataSource Config
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/mpdemo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: root

# MyBatis-Plus Config 
# 注意MP寻找默认mapper文件的目录是resources下的mapper目录下的xml文件
# 因此如果使用mapper文件 则需要在resources目录下创建mapper目录,
# 并添加对应的mapper文件
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: cn.smbms.pojo

在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

@SpringBootApplication
@MapperScan("cn.smbms.mapper")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

编码:

编写实体类 User.java(注意:此处使用了 Lombok 简化代码):

@Data
public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

编写Mapper接口UserMapper.java

public interface UserMapper extends BaseMapper<User> {

}

测试:

添加测试类,进行功能测试:

@SpringBootTest
@RunWith(SpringRunner.class)
class DemoApplicationTests {

    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() {
        List<User> userList = userMapper.selectList(null);
        Assert.assertEquals(5,userList.size());
        userList.forEach(System.out::println);
    }
}

控制台输出:
在这里插入图片描述
返回顶部

6. Thymeleaf模板引擎

Thymeleaf 是什么

Thymeleaf(正确读音:/ˈtaɪmˌlɪːf/)是一个模板引擎,主要用于编写动态页面。

注意:Thymeleaf:正确读音:/ˈtaɪmˌlɪːf/,可参考官网https://www.thymeleaf.org/faq.html#pronunciation

Thymeleaf的作用

–问题:动态页面技术已经有JSP,为什么还要用Thymeleaf?

主要原因包括以下几点:

  1. 使用模块引擎来编写动态页面,让开发人员无法在页面上编写 Java 代码,使得java代码和前端代码绝对的分离。
  2. SpringBoot默认整合Thymeleaf,不需要任何配置直接整合成功,打jar包发布不需要做任何配置。
  3. Thymeleaf相对于其他的模板引擎(如:Freemaker、velocity),有强大的工具支持。
  4. 相对于Jsp页面,执行效率高

总结:所有JSP可以使用的地方,Thymeleaf都可以使用,并根据Thymeleaf的优势,可以得出结论:Thymeleaf的作用就是取代JSP。

Thymeleaf的官网:https://www.thymeleaf.org/

官方文档译文:https://raledong.gitbooks.io/using-thymeleaf/content/

返回顶部

7. SpringBoot+MyBatis-Plus+Thymeleaf

需求:SpringBoot整合MyBatis-Plus,以及使用thymeleaf模板引擎改造超市订单管理系统

操作步骤如下:

安装:

引入 Spring Boot Starter 父工程:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
    <relativePath/>
</parent>

引入 spring-boot-starter-webspring-boot-devtoolsspring-boot-starter-thymeleafspring-boot-starter-testmybatis-plus-boot-startermysql 、依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>true</scope>
    <optional>true</optional>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>

配置:

application.yml 配置文件中添加 MySQL数据库的相关配置:

# DataSource Config
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: root

# MyBatis-Plus Config 
# 注意MP寻找默认mapper文件的目录是resources下的mapper目录下的xml文件
# 因此如果使用mapper文件 则需要在resources目录下创建mapper目录,
# 并添加对应的mapper文件
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false
  type-aliases-package: cn.smbms.pojo

备注:SpringBoot默认支持的模板引擎是Thymeleaf,因此不用配置,但需要将Thymeleaf的页面存放在templates文件夹下,并且页面的后缀为.html。

在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

@SpringBootApplication
@MapperScan("cn.smbms.mapper")
public class SmbmsSmpApplication {
    public static void main(String[] args) {
        SpringApplication.run(SmbmsSmpApplication.class, args);
    }
}

编码:

编写实体类 User.java,代码如下:

/**
 * 用户类
 */
@TableName("smbms_user")
public class User implements Serializable {
    private Integer id; //id
    private String userCode; //用户编码
    private String userName; //用户名称
    private String userPassword; //用户密码
    private Integer gender;  //性别
    private Date birthday;  //出生日期
    private String phone;   //电话
    private String address; //地址
    private Integer userRole;    //用户角色
    private Integer createdBy;   //创建者
    private Date creationDate; //创建时间
    private Integer modifyBy;     //更新者
    private Date modifyDate;   //更新时间
    @TableField(exist = false)
    private Integer age;//年龄
    @TableField(exist = false)
    private String userRoleName;    //用户角色名称
    /**证件照*/
    private String idPicPath;
    private String workPicPath;
	//省略toString以及其他属性的getter setter
    public Integer getAge() {
//        Date date = new Date();
//        Integer age = date.getYear()-birthday.getYear();
        //使用默认时区获取当前的日历
        Calendar now = Calendar.getInstance();
        Calendar birthday = Calendar.getInstance();
        //设置日历为生日的日期
        birthday.setTime(this.birthday);
        //获取现在的年份-生日的年份
        return now.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
    }
}

编写Mapper接口UserMapper.java,代码如下:

public interface UserMapper extends BaseMapper<User> {
    
}

编写Service接口UserService.java

public interface UserService extends IService<User> {
    
}

编写Service接口的实现类UserServiceImpl.java,代码如下:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
	
}

编写Controller类UserController.java,代码如下:

@Controller
public class UserController {
    @RequestMapping("/")
    public String login(){
        return "login";
    }
    @Autowired
    private UserService userService;
    @RequestMapping("/doLogin")
    public String doLogin(@RequestParam String userCode,
                          @RequestParam String userPassword,
                          HttpServletRequest request, HttpSession session){
        User user = userService.getOne(new QueryWrapper<User>().eq("userCode",userCode));
        if (user != null && userPassword.equals(user.getUserPassword())){
            session.setAttribute(Constants.USER_SESSION,user);
            return "redirect:/sys/main";
        }
        request.setAttribute("error","用户名或者密码有误!!");
        return "login";
    }
    
    @RequestMapping("/sys/main")
    public String main(){
        return "frame";
    }
    //省略其他代码
    
}

编写Interceptor类SysInterceptor.java,代码如下:

public class SysInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getSession().getAttribute("userSession") != null) {
            //成功
            return true;
        }else{
            System.out.println(request.getContextPath());
            System.out.println("preHandle=====>");
            response.sendRedirect("/login");
            return false;
        }
    }
}

编写配置类webConfig.java,代码如下:

/**
 * 和springmvc的webmvc拦截配置一样
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SysInterceptor()).addPathPatterns("/sys/**");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/static/");
        registry.addResourceHandler("/templates/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/templates/");
    }
}

编写前端页面,将之前的login.jsp文件拷贝到resources目录下的templates目录中,并改造为login.html,代码如下:

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head lang="en">
    <meta charset="UTF-8">
    <title>系统登录 - 超市订单管理系统</title>
    <!--静态文件直接使用绝对路径引用文件所在的目录即可
		或者使用相对路径也可以-->
    <link type="text/css" rel="stylesheet"
          href="/css/style.css" />
    <script type="text/javascript">
	/* if(top.location!=self.location){
	      top.location=self.location;
	 } */
    </script>
</head>
<body class="login_bg">
    <section class="loginBox">
        <header class="loginHeader">
            <h1>超市订单管理系统</h1>
        </header>
        <section class="loginCont">
	        <form class="loginForm" action="/doLogin"
                  name="actionForm" id="actionForm"  method="post" >
                <!--使用th:text属性输出,其他属性请参考官网:-->
				<div class="info" th:text="${error}"></div>
				<div class="inputbox">
                    <label for="user">用户名:</label>
					<input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
				</div>	
				<div class="inputbox">
                    <label for="mima">密码:</label>
                    <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
                </div>	
				<div class="subBtn">
					
                    <input type="submit" value="登录"/>
                    <input type="reset" value="重置"/>
                </div>	
			</form>
        </section>
    </section>
</body>
</html>

注意,必须加上命名空间xmlns:th=“http://www.w3.org/1999/xhtml”,否则Thymeleaf的自定义标签没有提示。

可以使用th:text属性输出表达式中的内容,其他属性请参考官网:https://www.thymeleaf.org/

改造frame.jsp,修改文件名为frame.html,内容如下:

<div th:insert="common/head" xmlns:th="http://www.w3.org/1999/xhtml"/>
<div class="right" xmlns:th="http://www.w3.org/1999/xhtml">
        <img class="wColck" src="/images/clock.jpg" alt=""/>
        <div class="wFont">
            <h2 th:text="${session.userSession.userName }"></h2>
            <p>欢迎来到超市订单管理系统!</p>
        </div>
    </div>
</section>
<div th:insert="common/foot" xmlns:th="http://www.w3.org/1999/xhtml"/>

改造common目录下的head.jsp,修改文件名为head.html,内容如下:

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head lang="en">
    <meta charset="UTF-8">
    <title>超市订单管理系统</title>
    <link type="text/css" rel="stylesheet" href="/css/style.css" />
    <link type="text/css" rel="stylesheet" href="/css/public.css" />
</head>
<body>
<!--头部-->
    <header class="publicHeader">
        <h1>超市订单管理系统</h1>
        <div class="publicHeaderR">
            <p><span>下午好!</span><span style="color: #fff21b" th:text="${session.userSession.userName}"> </span> , 欢迎你!</p>
            <a href="logout">退出</a>
        </div>
    </header>
<!--时间-->
    <section class="publicTime">
        <span id="time">2015年1月1日 11:11  星期一</span>
        <a href="#">温馨提示:为了能正常浏览,请使用高版本浏览器!(IE10+)</a>
    </section>
 <!--主体内容-->
 <section class="publicMian ">
     <div class="left">
         <h2 class="leftH2"><span class="span1"></span>功能列表 <span></span></h2>
         <nav>
             <!--省略其他内容-->
         </nav>
     </div>

改造common目录下的foot.jsp,修改文件名为foot.html,内容如下:

<footer class="footer">
    版权归北大青鸟
</footer>
<script type="text/javascript" src="js/time.js"/></script>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="js/common.js"></script>
<script type="text/javascript" src="calendar/WdatePicker.js"></script>
</body>
</html>

将静态文件直接复制到static目录下即可,如图所示:
在这里插入图片描述
问题:

  1. 为什么thymeleaf页面放在templates文件夹里面,并且后缀要是.html呢?

    答:SpringBoot框架会将内置支持的功能组件放在spring-boot-autoconfigure-2.2.6.RELEASE.jar 包下,而 Thymeleaf 框架就是内置支持的。所以在这个包里面可以找对应的自动配置代码,如图:在这里插入图片描述
    如果找默认的属性配置应该找XxxxProperties类,如上图,Thymeleaf模板的前后缀如下:

    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    

    所以Thymeleaf的页面存放在templates文件夹中,并且页面的后缀为.html。

  2. 项目结构中还有一个static文件夹,是用来放什么的呢?

    答:用来存放静态资源(css、js、image等等),SpringBoot将通用的Web模块的参数放在Web分包,具体资源配置信息放置在ResourceProperties配置类中。如图所示:在这里插入图片描述
    因此静态资源的默认路径为:
    在这里插入图片描述

测试:

在SpringBoot的启动类上右击,选择Run Application,如图所示:
在这里插入图片描述
浏览器输入地址:http://localhost:8080/,如图所示:
在这里插入图片描述
测试登录功能,系统运行正常。

其他关于Thymeleaf的属性以及详解,可参考官网:https://www.thymeleaf.org/doc/articles/standarddialect5minutes.html

返回顶部

8. SpringMVC+Spring+MyBatis-Plus+Thymeleaf

需求说明:使用Spring+SpringMVC+MyBatis-Plus,以及Thymeleaf模板改造超市订单管理系统

关于SpringMVC中的Thymeleaf的配置,可参考官网:https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html

操作步骤如下:

安装:

pom.xml文件添加如下依赖:

<!--Spring start-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.1.RELEASE</version>
    <scope>test</scope>
</dependency>
<!--Spring end-->

<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>
<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
    <scope>runtime</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.3.0</version>
</dependency>
<!--junit-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<!--slf4j-nop或者logback-classic任选其一即可-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>1.7.25</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
</dependency>
<!--logback-classic -->
<!--<dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>-->
<!-- thymeleaf -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.11.RELEASE</version>
</dependency>

<!-- thymeleaf-spring5 -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    <version>3.0.11.RELEASE</version>
</dependency>
<!--jackson-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>
<!-- commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

配置:

  • applicationContext.xml以及database.properties配置跟第3小节中SpringMVC+Spring+MyBatis-Plus的配置一致,点此参考

  • springmvc-servlet.xml配置如下:

    <context:component-scan base-package="cn.smbms.controller"/>
    <!--配置静态资源的路径-->
    <mvc:default-servlet-handler/>
    <!--配置消息转换器-->
    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
        <mvc:message-converters>
            <ref bean="jackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
    
    <!--配置jackson的消息转换器-->
    <bean id="jackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="objectMapper" ref="objectMapper"/>
        <property name="supportedMediaTypes">
            <list>
                <value>text/html</value>
                <value>application/json</value>
                <value>application/xml</value>
            </list>
         </property>
    </bean>
    <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
          p:indentOutput="true"
          p:simpleDateFormat="yyyy-MM-dd"/>
    <!--配置多视图解析器-->
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            <value>
                html=text/html
                json=application/json
                xml=application/xml
            </value>
        </property>
    </bean>
    <!--配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
        <property name="maxUploadSize" value="5000000"/>
    </bean>
    <!--配置thymeleaf视图解析器分三步:-->
    <!--配置模板解析器-->
    <bean id="templateResolver"
          class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/WEB-INF/templates/" />
        <property name="suffix" value=".html" />
        <!-- HTML is the default value, added here for the sake of clarity.          -->
        <property name="templateMode" value="HTML" />
        <!-- Template cache is true by default. Set to false if you want             -->
        <!-- templates to be automatically updated when modified.                    -->
        <property name="cacheable" value="true" />
    </bean>
    <!--配置模板引擎-->
    <bean id="templateEngine"
          class="org.thymeleaf.spring5.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
        <!-- Enabling the SpringEL compiler with Spring 4.2.4 or newer can speed up  -->
        <!-- execution in most scenarios, but might be incompatible with specific    -->
        <!-- cases when expressions in one template are reused across different data -->
        <!-- ypes, so this flag is "false" by default for safer backwards            -->
        <!-- compatibility.                                                          -->
        <property name="enableSpringELCompiler" value="true" />
    </bean>
    <!--配置thymeleaf视图解析器-->
    <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="characterEncoding" value="utf-8"/>
    </bean>
    <!--省略拦截器的配置-->
    

    关于在Spring配置Thymeleaf模板引擎更加详细的说明,可参考官网:https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html

  • web.xml配置如下:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <welcome-file-list>
        <welcome-file>/WEB-INF/templates/login.html</welcome-file>
    </welcome-file-list>
    

编码:

编写实体类User.java,代码如下:

/**
 * 用户类
 */
@TableName("smbms_user")
public class User implements Serializable {
    private Integer id; //id
    private String userCode; //用户编码
    private String userName; //用户名称
    private String userPassword; //用户密码
    private Integer gender;  //性别
    private Date birthday;  //出生日期
    private String phone;   //电话
    private String address; //地址
    private Integer userRole;    //用户角色
    private Integer createdBy;   //创建者
    private Date creationDate; //创建时间
    private Integer modifyBy;     //更新者
    private Date modifyDate;   //更新时间
    @TableField(exist = false)
    private Integer age;//年龄
    @TableField(exist = false)
    private String userRoleName;    //用户角色名称
    /**证件照*/
    private String idPicPath;
    private String workPicPath;
    //省略其他属性的getter,setter 以及toString()
    public Integer getAge() {
//        Date date = new Date();
//        Integer age = date.getYear()-birthday.getYear();
        //使用默认时区获取当前的日历
        Calendar now = Calendar.getInstance();
        Calendar birthday = Calendar.getInstance();
        //设置日历为生日的日期
        birthday.setTime(this.birthday);
        //获取现在的年份-生日的年份
        return now.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
    }
}

编写Mapper接口UserMapper.java,代码如下:

public interface UserMapper extends BaseMapper<User> {
    
}

编写Service接口UserService.java,代码如下:

public interface UserService extends IService<User> {
    
}

编写Service接口的实现类UserServiceImpl.java,代码如下:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
	
}

编写Controller类UserController.java,代码如下:

@Controller
public class UserController {
    @RequestMapping("/login")
    public String login(){
        return "login";
    }
    @Autowired
    private UserService userService;
    @RequestMapping("/doLogin")
    public String doLogin(@RequestParam String userCode,
                          @RequestParam String userPassword,
                          HttpServletRequest request, HttpSession session){
        User user = userService.getOne(new QueryWrapper<User>().eq("userCode",userCode));
        if (user != null && userPassword.equals(user.getUserPassword())){
            session.setAttribute(Constants.USER_SESSION,user);
            return "redirect:main";
        }
        request.setAttribute("error","用户名或者密码有误!!");
        return "login";
    }
    
    @RequestMapping("/main")
    public String main(){
        return "frame";
    }
    //省略其他代码
    
}

在WEB-INF目录下创建templates目录,将之前在第6小节改造的前端页面复制过来,静态资源文件放在statics目录下,修改前端页面静态资源文件的位置。

测试:

pom.xml文件中添加jetty插件,代码如下:

<build>
    <plugins>
         <!--定义tomcat插件-->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <!--端口号-->
                <port>8888</port>
                <!-- 路径 -->
                <path>/</path>
            </configuration>
        </plugin>
    </plugins>
</build>

使用maven插件的方式运行,加入以下命令:

clean -Djetty.http.port=8888 jetty:run

浏览器中输入路径:http://localhost:8888/,测试登录功能,正常通过

返回顶部

9. MyBatis-Plus代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率

特别说明:

自定义模板有哪些可用参数?Github Gitee AbstractTemplateEngine 类中方法 getObjectMap 返回 objectMap 的所有值都可用。

使用教程:

添加依赖:

MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:

  • 添加 代码生成器 依赖:

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.3.0</version>
    </dependency>
    
  • 添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。

    Velocity(默认):

    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.2</version>
    </dependency>
    

    Freemarker:

    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.30</version>
    </dependency>
    

    注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。具体可参考官网:https://mp.baomidou.com/guide/generator.html#%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96

编写配置:

MyBatis-Plus 的代码生成器提供了大量的自定义参数供用户选择,能够满足绝大部分人的使用需求。

public static void main(String[] args) {
    // 代码生成器
    AutoGenerator mpg = new AutoGenerator();

    // 全局配置
    GlobalConfig gc = new GlobalConfig();
    //获得程序当前路径
    String projectPath = System.getProperty("user.dir");
    //生成文件的输出目录 若有模块 加入模块名
    gc.setOutputDir(projectPath + "/模块名/src/main/java");
    //开发人员
    gc.setAuthor("jack");
    //是否打开输出目录 默认值:true
    gc.setOpen(false);
    //开启 swagger2 模式
    // gc.setSwagger2(true); 实体属性 Swagger2 注解
    // %s 为占位符
    gc.setServiceName("%sService"); // 去IService的I前缀
    //时间类型对应策略
    gc.setDateType(DateType.ONLY_DATE);
    mpg.setGlobalConfig(gc);

    // 数据源配置
    DataSourceConfig dsc = new DataSourceConfig();
    dsc.setUrl("jdbc:mysql://localhost:3306/smbms?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8");
    // dsc.setSchemaName("public");
    dsc.setDriverName("com.mysql.jdbc.Driver");
    dsc.setUsername("root");
    dsc.setPassword("root");
    mpg.setDataSource(dsc);

    // 包配置
    PackageConfig pc = new PackageConfig();
    //父包模块名
    pc.setModuleName("user");
    pc.setParent("cn.smbms");
    pc.setEntity("pojo");
    pc.setMapper("mapper");
    pc.setService("service");
    pc.setController("controller");
    mpg.setPackageInfo(pc);

    // 策略配置
    StrategyConfig strategy = new StrategyConfig();
    // 表名生成策略
    strategy.setNaming(NamingStrategy.underline_to_camel);
    // 字段名生成策略
    strategy.setColumnNaming(NamingStrategy.underline_to_camel);
    //strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
    // 是否使用Lombok优化代码
    //strategy.setEntityLombokModel(true);
    //生成 @RestController 控制器
    strategy.setRestControllerStyle(true);
    // 公共父类
    //strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
    // 写于父类中的公共字段
    //strategy.setSuperEntityColumns("id");
    //需要包含的表名,允许正则表达式(与exclude二选一配置)
    strategy.setInclude("smbms_user");
    //驼峰转连字符 doLogin-->do_login
    strategy.setControllerMappingHyphenStyle(true);
    //表前缀
    strategy.setTablePrefix("smbms_");
    // 自动填充配置
    //new Date();
    TableFill creationDate = new TableFill("creationDate", FieldFill.INSERT);
    TableFill modifyDate = new TableFill("modifyDate",
                                         FieldFill.INSERT_UPDATE);
	//tableFillList 表填充字段
    strategy.setTableFillList(Arrays.asList(creationDate,modifyDate));
    mpg.setStrategy(strategy);
	//执行代码生成器
    mpg.execute();

}

配置说明以及其他配置请参考官网:https://mp.baomidou.com/config/generator-config.html#restcontrollerstyle

运行main方法,生成代码!!

返回顶部

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页

打赏作者

Frank-Hi

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值