0-前言
Mybatis前身是iBatis,Apache的一个开源项目。Mybatis是一个类似于Hibernate的ORM持久化框架,支持普通SQL查询、存储过程以及高级映射。
Mybatis通常使用简单的xml或者注解用于配置和原始映射,将接口和POJO对象映射成数据库中的记录。
由于Mybatis是直接基于JDBC做了简单的映射包装,所有从性能上看:
JDBC>Mybatis>Hibernate
Mybatis的整体框架
](C:Users10224683Documents笔记_程磊SpringBootpicturesMybatis整体框架2.png)
1-Mybatis实现方式(1)
使用步骤总结
1)配置mybatis-config.xml 全局的配置文件 (1、数据源,2、外部的mapper)
2)创建SqlSessionFactory
3)通过SqlSessionFactory创建SqlSession对象
4)通过SqlSession操作数据库 CRUD
5)调用session.commit()提交事务
6)调用session.close()关闭会话==
目录结构
](C:Users10224683Documents笔记_程磊SpringBootpicturesImage 2019-11-13-13-58-29-001.png)
配置
<POM>依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<mybatis-config.xml>全局配置文件
<?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>
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 环境,可以配置多个,default:指定采用哪个环境 -->
<environments default="test">
<!-- id:唯一标识 -->
<environment id="test">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
<environment id="development">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}" /> <!-- 配置了properties,所以可以直接引用 -->
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 建立映射关系 -->
<mappers>
<mapper resource="mappers/MyMapper.xml" />
<mapper resource="mappers/UserDaoMapper.xml" />
<mapper resource="mappers/UserMapper.xml" />
</mappers>
</configuration>
源文件及实现
第一步:<mybatis-config.xml>全局配置文件
其中:关键的映射规则:
<mappers>
<!-- 将mapper文件映射到全局配置文件中 -->
<mapper resource="mappers/UserDaoMapper.xml" />
</mappers>
第二步:编写数据类
一下一次建包,编写java类
POJO:User.java
package com.onebooming.pojo;
import java.util.Date;
public class User {
private String id;
private String username;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
private String created;
private String updated;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getUpdated() {
return updated;
}
public void setUpdated(String updated) {
this.updated = updated;
}
@Override
public String toString() {
return "user{" +
"id='" + id + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", birthday=" + birthday +
", created='" + created + '\'' +
", updated='" + updated + '\'' +
'}';
}
}
dao:UserDao.java
package com.onebooming.dao;
import com.onebooming.pojo.User;
import java.util.List;
public interface UserDao {
/**
* 根据id查询用户信息
* @param id
* @return
*/
public User queryUserById(String id);
/**
* 查询所有用户信息
* @return
*/
public List<User> queryUserAll();
/**
* 新增用户
* @param User
*/
public void insertUser(User user);
/**
* 更新用户信息
* @param User
*/
public void updateUser(User user);
/**
* 根据id删除用户信息
* @param id
*/
public void deleteUser(String id);
}
daoImpl:UserDaoImpl
UserDao接口的实现类:
package com.onebooming.dao.daoImpl;
import com.onebooming.dao.UserDao;
import com.onebooming.pojo.User;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class UserDaoImpl implements UserDao {
public SqlSession sqlSession;
public UserDaoImpl(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
public User queryUserById(String id) {
return this.sqlSession.selectOne("UserDao.queryUserById", id);
}
public List<User> queryUserAll() {
return this.sqlSession.selectList("UserDao.queryUserAll");
}
public void insertUser(User user) {
this.sqlSession.insert("UserDao.insertUser", user);
}
public void updateUser(User user) {
this.sqlSession.update("UserDao.updateUser", user);
}
public void deleteUser(String id) {
this.sqlSession.delete("UserDao.deleteUser", id);
}
}
第三步:创建对应的mapper.xml文件
UserDaoMapper:(该文件一般集中放在resource-->mappers路径下)
注意:一定要修改对应namespace,以及的resultType和paramType的路径
<mapper namespace="UserDao">
namespace:命名空间,随便写,一般保证命名空间唯一
<select id="queryUserById" resultType="com.onebooming.pojo.User">
id:UserDao中CRUD的方法名,必须完全匹配
resultType:方法的返回值类型
完整:
<?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:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="UserDao">
<!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
resultType:sql语句查询结果集的封装类型,tb_user即为数据库中的表
-->
<!--<select id="queryUserById" resultType="com.zpc.mybatis.pojo.User">-->
<!--select * from tb_user where id = #{id}-->
<!--</select>-->
<!--使用别名-->
<select id="queryUserById" resultType="com.onebooming.pojo.User">
select
tuser.id as id,
tuser.user_name as username,
tuser.password as password,
tuser.name as name,
tuser.age as age,
tuser.birthday as birthday,
tuser.sex as sex,
tuser.created as created,
tuser.updated as updated
from
tb_user tuser
where tuser.id = #{id};
</select>
<select id="queryUserAll" resultType="com.onebooming.pojo.User">
select * from tb_user;
</select>
<!--插入数据-->
<insert id="insertUser" parameterType="com.onebooming.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
#{id},
#{username},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
now(),
now()
);
</insert>
<update id="updateUser" parameterType="com.onebooming.pojo.User">
UPDATE tb_user
<trim prefix="set" suffixOverrides=",">
<if test="username!=null">user_name = #{username},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
WHERE
(id = #{id});
</update>
<delete id="deleteUser">
delete from tb_user where id=#{id}
</delete>
</mapper>
第四步:在全局配置文件中添加映射
<mappers>
<!-- 将mapper文件映射到全局配置文件中 -->
<mapper resource="mappers/UserDaoMapper.xml" />
</mappers>
第五步:编写测试类
重点是:取全局配置文件---读取配置文件--构建SQLSessionFactory对象---获取SqlSession对象--映射UserDao对象
xml中的sql statement 硬编码到java代码中
public UserDao userDao;
public SqlSession sqlSession;
@Before
public void setUp() throws Exception {
//maybatis-config.xml
String resource = "mybatis-config.xml";
//读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession
sqlSession = sqlSessionFactory.openSession();
this.userDao = new UserDaoImpl(sqlSession);
}
package com.onebooming.dao;
import com.onebooming.dao.daoImpl.UserDaoImpl;
import com.onebooming.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import static org.junit.Assert.*;
public class UserDaoTest {
public UserDao userDao;
public SqlSession sqlSession;
@Before
public void setUp() throws Exception {
//maybatis-config.xml
String resource = "mybatis-config.xml";
//读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession
sqlSession = sqlSessionFactory.openSession();
this.userDao = new UserDaoImpl(sqlSession);
}
@Test
public void queryUserById() {
System.out.println(this.userDao.queryUserById("1"));
}
@Test
public void queryUserAll() {
List<User> userList = this.userDao.queryUserAll();
for(User user : userList){
System.out.println(user);
}
}
@Test
public void insertUser() throws Exception {
User user = new User();
user.setAge(16);
//user.setBirthday((new Date("1949/10/01"));
String str = "1994-10-01";
Date date = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
date = dateFormat.parse(str);
user.setBirthday(date);
user.setName("Boe Wang");
user.setPassword("root");
user.setId("5");
user.setUsername("Onebooming");
user.setSex(5);
this.userDao.insertUser(user);
this.sqlSession.commit();
}
@Test
public void updateUser() {
User user = new User();
user.setBirthday(new Date());
user.setName("静鹏");
user.setPassword("654321");
user.setSex(1);
user.setUsername("evanjin");
user.setId("1");
this.userDao.updateUser(user);
this.sqlSession.commit();
}
@Test
public void deleteUser() {
this.userDao.deleteUser("2");
this.sqlSession.commit();
}
}
2-Mybatis实现方式(2)
接口的动态代理 :只写接口和Mapper.xml
使用步骤总结
(1)编写实体类(pojo--User)(2)编写接口(dao--UserMapper)
(3)编写mapper.xml(mappers--UserMapper.xml)
(4)调用接口实现CRUD
目录结构
](C:Users10224683Documents笔记_程磊SpringBootpicturesImage 2019-11-13-14-43-48-001.png)
源文件及实现:接口的动态代理
第一步:全局配置文件
和实现方式一相同
第二步:编写数据类
pojo:User.java
package com.onebooming.pojo;
import java.util.Date;
public class User {
private String id;
private String username;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
private String created;
private String updated;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getUpdated() {
return updated;
}
public void setUpdated(String updated) {
this.updated = updated;
}
@Override
public String toString() {
return "user{" +
"id='" + id + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", birthday=" + birthday +
", created='" + created + '\'' +
", updated='" + updated + '\'' +
'}';
}
}
dao:UserMapper.java(接口)
在这个接口中设计CRUD方法
package com.onebooming.dao;
import com.onebooming.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 实现Mybatis的动态代理
*/
public interface UserMapper {
/**
* 登录(直接使用注解传入指定参数名称)
* @param username
* @param password
* @return
*/
public User login(@Param("username") String username,@Param("password") String password);
/**
* 根据表名查询用户信息(直接使用注解指定传入参数名称)
* @param tablename
* @return
*
*/
public List<User> queryUserByTablename(@Param("tablename") String tablename);
/**
* 根据Id查询用户信息
* @param id
* @return
*/
public User queryById(String id);
/**
* 查询所有用户信息
* @return
*/
public List<User> queryUserAll();
/**
* 新增用户信息
* @param user
*/
public void insertUser(User user);
/**
* 根据id更新用户信息
* @param user
*
*/
public void updateUser(User user);
/**
* 根据id删除用户信息
* @param id
*/
public void deleteUserById(String id);
}
第三步:创建对应的mapper.xml文件
(UserMapper.xml)
Note1:namespace:命名空间,随便写,一般保证命名空间唯一 ,为了使用接口动态代理,这里必须是接口的全路径名
Note2:1.#{},预编译的方式preparedstatement,使用占位符替换,防止sql注入,一个参数的时候,任意参数名可以接收;2.${},普通的Statement,字符串直接拼接,不可以防止sql注入,一个参数的时候,必须使用此方法接收参数
<?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:命名空间,随便写,一般保证命名空间唯一 ,为了使用接口动态代理,这里必须是接口的全路径名-->
<mapper namespace="com.onebooming.dao.UserMapper">
<!--
1.#{},预编译的方式preparedstatement,使用占位符替换,防止sql注入,一个参数的时候,任意参数名可以接收
2.${},普通的Statement,字符串直接拼接,不可以防止sql注入,一个参数的时候,必须使用${value}接收参数
-->
<select id="queryUserByTablename" resultType="com.onebooming.pojo.User">
select * from ${tablename}
</select>
<select id="login" resultType="com.onebooming.pojo.User">
select * from tb_user where user_name = #{username} and password = #{password}
</select>
<!-- statement,内容:sql语句。
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
resultType:sql语句查询结果集的封装类型,使用动态代理之后和方法的返回类型一致;resultMap:二选一
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<select id="queryUserById" resultType="com.onebooming.pojo.User">
select * from tb_user where id = #{id}
</select>
<select id="queryUserAll" resultType="com.onebooming.pojo.User">
select * from tb_user
</select>
<!-- 新增的Statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名
-->
<insert id="insertUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id" parameterType="com.onebooming.pojo.User">
insert into tb_user(id,user_name,password,name,age,sex,birthday,created,updated)
values (
#{id},
#{username},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>
<!--
更新的statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<update id="updateUser" parameterType="com.onebooming.pojo.User">
update tb_user
<trim prefix="set" suffixOverrides=",">
<if test="username!=null">user_name = #{username},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
where (id = #{id});
</update>
<!--
删除的statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<delete id="deleteUserById" parameterType="java.lang.String">
delete from tb_user where id=#{id}
</delete>
</mapper>
第四步:在全局配置文件中添加映射
将UserMapper.xml文件再mybatis-config.xml文件中声明
<mappers>
<mapper resource="mappers/UserDaoMapper.xml" />
<mapper resource="mappers/UserMapper.xml" />
</mappers>
第五步:编写测试类
package com.onebooming.dao;
import com.onebooming.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class UserMapperTest {
public UserMapper userMapper;
@Before
public void setUp() throws Exception {
//指定配置文件
String resource = "mybatis-config.xml";
//读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//1.映射文件的命名空间(namespace)必须是mapper接口的全路径
//2.映射文件的statement的id必须和mapper接口的方法名保持一致
//3.Statemen的resultType必须和mapper接口方法的返回类型一致
//4.Statement的parameterType必须和mapper接口方法的参数类型一致(不一定)
this.userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void login() {
System.out.println(this.userMapper.login("a","b"));
}
@Test
public void queryUserByTablename() {
List<User> userList = this.userMapper.queryUserByTablename("tb_user");
for(User user: userList){
System.out.println(user);
}
}
@Test
public void queryById() {
System.out.println(this.userMapper.queryById("2"));
}
@Test
public void queryUserAll(){
List<User> userList = this.userMapper.queryUserAll();
for(User user : userList){
System.out.println(user);
}
}
@Test
public void insertUser() throws ParseException {
User user = new User();
user.setId("6");
user.setUsername("mayun");
user.setPassword("123456");
user.setAge(25);
user.setSex(1);
String str = "1995-10-01";
Date date = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
date = dateFormat.parse(str);
user.setBirthday(date);
this.userMapper.insertUser(user);
System.out.println(user.getId());
}
@Test
public void updateUser() {
User user = new User();
user.setBirthday(new Date());
user.setName("草泥马");
user.setPassword("123456");
user.setSex(0);
user.setUsername("hehe");
user.setId("2");
this.userMapper.updateUser(user);
}
@Test
public void deleteUserById() {
this.userMapper.deleteUserById("1");
}
}
3-Mybatis实现方式(3)
mybatis笔记之使用Mapper接口注解
该方式只需对接口使用@Mapper注解,不需要编写mapper.xml文件,直接实现CRUD
配置
pom依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.onebooming</groupId>
<artifactId>boe-cloud-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>boe-cloud-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
核心
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
配置文件
application.propertities
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql:///boecloudservice?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=root
mybatis.config-location=classpath:/mybatis-config.xml
server.port=8081
logging.level.org.springframework.security=info
mybatis-config.xml
<?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>
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/boecloudservice?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
</configuration>
源文件及实现:直接使用注解编写接口
entities层:实体类
package com.onebooming.boecloudservice.bean;
import java.util.Date;
/**
* 虚拟机实体类
* @author Onebooming
*/
public class VirtualMachine {
public Long id;//虚拟机ID
public String machineName;//虚拟机名称
public String vmPathName;//虚拟机路径名
public String guestFullName;//客户机全名
public String instanceUuid;//实例UUID
public String annotation;//注释
public String powerState;//电源状态
public String toolsStatus;//工具状态
public String ipAddress;//IP地址
public Integer memorySizeMB;//内存大小
public Integer numCpu;//CPU核数
public Integer numVirtualDisks;//虚拟硬盘数
public Date bootTime;//boot时间
public String exsiIp;//exsiIP
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMachineName() {
return machineName;
}
public void setMachineName(String machineName) {
this.machineName = machineName;
}
public String getVmPathName() {
return vmPathName;
}
public void setVmPathName(String vmPathName) {
this.vmPathName = vmPathName;
}
public String getGuestFullName() {
return guestFullName;
}
public void setGuestFullName(String guestFullName) {
this.guestFullName = guestFullName;
}
public String getInstanceUuid() {
return instanceUuid;
}
public void setInstanceUuid(String instanceUuid) {
this.instanceUuid = instanceUuid;
}
public String getAnnotation() {
return annotation;
}
public void setAnnotation(String annotation) {
this.annotation = annotation;
}
public String getPowerState() {
return powerState;
}
public void setPowerState(String powerState) {
this.powerState = powerState;
}
public String getToolsStatus() {
return toolsStatus;
}
public void setToolsStatus(String toolsStatus) {
this.toolsStatus = toolsStatus;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public Integer getMemorySizeMB() {
return memorySizeMB;
}
public void setMemorySizeMB(Integer memorySizeMB) {
this.memorySizeMB = memorySizeMB;
}
public Integer getNumCpu() {
return numCpu;
}
public void setNumCpu(Integer numCpu) {
this.numCpu = numCpu;
}
public Integer getNumVirtualDisks() {
return numVirtualDisks;
}
public void setNumVirtualDisks(Integer numVirtualDisks) {
this.numVirtualDisks = numVirtualDisks;
}
public Date getBootTime() {
return bootTime;
}
public void setBootTime(Date bootTime) {
this.bootTime = bootTime;
}
public String getExsiIp() {
return exsiIp;
}
public void setExsiIp(String exsiIp) {
this.exsiIp = exsiIp;
}
@Override
public String toString() {
return "VirtualMachine{" +
"id=" + id +
", machineName='" + machineName + '\'' +
", vmPathName='" + vmPathName + '\'' +
", guestFullName='" + guestFullName + '\'' +
", instanceUuid='" + instanceUuid + '\'' +
", annotation='" + annotation + '\'' +
", powerState='" + powerState + '\'' +
", toolsStatus='" + toolsStatus + '\'' +
", ipAddress='" + ipAddress + '\'' +
", memorySizeMB=" + memorySizeMB +
", numCpu=" + numCpu +
", numVirtualDisks=" + numVirtualDisks +
", bootTime=" + bootTime +
", exsiIp='" + exsiIp + '\'' +
'}';
}
}
dao层:接口
package com.onebooming.boecloudservice.dao;
import com.onebooming.boecloudservice.bean.VirtualMachine;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface VirtualMachineDao {
/**
* 增加记录
* @param virtualMachine
*/
/**
* 使用Option来对应着XML设置的select标签的属性
* userGeneratordKeys表示要使用自增主键
* keyProperty用来指定主键字段的字段名。
* 自增主键会使用数据库底层的自增特性。
*/
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into t_virtualmachine " +
"(machineName,vmPathName,guestFullName,instanceUuid,annotation,powerState,toolsStatus,ipAddress,memorySizeMB,numCpu,numVirtualDisks,bootTime,exsiIp) " +
"values (" +
"#{machineName},#{vmPathName},#{guestFullName},#{instanceUuid},#{annotation},#{powerState},#{toolsStatus},#{ipAddress},#{memorySizeMB},#{numCpu},#{numVirtualDisks},#{bootTime},#{exsiIp})")
public void addVirtualMachine(VirtualMachine virtualMachine);
/**
* 删除记录
* @param id
*/
@Delete("delete from t_virtualmachine where id=#{id}")
public void deleteById(@Param("id") Long id);
@Delete("delete * from t_virtualmachine")
public void deleteAll();
//注意SQL语句:set后和where前都需要数据一个空格
/**
* 更新记录--根据id
* @param virtualMachine
*/
@Update("update t_virtualmachine set " +
"machineName=#{machineName}," +
"vmPathName=#{vmPathName}," +
"guestFullName=#{guestFullName}," +
"instanceUuid=#{instanceUuid}," +
"annotation=#{annotation}," +
"powerState=#{powerState}," +
"toolsStatus=#{toolsStatus}," +
"ipAddress=#{ipAddress}," +
"memorySizeMB=#{memorySizeMB}," +
"numCpu=#{numCpu}," +
"numVirtualDisks=#{numVirtualDisks}," +
"bootTime=#{bootTime}," +
"exsiIp=#{exsiIp} " +
"where id=#{id}")
public void updateVMById(VirtualMachine virtualMachine);
/**
* 更新记录--根据机器名--MachineName
* @param virtualMachine
*/
@Update("update t_virtualmachine set " +
"vmPathName=#{vmPathName}," +
"guestFullName=#{guestFullName}," +
"instanceUuid=#{instanceUuid}," +
"annotation=#{annotation}," +
"powerState=#{powerState}," +
"toolsStatus=#{toolsStatus}," +
"ipAddress=#{ipAddress}," +
"memorySizeMB=#{memorySizeMB}," +
"numCpu=#{numCpu}," +
"numVirtualDisks=#{numVirtualDisks}," +
"bootTime=#{bootTime}," +
"exsiIp=#{exsiIp} " +
"where machineName=#{machineName}")
public void updateVMByName(VirtualMachine virtualMachine);
/**
* 查询记录---根据机器名查询
*/
/**
* 对于表的字段名和对象的属性名没有太大相同点并且表中的字段挺多的情况下,应该使用ResultMap做适配。
*/
@Results(id = "VMResult", value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "machineName",property = "machineName"),
@Result(column = "vmPathName",property = "vmPathName"),
@Result(column = "guestFullName",property = "guestFullName"),
@Result(column = "instanceUuid",property = "instanceUuid"),
@Result(column = "annotation",property = "annotation"),
@Result(column = "powerState",property = "powerState"),
@Result(column = "toolsStatus",property = "toolsStatus"),
@Result(column = "ipAddress",property = "ipAddress"),
@Result(column = "memorySizeMB",property = "memorySizeMB"),
@Result(column = "numCpu",property = "numCpu"),
@Result(column = "numVirtualDisks",property = "numVirtualDisks"),
@Result(column = "bootTime",property = "bootTime"),
@Result(column = "exsiIp",property = "exsiIp"),
})
@Select("select * from t_virtualmachine where machineName = #{machineName}")
public List<VirtualMachine> selectByName(@Param("machineName") String machineName);
/**
* 查询记录,获取所有虚拟机记录
* @return
*/
@ResultMap("VMResult")
@Select("select * from t_virtualmachine")
public List<VirtualMachine> findAll();
/**
* 根据id查询记录
* @param id
* @return
*/
@Select("select * from t_virtualmachine where id = #{id}")
public VirtualMachine selectById(@Param("id") Long id);
}
Service层:
package com.onebooming.boecloudservice.service;
import com.onebooming.boecloudservice.bean.VirtualMachine;
import com.onebooming.boecloudservice.dao.VirtualMachineDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author Onebooming
* @apiNote 虚拟机服务层
*/
@Service
@Transactional
public class VirtualMachineService {
@Autowired
private VirtualMachineDao virtualMachineDao;
/**
* 服务类:增加虚拟机信息
* @param virtualMachine
*/
public void addNewVMInfo(VirtualMachine virtualMachine){
virtualMachineDao.addVirtualMachine(virtualMachine);
}
/**
* 服务类:修改虚拟机信息
* @param virtualMachine
*/
public void updateVMInfo(VirtualMachine virtualMachine){
virtualMachineDao.updateVMByName(virtualMachine);
}
/**
* 服务类:根据id删除虚拟机记录
* @param id
*/
public void deleteVMById(Long id){
virtualMachineDao.deleteById(id);
}
/**
* 服务类:删除全部虚拟机记录
*/
public void deleteAllVM(){
virtualMachineDao.deleteAll();
}
/**
* 服务类:查询全部服务器记录
* @return
*/
public List<VirtualMachine> findAll(){
return virtualMachineDao.findAll();
}
/**
* 服务类:根据虚拟机名查询虚拟机记录
* @param name
* @return
*/
public List<VirtualMachine> findByName(String name){
return virtualMachineDao.selectByName(name);
}
/**
* 服务类:根据id查询服务器类
* @param id
* @return
*/
public VirtualMachine findById(Long id){
return virtualMachineDao.selectById(id);
}
}
注意
ResultMap
对于表的字段名和对象的属性名没有太大相同点并且表中的字段挺多的情况下,应该使用ResultMap做适配。
/**
* 使用ResultMap
*
* @param id
* @return
*/
@Results(id = "VMResult", value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "machineName",property = "machineName"),
@Result(column = "vmPathName",property = "vmPathName"),
@Result(column = "guestFullName",property = "guestFullName"),
@Result(column = "instanceUuid",property = "instanceUuid"),
@Result(column = "annotation",property = "annotation"),
@Result(column = "powerState",property = "powerState"),
@Result(column = "toolsStatus",property = "toolsStatus"),
@Result(column = "ipAddress",property = "ipAddress"),
@Result(column = "memorySizeMB",property = "memorySizeMB"),
@Result(column = "numCpu",property = "numCpu"),
@Result(column = "numVirtualDisks",property = "numVirtualDisks"),
@Result(column = "bootTime",property = "bootTime"),
@Result(column = "exsiIp",property = "exsiIp"),
})
@Select("select * from t_virtualmachine where machineName = #{machineName}")
public List<VirtualMachine> selectByName(@Param("machineName") String machineName);
@Results对应着XML中的ResultMap,同时可以为其指定一个id,其它地方可以使用这个id来引用它,比如要引用上面的这个Results: ==(<u>VMResult</u>)==
/**
* 查询记录,获取所有虚拟机记录
* @return
*/
@ResultMap("VMResult")
@Select("select * from t_virtualmachine")
public List<VirtualMachine> findAll();
使用@ResultMap来引用一个已经存在的ResultMap,这个ResultMap可以是在Java中使用@Results注解定义的,也可以是在XML中使用resultMap标签定义的。
局限
使用接口注解的优点:
- 比较方便,快速编写映射语句
使用接口注解的缺点:
1. 适用于比较简单的配置,当太复杂了接口就搞不定了。
2. **不能使用动态SQL**,有点鸡肋。
4-Mybatis实现方式(4)
@Mapper注解+mapper.xml
优势:灵活,可实现复杂的sql查询
目录
因为涉及到项目内容,这里不便贴图
简要介绍一下:
bean包:PhysicServer.class
dao包:PhysicServerMapper.class
/resource/mappers/:PhysicServerMapper.xml
源文件及实现
Step1-创建SpringBoot项目
Step2-添加mybatis依赖
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
<!-- druid阿里巴巴数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.26</version>
</dependency>
Step3-application.properties中配置Druid数据源
# 主数据源,默认的
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 数据库名称
spring.datasource.url=jdbc:mysql:///boecloudservice?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT
# 数据库登录账号
spring.datasource.username=root
# 数据登录密码
spring.datasource.password=root
# 主配置文件
mybatis.config-location=classpath:/mybatis-config.xml
# SpringBoot应用程序服务访问端口号
server.port=8081
logging.level.org.springframework.security=info
# 下面为Druid连接池的补充设置,应用到上面所有数据源中
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
#spring.datasource.useGlobalDataSourceStat=true
Step4-java代码编写(bean+dao)
实体类:PhysicServer
package com.onebooming.boecloudservice.bean;
import java.util.HashMap;
/**
* CPU服务器类
* @author Onebooming
*
*/
public class PhysicServer {
private Long id;//设备id
private String name;//设备名
private String area;//设备所在地
private String datacenter;//数据中心
private String position;//位置
private String height;//高度
private String brand;//品牌
private String type;//型号
private String serialNumber;//序列号
private String bIp;//业务IP
private String mgmtIp;//管理IP
private String cpuName;//CPUming
private int cpuNum;//cpu数量
private HashMap<Integer, Integer> memoryMap;//内存条规格及数量
//key;内存条规模(4G/8G/16G/32G...),value:内存条数量
private int memorySum;//内存总量
private int storage;//存储空间总量
private HashMap<String, Integer> diskMap;//磁盘规格及数量
private String manufactor;//制造商
private String department;//所属部门
private String user;//使用者
private String maintainor;//运维人员
@Override
public String toString() {
return "PhysicServer{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", area='" + area + '\'' +
", datacenter='" + datacenter + '\'' +
", position='" + position + '\'' +
", height='" + height + '\'' +
", brand='" + brand + '\'' +
", type='" + type + '\'' +
", serialNumber='" + serialNumber + '\'' +
", bIp='" + bIp + '\'' +
", mgmtIp='" + mgmtIp + '\'' +
", cpuName='" + cpuName + '\'' +
", cpuNum=" + cpuNum +
", memoryMap=" + memoryMap +
", memorySum=" + memorySum +
", storage=" + storage +
", diskMap=" + diskMap +
", manufactor='" + manufactor + '\'' +
", department='" + department + '\'' +
", user='" + user + '\'' +
", maintainor='" + maintainor + '\'' +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getDatacenter() {
return datacenter;
}
public void setDatacenter(String datacenter) {
this.datacenter = datacenter;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
public String getbIp() {
return bIp;
}
public void setbIp(String bIp) {
this.bIp = bIp;
}
public String getMgmtIp() {
return mgmtIp;
}
public void setMgmtIp(String mgmtIp) {
this.mgmtIp = mgmtIp;
}
public String getCpuName() {
return cpuName;
}
public void setCpuName(String cpuName) {
this.cpuName = cpuName;
}
public int getCpuNum() {
return cpuNum;
}
public void setCpuNum(int cpuNum) {
this.cpuNum = cpuNum;
}
public HashMap<Integer, Integer> getMemoryMap() {
return memoryMap;
}
public void setMemoryMap(HashMap<Integer, Integer> memoryMap) {
this.memoryMap = memoryMap;
}
public int getMemorySum() {
return memorySum;
}
public void setMemorySum(int memorySum) {
this.memorySum = memorySum;
}
public int getStorage() {
return storage;
}
public void setStorage(int storage) {
this.storage = storage;
}
public HashMap<String, Integer> getDiskMap() {
return diskMap;
}
public void setDiskMap(HashMap<String, Integer> diskMap) {
this.diskMap = diskMap;
}
public String getManufactor() {
return manufactor;
}
public void setManufactor(String manufactor) {
this.manufactor = manufactor;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getMaintainor() {
return maintainor;
}
public void setMaintainor(String maintainor) {
this.maintainor = maintainor;
}
}
dao接口:PhysicServerMapper
package com.onebooming.boecloudservice.dao;
import com.onebooming.boecloudservice.bean.PhysicServer;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Onebooming
* @apiNote 服务器服务访问层类
*/
@Mapper
public interface PhysicServerMapper {
/**
* 增加服务器信息
* @param physicServer
* @return
*/
public void addServers(PhysicServer physicServer);
/**
* 更新服务器信息
* @param physicServer
* @return
*/
public void updateServers(PhysicServer physicServer);
/**
* 根据id删除服务器信息
* @param id
*/
public void deleteServersById(Long id);
/**
* 获取所有服务器信息
* @return
*/
public List<PhysicServer> getAllServers();
/**
* 根据服务器名获取
* @param name
* @return
*/
public PhysicServer getServerByName(@Param("name") String name);
}
Step5-mapper.xml文件编写
- 直接在mysql中创建数据:boecloudserver
- 在数据库中建立数据表:t_phsicserver
- [ ] ==注意的是数据中的字段名称最好和PhysicServer.java实体类中的属性名一致,最好是复制过去,这样,可以避免很多sql语句中的拼写错误。==
如图
同时编写对应的mapper文件:PhysicServerMapper.xml
**注意:这里最重要的还是的namespace的绝对路径:"com.onebooming.boecloudservice.dao.PhysicServerMapper"
以及sql语句中的参数类型,返回值类型的路径**
<?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.onebooming.boecloudservice.dao.PhysicServerMapper">
<insert id="addServers" parameterType="com.onebooming.boecloudservice.bean.PhysicServer" useGeneratedKeys="true" keyProperty="id">
insert into t_physicservers(name,area,datacenter,position,height,brand,type,serialnumber,
bIp,mgmtIp,cpuname,cpunum,memorysum,storage,manufactor,department,user,maintainor)
values
(#{name},#{area},#{datacenter},#{position},#{height},#{brand},#{type},#{serialNumber},
#{bIp},#{mgmtIp},#{cpuName},#{cpuNum},#{memorySum},#{storage},#{manufactor},#{department},#{user},#{maintainor})
</insert>
<update id="updateServers" parameterType="com.onebooming.boecloudservice.bean.PhysicServer">
update t_physicservers set
name=#{name},
area=#{area},
datacenter=#{datacenter},
position=#{position},
height=#{height},
brand=#{brand},
type=#{type},
serialnumber=#{serialNumber},
bIp=#{bIp},
mgmtIp=#{mgmtIp},
cpuname=#{cpuName},
cpunum=#{cpuNum},
memorysum=#{memorySum},
storage=#{storage},
manufactor=#{manufactor},
department=#{department},
user=#{user},
maintainor=#{maintainor}
where id=#{id}
</update>
<delete id="deleteServersById" parameterType="java.lang.Long">
delete from t_physicservers where id=#{id}
</delete>
<select id="getAllServers" resultType="com.onebooming.boecloudservice.bean.PhysicServer">
select * from t_physicservers
</select>
<select id="getServerByName" parameterType="String" resultType="com.onebooming.boecloudservice.bean.PhysicServer">
select * from t_physicservers where name=#{name}
</select>
</mapper>
将PhysicServerMapper.xml文件再mybatis-config.xml文件中声明
<mappers>
<mapper resource="mappers/ArticleMapper.xml" />
<mapper resource="mappers/CategoryMapper.xml" />
<mapper resource="mappers/PhysicServerMapper.xml" />
<mapper resource="mappers/TagsMapper.xml" />
<mapper resource="mappers/RolesMapper.xml" />
<mapper resource="mappers/UserMapper.xml" />
</mappers >
接下来,就可以测试了。
后记
关于Mybatis,我也是个初学者,学了差不多两周时间,也在项目中踩过坑。于是就将自己的实践步骤整合起来了。文章中的错误也请大家及时指正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。