Idea中 mybatis 配置范例(小白可以空走弯路)
什么都 不说了,上干货:
一、使用环境(前提重要)
- Win10 + JDK v11.0.15 + MySQL v8.0.28
- Idea 2021.3.3
- Apache Tomcat v9.0.60 + Maven v3.8.5
温馨提示:Tomcat 不要用 v10.0.* 的,其中 Servlet 引用跟 v9.* 变化太大,网上好多教材出来的结果都会报错,后期学习其它方面内容查起来太累了。
JDK、MySQL、Tomcat、Idea、Maven 全用的是官网的 zip 文件解压安装配置(机器配置跟不上时代,将就用)[ git只有exe文件,就装了vscode v1.67.2,其它工具就装了Navicat Premium 15 ]。
以上工具全可以是不用掏银子了的,用来学习正好!
<maven 使用了腾讯云的镜像源,测试时比阿里云快一点点,默认的国外网站会让你崩溃>
二、我的项目文件,可供参考:
数据库示例文件:mybatis.sql
另附 :
–>国外测试用例 生成网站 https://mockaroo.com/
–>国内测试用例生成网站 https://hepengju.com/
可以按需生成你想要的带数据的数据库表,建议收藏]
/*
Navicat Premium Data Transfer
Source Server : CMySQL
Source Server Type : MySQL
Source Server Version : 80028
Source Host : localhost:3306
Source Schema : mybatis
Target Server Type : MySQL
Target Server Version : 80028
File Encoding : 65001
Date: 01/06/2022 17:06:33
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int NOT NULL,
`name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'NULL',
`email` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`age` int NULL DEFAULT NULL,
`chinese_score` float(6, 2) NULL DEFAULT NULL,
`math_score` float(6, 2) NULL DEFAULT NULL,
`english_score` float(6, 2) NULL DEFAULT NULL,
`total_score` float(7, 2) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1000, '赵一', 'zhao@sina.com', 20, 63.00, 88.00, 92.50, NULL);
INSERT INTO `student` VALUES (1001, '钱二', 'qian@126.com', 28, 75.50, 65.60, 59.50, NULL);
INSERT INTO `student` VALUES (1002, '孙三', 'zwu@qq.com', 22, 89.80, 99.50, 76.00, NULL);
INSERT INTO `student` VALUES (1003, '李四', 'li@qwe.com', 26, 54.80, 77.80, 83.00, NULL);
INSERT INTO `student` VALUES (1004, '周五', 'zhou@we.com', 19, 68.50, 65.30, 100.00, NULL);
INSERT INTO `student` VALUES (1005, '吴六', 'wu@sina.com', 25, 95.00, 100.00, 86.00, NULL);
INSERT INTO `student` VALUES (1006, '郑七', 'zheng@qq.com', 22, 75.50, 88.00, 100.00, NULL);
INSERT INTO `student` VALUES (1007, '王八', 'wang@gmail.com', 26, 95.00, 65.60, 92.50, NULL);
INSERT INTO `student` VALUES (1008, '冯九', 'feng@tt.com', 22, 66.00, 59.00, 100.00, NULL);
INSERT INTO `student` VALUES (1009, '陈十', 'cheng@sas.cn', 25, 68.50, 65.60, 92.50, NULL);
- POM.xml 文件内容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ltg</groupId>
<artifactId>mybatis-start</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--扫描xml插件, 缺少了会报错: 找不到?.XML 文件[不能在编译后的 Classes 目录生成对应文件] -->
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
https://mvnrepository.com/ 真是个强大的网站,不能确认正确的依赖代码可以直接查找到!
2. 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>
<!--
读取jdbc.propertis属性,
通过方法参数传递的属性具有最高优先级,
resource/url 属性中指定的配置文件次之,
最低优先级的则是 properties 元素中指定的属性
-->
<properties resource="jdbc.properties"></properties>
<!--设置日志输出-->
<settings>
<!--标准日志值'STDOUT_LOGGING',可以不用配置另的信息-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--
注册 mapper.xml 文件
resource: 从 resource 目录下找指定的文件加载;
url: 使用绝对路径注册
class: 动态代理方式下的注册
-->
<mapper resource="Mapper/studentMapper.xml"/>
</mappers>
</configuration>
其中包含相对应的 db.properties 文件,内容如下:
jbbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=123456
url 最后一个参数:allowPublicKeyRetrieval=true 一定要加!
- studentMapper.xml 文件内容:
<?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.ltg.dao.studentDao">
//id 和 对应 Dao 方法对应
//查询全部信息,方法的参数为空
<select id="selectAll" resultType="com.ltg.entity.student">
select * from student
</select>
//查询指定ID信息,方法的参数为单个整型值
<select id="selectId" resultType="com.ltg.entity.student">
select id,name,email,chinese_score
from student
where id = #{id}
</select>
//查询语文和数据成绩名单,方法的参数为两个浮点型数
//可直接用位置参数来获取参数值。使用 arg0 、 arg1 、 arg2 或者 param1 、 param2 、 param3 来代表第1、2、3个参数。
//注意: arg<N> 是以 0 开始计数,而 param<N> 是以 1 开始计数的。
//注意:二者不可混用,否则会出错。
//注意:多参数使用时,>、>=、<=、<、& 要用转义字符,遵循 xml 文件语法。
<select id="selectScore" resultType="com.ltg.entity.student">
select id,name,email,chinese_score,math_score
from student
where chinese_score > #{param1} and math_score > #{param2}
</select>
</mapper>
- mapper : 是当前文件的根标签,格式固定
- namespace : 叫做命令空间,唯一值的,可以自定义的字体串。推荐使用全限定的 dao 接口的全限定名称。
[获取技巧:打开项目文件目录树,选中相应dao文件,右击,选中“copy path/Reference…”,再选 “copy Reference”可取得该限定路径]
(本案例:com.ltg.dao.StudentDao) - ///: 数据库操作指定标签
- id : 要执行的 sql 语句的唯一标识,mybatis 会使用这个 id 的值来执行 sql 语句。
可以算自定义,推荐使用接口中的方法名称。 - resultType : 执行结果集,表示结果类型。遍历执行得到的 java 对象类型,值写的是类型的全限定名称。
(本案例 : com.ltg.dao.StudentDao.queryById) - 若结果集使用 resultMap,则其子标签 property={显示列名称} 显示列名称 应当与实体类列名称保持一致,否则报错
- studentDao.class 接口文件内容:
package com.ltg.dao;
import com.ltg.entity.student;
import java.util.List;
public interface studentDao {
//查询全部信息,方法的参数为空
List<student> selectAll();
//查询指定ID信息,方法的参数为单个整型值
List<student> selectId(int i);
//查询语文和数据成绩名单,方法的参数为两个浮点型数
List<student> selectScore(float a,float b);
}
- student.class 实体文件内容:
package com.ltg.entity;
public class student {
private Integer id;
private String name;
private String email;
private Integer age;
private Float chinese_score;
private Float math_score;
private Float english_score;
private Float total_score;
// 下面 get & set 都是通过idea自动生成的代码,很方便
public Integer getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
......
// 下面这个也是通过idea自动生成的代码
@Override
public String toString() {
return "student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
", chinese_score=" + chionese_score +
", math_score=" + math_score +
", english_score=" + english_score +
", total_score=" + total_score +
'}';
}
}
- mybatisApp 文件内容:
package com.ltg;
import com.ltg.entity.student;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class mybatisApp {
public static void main(String[] args) throws IOException {
//使用 mybatis 读取 student 数据
//1.定义 mybatis 主配置文件的名称,从类路径的根开始 (target/classes)
//2.读取这个 config 表示的文件
//3.创建一个 SqlSessionFactoryBuilder 对象
//4.创建一个 SqlSessionFactory 对象
//5.获取 sqlSession 对象,从 SqlSessionFactory 中获取
//6.调用要执行的sql语句的标识。sql映射文件中的 namespace + "." + id 标签的值
//7.执行 sql 语句
//8.输出结果
//9.关闭SqlSession对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//对应第一条 selectAll 语句,无参数
List<student> StudentList = sqlSession.selectList("com.ltg.dao.studentDao.selectAll");
StudentList.forEach(student -> System.out.println(student));
System.out.println("Next...");
studentDao mapper = sqlSession.getMapper(studentDao.class);
//对应第二条 selectAll 语句,1个参数
List<student> list1 = mapper.selectId(1016);
list1.forEach(student -> System.out.println(list1));
//对应第三条 selectAll 语句,2个参数
System.out.println("Contiue...");
List<student> list2 = mapper.selectScore(80,80);
list2.forEach(student -> System.out.println(list2));
sqlSession.close();
// 以上照抄 mybatis 官网部分代码
}
}
效果等同第6步的一段代码文件(StartTest.java),仅供参考:
[位置通常存放在 src / test / java / 目录下]
package ...; //根据实际包名修改
import com.ltg.mapper.StudentMapper;
import com.ltg.pojo.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
public class StartTest {
SqlSession sqlSession;
@Before
public void openSqlSession() throws IOException {
String resource = "SqlMapConfig.xml";
// 1.使用文件流读取核心配置文件 SqlMapConfig.xml
InputStream inputStream = Resources.getResourceAsStream(resource);
// 2.创建 SqlSessionFactory 工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 3.取出 sqlSession ,带(true)参数表示提交事务,默认为空 (false)
sqlSession = sqlSessionFactory.openSession(true);
}
@After
public void closeSqlSession() {
sqlSession.close();
}
@Test
public void testQueryAll() {
// 取出动态代理的对象,完成接口中方法的调用,实则是调用 xml 文件中相应的标签的功能
// 方法1:适用返回结果是超过一个实体 方法接口返回使用类型:实体集类型 -> List<Basicdata>
List<Basicdata> list = sqlSession.selectList("com.ltg.mapper.StudentMapper.queryAll");
list.forEach(System.out::println);
System.out.println("Testing QueryAll() is end!");
}
@Test
public void testQueryById() {
// 取出动态代理的对象,完成接口中方法的调用,实则是调用 xml 文件中相应的标签的功能
// 方法2:适用返回结果是一个实体 方法接口返回使用类型:实体类型 -> Basicdata
StudentMapper bMapper = sqlSession.getMapper(StudentMapper.class);
Student student = bMapper.queryById(100);
System.out.println(student);
System.out.println("Testing QueryBYId() is end!");
}
@Test
public void testQueryByName() {
// 取出动态代理的对象,完成接口中方法的调用,实则是调用 xml 文件中相应的标签的功能
StudentMapper bMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = bMapper.queryByName("ser");
list.forEach(System.out::println);
System.out.println("Testing QueryByName() is end!");
}
@Test
public void testQueryByNearName() {
// 取出动态代理的对象,完成接口中方法的调用,实则是调用 xml 文件中相应的标签的功能
StudentMapper bMapper = sqlSession.getMapper(StudentMapper.class);
System.out.println(bMapper.getClass()); // Pause->test,Can be deleted
List<Student> list = bMapper.queryByNearName("first_name","sar");
list.forEach(System.out::println);
System.out.println("Testing QueryByNearName() is end!");
}
@Test
public void testQueryByLimit() {
StudentMapper bMapper = sqlSession.getMapper(StudentMapper.class);
HashMap<String, Integer> map = new HashMap<>();
map.put("startIndex", 10);
map.put("pageSize", 20);
List<Student> list = bMapper.queryByLimit(map);
list.forEach(System.out::println);
System.out.println("Testing QueryByLimit is over!");
}
@Test
public void testQueryByRowBounds() {
// RowBounds 实现
RowBounds rowBounds = new RowBounds(1,10);
List<Student> list = sqlSession.selectList("com.ltg.mapper.StudentMapper.queryByRowBounds",null,rowBounds);
list.forEach(System.out::println);
System.out.println("Testing QueryByRowBounds is over!");
}
@Test
public void testgetBasicdataById() {
StudentMapper bMapper = sqlSession.getMapper(StudentMapper.class);
Student student = bMapper.getStudentById(10);
System.out.println(student);
System.out.println("Testing getBasicdataById is over!");
}
}
个人推荐使用以下目录结构(清晰,一目了然):
一个简单的 mybatis 项目,需要手动编写的仅需5个文件(要按规范要求编写)即可,其余的将由 idea 自动链接引入。
要点汇集:
- mapper 下的 java接口文件 和 xml映射文件
放一个目录中
并且同名
(降低出错几率)。
如 mapper /xxxxMapper
.java, 和 mapper /xxxxMapper
.xml- xml映射文件 中的 “select”、“update”、“delete”、"insert"语句中的 id 标识符必须和java接口文件中的方法名保持一致。
如 mapper /xxxxMapper
.java 有 方法 intyyyy()
; 方法;
则对应的 mapper /xxxxMapper
.xml 有<select id="yyyy"> select * from database </select>
对应;- SqlMapConfig.xml 文件有映射文件对应段:
<mappers> <mapper resource="Mapper/xxxxMapper.xml"/> </mappers>