sts mysql_STS中MyBatis的基本实现

本文采用的是《深浅spring boot 2.x》中第5章的例子,用一个接口实现对一个表项的读取。

数据库:mysql下建立user数据库,表名为t_usr

1. 数据源设置

在application.properties文件中加入数据源设置项:

#数据源设置(user是数据库的名称,一开始没有理解,写成了项目名称)

spring.datasource.url = jdbc:mysql://localhost:3306/user

spring.datasource.username = root

spring.datasource.password = 123456

spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver

spring.datasource.tomcat.max-idle = 10

spring.datasource.tomcat.max-active = 50

spring.datasource.tomcat.max-wait = 10000

spring.datasource.tomcat.initial-size = 5

这里使用了内置的mysql数据源,也可根据需要设置DBCP2

2. 相关依赖项的添加

在pom.xml中添加相关依赖项:

mysql

mysql-connector-java

org.springframework.boot

spring-boot-starter-jdbc

org.mybatis.spring.boot

mybatis-spring-boot-starter

1.3.2

org.mybatis

mybatis

3.4.4

3. 建立POJO类及其读取操作服务接口

3.1 建立一个User类:

@Alias(value = "user") //基于MyBatis的别名,为映射作准备

public class User {

private Long id = null;

private String userName = null;

private SexEnum sex = null; //性别枚举,这里需要使用typehandler进行转换(转换较多用于枚举)

private String note = null;

//**********setter 和 getter必须有,这里省略*****************************************

}

其中SexEnum是一个enum类型:

public enum SexEnum {

MALE(1, "男"), FEMALE(2, "女");

private int id;

private String name;

SexEnum(int id, String name){

this.id = id;

this.name = name;

}

public static SexEnum getEnumById(int id) {

for(SexEnum sex : SexEnum.values()) {

if(sex.getId() == id) {

return sex;

}

}

return null;

}

public void setId(int id) {

this.id = id;

}

public int getId() {

return id;

}

public void setName(String name) {

this.name = name;

}

public String getName() {

return name;

}

}

根据要求enum必须建立类型处理typeHandler

3.2 建立typeHandler

由于性别是enum类型,所以必须建立数据库表中数据类型与SexEnum类之间的转换关系:

//实现JDBC与SexEnum之间的转换关系

//声明JdbcType为整形

@MappedJdbcTypes(JdbcType.INTEGER)

//声明JavaType为SexEnum

@MappedTypes(value = SexEnum.class)

public class SexTypeHandler extends BaseTypeHandler {

//设置非空性别参数,为存储作准备

@Override

public void setNonNullParameter(PreparedStatement ps, int i, SexEnum parameter, JdbcType jdbcType)

throws SQLException {

ps.setInt(i, parameter.getId());

}

@Override

public SexEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {

int sex = rs.getInt(columnName);

if(sex != 1 && sex != 2) {

return null;

}

return SexEnum.getEnumById(sex);

}

//通过列标读取性别

@Override

public SexEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

int sex = rs.getInt(columnIndex);

if(sex != 1 && sex != 2) {

return null;

}

return SexEnum.getEnumById(sex);

}

//通过存储过程读取性别

@Override

public SexEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {

int sex = cs.getInt(columnIndex);

if(sex != 1 && sex != 2) {

return null;

}

return SexEnum.getEnumById(sex);

}

}

3.3 建立一个读取user表的接口(MyBatisUserDao ),该接口不实现,其实现交给mybatis的MapperFactoryBean自动生成

该接口由MapperFactoryBean自动实现。

这里的@Repository是必须的,但没有明白其具体含义

@Repository

public interface MyBatisUserDao {

public User getUser(Long id);

}

3.4 建立调用上面MyBatisUserDao的服务接口并实现之(服务类必须由接口实现)

(1)接口

import boat.db.pojo.*;

public interface MyBatisUserService {

public User getUser(Long id);

}

(2)服务实现

该服务调用由MapperFactoryBean实现的MyBatisUserDao.getUser(Long id)函数

@Service

public class MyBatisUserServiceImp implements MyBatisUserService {

@Autowired

private MyBatisUserDao myBatisUserDao = null;

@Override

public User getUser(Long id) {

return myBatisUserDao.getUser(id);

}

}

4. 建立User、MyBatisUserDao 和SQL语句之间的映射关系(即POJO实体、数据操作接口及SQL语句之间的映射关系),以便mybatis进行自动化实现

建立一个XML(userMapper.xml),其内容如下:

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select id, user_name as userName, sex, note from user.t_user where id = #{id}

(1)这里的namespace属性对应我们声明的MyBatisUserDao接口,我们将它交给MyBatis实现

(2)MyBatisUserDao中的函数getUser的映射放在其子节点中,节点的名称为select,说明是一个SELECT语句,对应的函数是id="getUser",函数的输入参数类型parameterType="long",返回类型resultType="user"。

(3)该子节点的内容为getUser对应的SQL语句。

5. 配置映射文件和mybatis扫描的包

在application.properties文件中增加下列内容:

#MyBatis映射文件通配

mybatis.mapper-locations = classpath:/boat/db/*.xml

#MyBatis扫描别名包,与注解@Alias联用

mybatis.type-aliases-package = boat.db.pojo

#配置typeHandler的扫描包

mybatis.type-handlers-package = boat.db.pojo

#日志配置

logging.level.root = DEBUG

logging.level.org.springframework = DEBUG

logging.level.org.org.mybatis = DEBUG

(1)将映射文件的位置用classpath属性给出。

(2)给出POJO类的包名,供mybatis扫描。

(3)给出typeHandler的包名,供mybatis扫描

(4)日志配置成DEBUG型

6. 基于Spring boot集成mybatis

在主类(带main函数的类)中加入下列代码:

@Autowired

SqlSessionFactory sqlSessionFactory = null;

@Bean

public MapperFactoryBean initMyBatisUserDao() {

MapperFactoryBean bean = new MapperFactoryBean<>();

bean.setMapperInterface(MyBatisUserDao.class);

bean.setSqlSessionFactory(sqlSessionFactory);

return bean;

}

(1)自动生成一个SqlSessionFactory ,用于根据前面的POJO、操作接口和SQL之间的映射关系自动实现代码;

(2)生成一个基于MyBatisUserDao和SqlSessionFactory 的MapperFactoryBean,这个Bean实现了MyBatisUserDao操作接口的自动化;

7. 运行和调试

建立一个Controller,用于调用服务

@Controller

@RequestMapping("/mybatis")

public class MyBatisController {

@Autowired

private MyBatisUserService myBatisUserService = null;

@RequestMapping("/getuser")

@ResponseBody

public User getUser(Long id) {

return myBatisUserService.getUser(id);

}

}

@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

然后调试运行,出现的两个错误

一是找不到数据库:提示是没有找到DB_Example 数据库,我发现由于理解错误,在application.properties中将spring.datasource.url 项搞错了,写成了 jdbc:mysql://localhost:3306/DB_Example ,DB_Example 是项目名称,改变数据库名user后通过。

二是时区错误:第一项改了后,运行时提示“mysql时区错误”。查百度后,认为需要重新配置mysql时区,但在cmd中无论如何登录mysql都失败了,查了很多百度,但也不成功。后来发现my.ini文件中有时区设置项,将原来的:

[mysqld_safe]

time-zone='UTC'

改为:

[mysqld]

default-time-zone='+08:00'

运行成功

第三未解决问题:mysql不能登录,以后再说

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值