目录
pom.xml中的dependencies
中导入如下代码:<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.3version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.12version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.19version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
log4j.properties
文件将以下内容拷贝进去,用于输出日志等相关配置。# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
配置数据库连接是为了连接数据库以便进行CRUD操作
配置数据库连接,在resources文件夹中新建SqlMapConfig.xml
储存数据库相关配置,配置如下
<configuration>
<typeAliases>
<package name="com.database.mybatis.entity"/>
typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="qwer123"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.database.mybatis.dao">package>
mappers>
configuration>
类型别名的作用:
<typeAliases>
<typeAlias alias="Student" type="com.database.mybatis.entity.Student"/>
typeAliases>
com.database.mybatis.entity.Student
的别名是student
。<typeAliases>
<package name="com.database.mybatis.entity"/>
typeAliases>
创建实体类的作用是为了将存放数据库中返回的数据,以便于进行相应的操作。
创建实体类之前应先建立数据库相应的表,提供测试的数据库表有3个:Teacher、Class、Student。三个表是多对多的关系,EER图如下:
CREATE DATABASE test;
use test;
CREATE TABLE student(
id INT PRIMARY KEY,
teacher_id INT,
class_id INT,
student_nub BIGINT NOT NULL,
student_name VARCHAR(20) NOT NULL,
student_sex VARCHAR(20) DEFAULT '男',
student_phone VARCHAR(20)
);
SELECT * FROM student;
INSERT INTO student VALUES(1,1,1,1800300101,'一班一号','男',NULL);
CREATE TABLE class(
id INT PRIMARY KEY,
teacher_id INT,
student_id INT,
class_nub BIGINT NOT NULL,
class_name VARCHAR(20) NOT NULL,
class_maxperson INT NOT NULL,
class_haveperson INT NOT NULL,
class_place INT NOT NULL
);
INSERT INTO class VALUES(1,1,1,300101,'三院一年级一号课',80,0,17101);
SELECT * FROM class;
CREATE TABLE teacher(
id INT PRIMARY KEY,
student_id INT,
class_id INT,
teacher_nub BIGINT NOT NULL,
teacher_name VARCHAR(20) NOT NULL,
teacher_sex VARCHAR(20) DEFAULT '男',
teacher_phone VARCHAR(20)
);
INSERT INTO teacher VALUES(1,1,1,003001,'三院一号教师','男','13113311331');
SELECT * FROM teacher;
alter table student add foreign key(class_id) references class(id);
alter table student add foreign key(teacher_id) references teacher(id);
alter table teacher add foreign key(class_id) references class(id);
alter table teacher add foreign key(student_id) references student(id);
alter table class add foreign key(teacher_id) references teacher(id);
alter table class add foreign key(student_id) references student(id);
实体类创建时尽量遵循阿里巴巴java开发手册命名规则,养成良好习惯。数据库中表的字段类型需要与Java类型相对应,Java变量名以表字段名全称命名,例如表字段为student_id,则Java变量名应为StudentId。
sql变量类型与Java变量对照表如下:
Java类型 | SQL类型 |
---|---|
boolean | BIT |
byte | TINYINT |
short | SMALLINT |
int | INTEGER |
long | BIGINT |
String | CHAR,VARCHAR,LONGVARCHAR |
java.sql.Date | DATE |
java.sql.Time | TIME |
java.sql.Timestamp | TIMESTAMP |
public class Class implements Serializable {
private Integer id;
private Integer teacherId;
private Integer studentId;
private BigInteger classNub;
private String className;
private Integer classMaxPerson;
private Integer classHavePerson;
private Integer classPlace;
}
package com.database.mybatis.entity;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.List;
/**
* @author linxi
* @function
* @project database
* @package com.database.mybatis.model
* @date 2020/5/8-1:37 下午
*/
public class Class implements Serializable {
private Integer id;
private Integer teacherId;
private Integer studentId;
private BigInteger classNub;
private String className;
private Integer classMaxPerson;
private Integer classHavePerson;
private Integer classPlace;
@Override
public String toString() {
return "Class{" +
"id=" + id +
", teacher_id=" + teacherId +
", student_id=" + studentId +
", class_nub=" + classNub +
", class_name='" + className + '\'' +
", class_maxperson=" + classMaxPerson +
", class_haveperson=" + classHavePerson +
", class_place=" + classPlace +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getTeacherId() {
return teacherId;
}
public void setTeacherId(Integer teacherId) {
this.teacherId = teacherId;
}
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public BigInteger getClassNub() {
return classNub;
}
public void setClassNub(BigInteger classNub) {
this.classNub = classNub;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Integer getClassMaxPerson() {
return classMaxPerson;
}
public void setClassMaxPerson(Integer classMaxPerson) {
this.classMaxPerson = classMaxPerson;
}
public Integer getClassHavePerson() {
return classHavePerson;
}
public void setClassHavePerson(Integer classHavePerson) {
this.classHavePerson = classHavePerson;
}
public Integer getClassPlace() {
return classPlace;
}
public void setClassPlace(Integer classPlace) {
this.classPlace = classPlace;
}
}
/**
* results的ID用于定义此对应的名称,在其他接口中直接使用@Resultmap("ID")来使用此对应关系,无需重写。
* 表中主键需要在@Result()中的id属性设为true(默认为false)
* @resylt() 的column属性为表中字段名,property为实体类变量名
*/
@Results(id = "classDao", value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "teacher_id",property = "teacherId"),
@Result(column = "student_id",property = "studentId"),
@Result(column = "class_nub",property = "classNub"),
@Result(column = "class_name",property = "className"),
@Result(column = "class_maxperson",property = "classMaxPerson"),
@Result(column = "class_haveperson",property = "classHavePerson"),
@Result(column = "class_place",property = "classPlace")
})
接口例子:
/**
* results的ID用于定义此对应的名称,在其他接口中直接使用@Resultmap("ID")来使用此对应关系,无需重写。
* 表中主键需要在@Result()中的id属性设为true(默认为false)
* @resylt() 的column属性为表中字段名,property为实体类变量名
*/
@Results(id = "classDao", value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "teacher_id",property = "teacherId"),
@Result(column = "student_id",property = "studentId"),
@Result(column = "class_nub",property = "classNub"),
@Result(column = "class_name",property = "className"),
@Result(column = "class_maxperson",property = "classMaxPerson"),
@Result(column = "class_haveperson",property = "classHavePerson"),
@Result(column = "class_place",property = "classPlace")
})
@Select("select * from class")
List<Class> findAllClass();
@ResultMap("classDao")
@Select("select * from class where id=#{id}")
List<Class> findClassById(Integer classId);
模糊查询
@Select("select * from class where class_name like '%${value}%'")
这种方式直接传送参数进来就可,不需要加%
号。例如传送张三作为value即相当于:select * from class where class_name like %张三%。\
例子:
@ResultMap("classDao")
@Select("select * from class where class_name like '%${value}%'")
List<Class> findClassByClassName(String className);
@Select("select * from class where class_name like #{username}")
这种方式传送参数时需要带%
,例如传送%张三%
作为value即相当于:select * from class where class_name like %张三%。
例子:
@ResultMap("classDao")
@Select("select * from class where class_name like #{username}")
List<Class> findClassByClassName(String className);
多表查询:多表对应关系有两种:一对一和一对多。
一对一:假设有表A,B;A表中有字段id和b_id,b_id对应B表的id(id为唯一值),所以A表的每一列都有唯一一个B与其对应,则此关系为一对一。一对一关系需要用@one注解映射。
private Teacher teacher;
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Select("select * from teacher where class_id=#{class_id}")
Teacher findTeacherByClassId(Integer classId);
@Results(value = {
@Result(id = true, column = "id", property = "id"),
@Result(column = "teacher_id", property = "teacherId"),
@Result(column = "student_id", property = "studentId"),
@Result(column = "class_nub", property = "classNub"),
@Result(column = "class_name", property = "className"),
@Result(column = "class_maxperson", property = "classMaxPerson"),
@Result(column = "class_haveperson", property = "classHavePerson"),
@Result(column = "class_place", property = "classPlace"),
@Result(property = "teacher", column = "teacherId",
one = @One(select =
"com.database.mybatis.dao.TeacherDao.findTeacherByClassId",
fetchType = FetchType.EAGER))
})
@Select("select * from class where id = #{id}")
Class findClassAndTeacherByClassId(Integer classId);
一对多:假设有表A,B;A表中有字段id和b_room,b_room对应B表的room(room不唯一),所以A表的每一列都有多个B与其对应,则此关系为一对多。一对多关系需要用@many注解映射
private List<Student> students;
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Select("select * from student where class_id=#{class_id}")
List<Student> findStudentByClassId(Integer classId);
@Select("select * from class where id=#{id}")
@Results(value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "teacher_id",property = "teacherId"),
@Result(column = "student_id",property = "studentId"),
@Result(column = "class_nub",property = "classNub"),
@Result(column = "class_name",property = "className"),
@Result(column = "class_maxperson",property = "classMaxPerson"),
@Result(column = "class_haveperson",property = "classHavePerson"),
@Result(column = "class_place",property = "classPlace"),
@Result(property = "students", column = "id",
many = @Many(select =
"com.database.mybatis.dao.StudentDao.findStudentByClassId",
fetchType = FetchType.LAZY))
})
List<Class> findClassAndStudentsByClassId(Integer classId);
例子:
@ResultMap("classDao")
@Insert("insert into class(id,teacher_id,student_id,class_nub,class_name,class_maxperson,class_haveperson,class_place) values(#{id},#{teacher_id},#{student_id},#{class_nub},#{class_name},#{class_maxperson},#{class_haveperson},#{class_place})")
void insertClass(Class aClass);
此中的所有字段都在Class实体类中,只要在#{}
中填入对应的字段名或者别名并将Class作为参数传入,Mybatis就会在Class中自动查找对应的关系。
例子:
@ResultMap("classDao")
@Update("update class set teacher_id=#{teacher_id},student_id=#{student_id},class_nub=#{class_nub},class_name=#{class_name},class_maxperson=#{class_maxperson},class_haveperson=#{class_haveperson},class_place=#{class_place} where id=#{id}")
void updateClassById(Class aClass);
例子:
@ResultMap("classDao")
@Delete("delete from class where id=#{id}")
void deleteClassById(Integer classId);
testClass.java
。例子:
//读取数据库配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//建造者模式创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//使用工厂模式生产SqlSession对象
SqlSession session = factory.openSession();
//使用SqlSession创建Dao接口的代理对象执行方法
ClassDao classDao = session.getMapper(ClassDao.class);
//使用代理对象执行方法
List<Class> aClass = classDao.findAll();
for (Class aClass1 : aClass) {
System.out.println(aClass1);
System.out.println(aClass1.getStudents());
}
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml").getMapper(ClassDao.class);
List<Class> aClass = classDao.findAll();
for (Class aClass1 : aClass) {
System.out.println(aClass1);
System.out.println(aClass1.getStudents());
}
public class TestClass {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private ClassDao classDao;
@Before
public void init() throws IOException {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
classDao = session.getMapper(ClassDao.class);
}
@After
public void destroy() throws IOException {
session.commit();
session.close();
in.close();
}
@Test
public void testFindClassById(){
List<Class> classes = classDao.findClassById(1);
for (Class aClass : classes) {
System.out.println(aClass);
}
}