|
一.Mybatis注解开发单表操作
1.1 MyBatis的常用注解
这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper
映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
@Insert(“新增的SQL语句”)∶执行新增操作注解
@Delete(“删除的SQL语句”)︰执行删除操作注解
@Update(“修改的SQL语句”)∶执行修改操作注解
@Select(“查询的SQL语句”)∶执行查询操作注解
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
1.2 MyBatis的增删改查
注解开发实现查询操作
数据 库准备
CREATE DATABASE db25;
USE db25;
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
age INT
);
INSERT INTO student VALUES (NULL,'张三',17);
INSERT INTO student VALUES (NULL,'李四',18);
INSERT INTO student VALUES (NULL,'王五',19);
INSERT INTO student VALUES (NULL,'赵六',20);maven引入坐标
<!--导包 以坐标的方式 -->
<!-- dependencies 依赖包 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.jsqlparser/jsqlparser -->
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>3.1</version>
</dependency>
</dependencies>数据库连接配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db25
username=root
password=123456日志配置文件
# Global logging configuration
# ERROR 错误信息
# WARN 警告信息
# INFO 普通信息
# DEBUG
# stdout 信息输出到控制台
log4j.rootLogger=DEBUG, stdout
# Console output...
# 输出格式
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n创建接口和查询方法
package com.itss.mapper;
import com.itss.bean.Student;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author IT苏苏
* @className StudentMapper.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 26 日 09 9:14:38
**/
public interface StudentMapper {
// 查询全部
@Select(&#34;SELECT * FROM student&#34;)//通过注解来查询 省略了映射配置文件
public abstract List<Student> selectAll();
}
在核心配置文件中配置映射关系
<?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34; ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC &#34;-//mybatis.org//DTD Config 3.0//EN&#34; &#34;http://mybatis.org/dtd/mybatis-3-config.dtd&#34;>
<!--configuration 核心根标签-->
<configuration>
<!-- <properties> :引入数据库连接配置文件标签。
属性 resource:数据库连接配置文件路径-->
<properties resource=&#34;jdbc.properties&#34;/>
<!--配置 log4j -->
<settings>
<setting name=&#34;logImpl&#34; value=&#34;log4j&#34;/>
</settings>
<!--<typeAliases>:为全类名起别名的父标签。-->
<typeAliases>
<!--通用方式 在bean包下所有的类一起 起别名
别名就是类名 例如 bean包下的Card类 别名就为 card -->
<package name=&#34;com.itss.bean&#34;/>
</typeAliases>
<!--集成分页插件助手
plugin指定集成第三方插件
interceptor指定插件的全类名-->
<plugins>
<plugin interceptor=&#34;com.github.pagehelper.PageInterceptor&#34;></plugin>
</plugins>
<!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
<environments default=&#34;mysql&#34;>
<!--environment配置数据库环境 id属性唯一标识-->
<environment id=&#34;mysql&#34;><!-- environments 要与 environment 一样 表示要使用哪一个 environment 就将environments 更改成一样-->
<!-- transactionManager事务管理。 type属性,采用JDBC默认的事务-->
<transactionManager type=&#34;JDBC&#34;></transactionManager>
<!-- dataSource数据源信息 type属性 连接池-->
<dataSource type=&#34;POOLED&#34;>
<!-- property获取数据库连接的配置信息 数据库连接配置文件引入后 -->
<property name=&#34;driver&#34; value=&#34;${driver}&#34;/>
<property name=&#34;url&#34; value=&#34;${url}&#34;/>
<property name=&#34;username&#34; value=&#34;${username}&#34;/>
<property name=&#34;password&#34; value=&#34;${password}&#34;/>
</dataSource>
</environment>
</environments>
<!--配置映射关系-->
<mappers>
<!--在核心配置文件中指定接口的包-->
<!--指定接口包的路径-->
<package name=&#34;com.itss.mapper&#34;/>
</mappers>
</configuration>
编写测试类
package com.itss.test;
import com.itss.bean.Student;
import com.itss.mapper.StudentMapper;
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.Test;
import java.io.InputStream;
import java.util.List;
/**
* @author IT苏苏
* @className Test01.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 26 日 09 9:22:09
**/
/*
* //1.加载核心配置文件
//2.获取Sq1Session工厂对象
//3.通过工厂对象获取Sq1Session对象
//4.获取StudentMapper接口的实现类对象
//5.调用实现类对象中的方法,接收结果
//6.处理结果
//7.释放资源*/
public class Test01 {
@Test
public void selectAll() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Student> list = mapper.selectAll();
//6.处理结果
for (Student student : list
) {
System.out.println(student);
}
//7.释放资源
sqlSession.close();
is.close();
}
}
运行结果

注解实现新增操作
创建新增方法 在接口内新增 新增方法
// 新增操作
@Insert(&#34;INSERT INTO student VALUES (#{id},#{name},#{age})&#34;)
public abstract Integer insert(Student student);编写测试类
@Test
public void insert() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Student stu = new Student(5, &#34;新增的学生姓名&#34;, 18);
Integer result = mapper.insert(stu);
//6.处理结果
System.out.println(&#34;影响行数:&#34; + result);
//7.释放资源
sqlSession.close();
is.close();
}运行结果

注解实现修改操作
创建修改方法
// 修改操作
@Update(&#34;UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}&#34;)
public abstract Integer update(Student student);编写测试类
@Test
public void update() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Student stu = new Student(5, &#34;新增的学生姓名&#34;, 99);
Integer result = mapper.update(stu);
//6.处理结果
System.out.println(&#34;影响行数:&#34; + result);
//7.释放资源
sqlSession.close();
is.close();
}运行结果

注解实现删除操作
创建删除方法
// 删除操作
@Delete(&#34;DELETE FROM student WHERE id=#{id}&#34;)
public abstract Integer delete(Integer id);编写测试类
@Test
public void delete() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Integer result = mapper.delete(6);
//6.处理结果
System.out.println(&#34;影响行数:&#34; + result);
//7.释放资源
sqlSession.close();
is.close();
}运行结果 删除 id为6 的学生信息

1.3 注解开发总结
注解可以简化开发操作,省略映射配置文件的编写。
- 常用注解
@Select(“查询的 SQL 语句”):执行查询操作注解
@Insert(“查询的 SQL 语句”):执行新增操作注解
@Update(“查询的 SQL 语句”):执行修改操作注解
@Delete(“查询的 SQL 语句”):执行删除操作注解
- 配置映射关系
<mappers> <package name=&#34;接口所在包&#34;/> </mappers> 二.MyBatis注解开发的多表操作
2.1 MyBatis的注解实现复杂映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置


2.2 一对一查询
2.2.1 一对一查询的模型
一对一查询的需求:查询一个用户信息,与此同时查询出该用户对应的身份证信息

数据库 表准备

创建Card类
package com.itss.bean;
/**
* @author IT苏苏
* @className Card.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 24 日 20 20:22:58
**/
public class Card {
private Integer id;//主键id
private String number;//身份证号
private Person p;//所属人的对象
public Card() {
}
public Card(Integer id, String number, Person p) {
this.id = id;
this.number = number;
this.p = p;
}
@Override
public String toString() {
return &#34;Card{&#34; +
&#34;id=&#34; + id +
&#34;, number=&#39;&#34; + number + &#39;\&#39;&#39; +
&#34;, p=&#34; + p +
&#39;}&#39;;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Person getP() {
return p;
}
public void setP(Person p) {
this.p = p;
}
}
创建Person类
package com.itss.bean;
/**
* @author IT苏苏
* @className Person.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 24 日 20 20:20:06
**/
public class Person {
private Integer id;//主键id
private String name;//人的姓名
private Integer age;//人的年龄
public Person() {
}
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return &#34;Person{&#34; +
&#34;id=&#34; + id +
&#34;, name=&#39;&#34; + name + &#39;\&#39;&#39; +
&#34;, age=&#34; + age +
&#39;}&#39;;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
}

2.2.2 一对一查询的语句
对应的sql语句:
SELECT * FROM card;
SELECT * FROM person WHERE id=#{id};2.2.3 创建PersonMapper接口
package com.itss.one_to_one;
import com.itss.bean.Person;
import org.apache.ibatis.annotations.Select;
/**
* @author IT苏苏
* @className PersonMapper.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 26 日 15 15:11:01
**/
public interface PersonMapper {
// 根据id查询
@Select(&#34;SELECT * FROM person WHERE id=#{id}&#34;)
public abstract Person selectById(Integer id);
}
2.2.4 创建CardMapper接口 使用注解配置Mapper

package com.itss.one_to_one;
import com.itss.bean.Card;
import com.itss.bean.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author IT苏苏
* @className CardMapper.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 26 日 15 15:10:41
**/
public interface CardMapper {
// 查询全部
@Select(&#34;SELECT * FROM card&#34;)
@Results({
@Result(column =&#34;id&#34;, property = &#34;id&#34;),
@Result(column = &#34;number&#34;,property = &#34;number&#34;),
@Result(
property = &#34;p&#34;,//被包含对象的变量
javaType = Person.class,//被包含对象的实际数据类型
column = &#34;pid&#34;,//根据查询出的card表中低端pid字段来查询person表
/*
* One @One 一对一固定写法
* select属性:指定调用哪个接口中的哪个方法*/
one = @One(select = &#34;com.itss.one_to_one.PersonMapper.selectById&#34;)
)
})
public abstract List<Card> selectAll();
}
配置核心配置文件

2.2.5 测试类
package com.itss.one_to_one;
import com.itss.bean.Card;
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.Test;
import java.io.InputStream;
import java.util.List;
/**
* @author IT苏苏
* @className Test01.java
* @Form no
* @Description ToDo
* @createTime 2022 年 11 月 26 日 15 15:15:09
**/
public class Test01 {
@Test
public void selectAll() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
CardMapper mapper = sqlSession.getMapper(CardMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Card> list = mapper.selectAll();
//6.处理结果
for (Card card : list
) {
System.out.println(card);
}
//7.释放资源
sqlSession.close();
is.close();
}
}
2.2.6 一对一配置总结
@Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
one 属性:一对一查询固定属性
@One:一对一查询的注解。
select 属性:指定调用某个接口中的方法2.3 一对多查询
2.3.1 一对多查询的模型
一对多查询的需求:查询一个课程,与此同时查询出该该课程对应的学生信息

2.3.3 创建StudentMapper接口
public interface StudentMapper {
//根据cid查询student表
@Select(&#34;SELECT * FROM student WHERE cid=#{cid}&#34;)
public abstract List<Student> selectByCid(Integer cid);
}
2.3.4 使用注解配置Mapper
public interface ClassesMapper {
//查询全部
@Select(&#34;SELECT * FROM classes&#34;)
@Results({
@Result(column = &#34;id&#34;,property = &#34;id&#34;),
@Result(column = &#34;name&#34;,property = &#34;name&#34;),
@Result(
property = &#34;students&#34;, // 被包含对象的变量名
javaType = List.class, // 被包含对象的实际数据类型
column = &#34;id&#34;, // 根据查询出的classes表的id字段来查询student表
/*
many、@Many 一对多查询的固定写法
select属性:指定调用哪个接口中的哪个查询方法
*/
many = @Many(select = &#34;com.itss.one_to_many.StudentMapper.selectByCid&#34;)
)
})
public abstract List<Classes> selectAll();
}2.3.5 测试类
public class Test01 {
@Test
public void selectAll() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取ClassesMapper接口的实现类对象
ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Classes> list = mapper.selectAll();
//6.处理结果
for (Classes cls : list) {
System.out.println(cls.getId() + &#34;,&#34; + cls.getName());
List<Student> students = cls.getStudents();
for (Student student : students) {
System.out.println(&#34;\t&#34; + student);
}
}
//7.释放资源
sqlSession.close();
is.close();
}
}2.3.6 一对多配置总结
@Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
many 属性:一对多查询固定属性
@Many:一对多查询的注解。
select 属性:指定调用某个接口中的方法2.4 多对多查询
2.4.1 多对多查询的模型
多对多查询的需求:查询学生以及所对应的课程信息

2.4.2 多对多查询的语句
对应的sql语句:
SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id
SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}2.4.3 添加CourseMapper 接口方法
public interface CourseMapper {
//根据学生id查询所选课程
@Select(&#34;SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}&#34;)
public abstract List<Course> selectBySid(Integer id);
}
2.4.4 使用注解配置Mapper
public interface StudentMapper {
//查询全部
@Select(&#34;SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id&#34;)
@Results({
@Result(column = &#34;id&#34;,property = &#34;id&#34;),
@Result(column = &#34;name&#34;,property = &#34;name&#34;),
@Result(column = &#34;age&#34;,property = &#34;age&#34;),
@Result(
property = &#34;courses&#34;, // 被包含对象的变量名
javaType = List.class, // 被包含对象的实际数据类型
column = &#34;id&#34;, // 根据查询出student表的id来作为关联条件,去查询中间表和课程表
/*
many、@Many 一对多查询的固定写法
select属性:指定调用哪个接口中的哪个查询方法
*/
many = @Many(select = &#34;com.itss.many_to_many.CourseMapper.selectBySid&#34;)
)
})
public abstract List<Student> selectAll();
}2.4.5 测试类
public class Test01 {
@Test
public void selectAll() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Student> list = mapper.selectAll();
//6.处理结果
for (Student student : list) {
System.out.println(student.getId() + &#34;,&#34; + student.getName() + &#34;,&#34; + student.getAge());
List<Course> courses = student.getCourses();
for (Course cours : courses) {
System.out.println(&#34;\t&#34; + cours);
}
}
//7.释放资源
sqlSession.close();
is.close();
}
}2.4.6 多对多配置总结
@Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
many 属性:一对多查询固定属性
@Many:一对多查询的注解。
select 属性:指定调用某个接口中的方法三.构建sql
3.1 SQL 构建对象介绍
- 我们之前通过注解开发时,相关 SQL 语句都是自己直接拼写的。一些关键字写起来比较麻烦、而且容易出错。
- MyBatis 给我们提供了 org.apache.ibatis.jdbc.SQL 功能类,专门用于构建 SQL 语句

手动编sql与利用sql功能类编写sql语句对比
package com.itss.sql;
import org.apache.ibatis.jdbc.SQL;
public class sqlTest {
public static void main(String[] args) {
String sql = getSql();
System.out.println(&#34;手动编写的sql:&#34; + sql);
System.out.println(&#34;----------------------&#34;);
String toSql = getToSql();
System.out.println(&#34;利用sql功能类编写的sql:&#34; + toSql);
}
private static String getSql() {
String sql = &#34;SELECT * FROM student&#34;;
return sql;
}
private static String getToSql() {
String sql = new SQL() {
{
SELECT(&#34;*&#34;);
FROM(&#34;student&#34;);
}
}.toString();
return sql;
}
}

运行结果一样 但是用sql功能类编写可以减小代码的出错率
3.2 查询功能的实现
public class ReturnSql {
// 定义方法,返回查询的sql语句
public String getSelectAll() {
return new SQL() {
{
SELECT(&#34;*&#34;);
FROM(&#34;student&#34;);
}
}.toString();
}
}
- @SelectProvider:生成查询用的 SQL 语句注解。
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法
// 查询全部
// @Select(&#34;SELECT * FROM student&#34;)//通过注解来查询 省略了映射配置文件
// type:功能类对象 method:具体调用的方法
@SelectProvider(type = ReturnSql.class, method = &#34;getSelectAll&#34;)
public abstract List<Student> selectAll();测试方法
@Test
public void selectAll() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Student> list = mapper.selectAll();
//6.处理结果
for (Student student : list
) {
System.out.println(student);
}
//7.释放资源
sqlSession.close();
is.close();
}3.3 新增功能的实现
// 定义方法,返回新增的sql语句
public String getInsert(Student student) {
return new SQL() {{
INSERT_INTO(&#34;student&#34;);
INTO_VALUES(&#34;#{id},#{name},#{age}&#34;);
}}.toString();
}
- @InsertProvider:生成新增用的 SQL 语句注解。
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法
// 新增操作
// @Insert(&#34;INSERT INTO student VALUES (#{id},#{name},#{age})&#34;)
@InsertProvider(type = ReturnSql.class, method = &#34;getInsert&#34;)
public abstract Integer insert(Student student);测试方法
@Test
public void insert() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Student stu = new Student(5, &#34;新增的学生姓名&#34;, 18);
Integer result = mapper.insert(stu);
//6.处理结果
System.out.println(&#34;影响行数:&#34; + result);
//7.释放资源
sqlSession.close();
is.close();
}3.4 修改功能的实现
// 定义方法,返回修改的sql语句
public String getUpdate(Student student) {
return new SQL() {
{
UPDATE(&#34;student&#34;);
SET(&#34;name=#{name}&#34;,&#34;age=#{age}&#34;);
WHERE(&#34;id=#{id}&#34;);
}
}.toString();
}
- @UpdateProvider:生成修改用的 SQL 语句注解。
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法
// 修改操作
// @Update(&#34;UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}&#34;)
@UpdateProvider(type = ReturnSql.class, method = &#34;getUpdate&#34;)
public abstract Integer update(Student student);测试方法
@Test
public void update() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Student stu = new Student(5, &#34;新增的学生姓名&#34;, 99);
Integer result = mapper.update(stu);
//6.处理结果
System.out.println(&#34;影响行数:&#34; + result);
//7.释放资源
sqlSession.close();
is.close();
}3.5 删除功能的实现
// 定义方法,返回删除的sql语句
public String getDelete(Integer id) {
return new SQL() {
{
DELETE_FROM(&#34;student&#34;);
WHERE(&#34;id=#{id}&#34;);
}
}.toString();
}
- @DeleteProvider:生成删除用的 SQL 语句注解。
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法
// 删除操作
// @Delete(&#34;DELETE FROM student WHERE id=#{id}&#34;)
@DeleteProvider(type = ReturnSql.class, method = &#34;getDelete&#34;)
public abstract Integer delete(Integer id);测试方法
@Test
public void delete() throws Exception {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取Sq1Session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取Sq1Session对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Integer result = mapper.delete(5);
//6.处理结果
System.out.println(&#34;影响行数:&#34; + result);
//7.释放资源
sqlSession.close();
is.close();
}构建SQL语句小结
org.apache.ibatis.jdbc.SQL:构建SQL语句的功能类。通过一些方法来代替SQL语句的关键字。
SELECT()
FROM()
WHERE()
INSERT_INT()
VALUES()
UPDATE()
DELETE_FROM()
@SelectProvider :生成查询用的SQL语句注解。
@lnsertProvider:生成新增用的SQL语句注解。
@UpdateProvider:生成修改用的SQL语句注解。
@DeleteProvider :生成删除用的SQL语句注解。
type属性︰生成SQL语句功能类对象
method属性:指定调用方法
四.综合案例
4.1 系统介绍
我们之前在做学生管理系统时,使用的是原始JDBC操作数据库的,操作非常麻烦,现在我们使用MyBatis操作数据库,简化Dao的开发。
4.2 环境搭建(略)
数据库
-- 创建db26数据库
CREATE DATABASE db26;
-- 使用db26数据库
USE db26;
-- 创建用户表
CREATE TABLE USER(
uid VARCHAR(50) PRIMARY KEY, -- 用户id
ucode VARCHAR(50), -- 用户标识
loginname VARCHAR(100), -- 登录用户名
PASSWORD VARCHAR(100), -- 登录密码
username VARCHAR(100), -- 用户名
gender VARCHAR(10), -- 用户性别
birthday DATE, -- 出生日期
dutydate DATE -- 入职日期
);
-- 添加一条测试数据
INSERT INTO USER VALUES (&#39;11111111&#39;, &#39;zhangsan001&#39;, &#39;zhangsan&#39;, &#39;1234&#39;, &#39;张三&#39;, &#39;男&#39;, &#39;2008-10-28&#39;, &#39;2018-10-28&#39;);
-- 创建student表
CREATE TABLE student(
sid INT PRIMARY KEY AUTO_INCREMENT, -- 学生id
NAME VARCHAR(20), -- 学生姓名
age INT, -- 学生年龄
birthday DATE -- 学生生日
);
-- 添加数据
INSERT INTO student VALUES (NULL,&#39;张三&#39;,23,&#39;1999-09-23&#39;),(NULL,&#39;李四&#39;,24,&#39;1998-08-10&#39;),
(NULL,&#39;王五&#39;,25,&#39;1996-06-06&#39;),(NULL,&#39;赵六&#39;,26,&#39;1994-10-20&#39;);4.3 代码改造
- 步骤一:新增MyBatis配置文件 MyBatisConfig.xml
<?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34; ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC &#34;-//mybatis.org//DTD Config 3.0//EN&#34; &#34;http://mybatis.org/dtd/mybatis-3-config.dtd&#34;>
<!--configuration 核心根标签-->
<configuration>
<!--引入数据库连接的配置文件-->
<properties resource=&#34;config.properties&#34;/>
<!--配置LOG4J-->
<settings>
<setting name=&#34;logImpl&#34; value=&#34;log4j&#34;/>
</settings>
<!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
<environments default=&#34;mysql&#34;>
<!--environment配置数据库环境 id属性唯一标识-->
<environment id=&#34;mysql&#34;>
<!-- transactionManager事务管理。 type属性,采用JDBC默认的事务-->
<transactionManager type=&#34;JDBC&#34;></transactionManager>
<!-- dataSource数据源信息 type属性 连接池-->
<dataSource type=&#34;POOLED&#34;>
<!-- property获取数据库连接的配置信息 -->
<property name=&#34;driver&#34; value=&#34;${driver}&#34; />
<property name=&#34;url&#34; value=&#34;${url}&#34; />
<property name=&#34;username&#34; value=&#34;${username}&#34; />
<property name=&#34;password&#34; value=&#34;${password}&#34; />
</dataSource>
</environment>
</environments>
<!--配置映射关系-->
<mappers>
<package name=&#34;com.itss&#34;/>
</mappers>
</configuration>步骤二: 删除StudentDaoImpl,修改StudentDao
package com.itheima.dao;
import com.itheima.domain.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.ArrayList;
/*
Dao层接口
*/
public interface StudentDao {
//查询所有学生信息
@Select(&#34;SELECT * FROM student&#34;)
public abstract ArrayList<Student> findAll();
//条件查询,根据id获取学生信息
@Select(&#34;SELECT * FROM student WHERE sid=#{sid}&#34;)
public abstract Student findById(Integer sid);
//新增学生信息
@Insert(&#34;INSERT INTO student VALUES (#{sid},#{name},#{age},#{birthday})&#34;)
public abstract int insert(Student stu);
//修改学生信息
@Update(&#34;UPDATE student SET name=#{name},age=#{age},birthday=#{birthday} WHERE sid=#{sid}&#34;)
public abstract int update(Student stu);
//删除学生信息
@Delete(&#34;DELETE FROM student WHERE sid=#{sid}&#34;)
public abstract int delete(Integer sid);
}步骤三:修改`StudentServiceImpl`
* 步骤三:修改`StudentServiceImpl`
~~~java
package com.itheima.service.impl;
import com.itheima.dao.StudentDao;
import com.itheima.domain.Student;
import com.itheima.service.StudentService;
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.ArrayList;
import java.util.List;
/**
* 学生的业务层实现类
*/
public class StudentServiceImpl implements StudentService {
@Override
public List<Student> findAll() {
ArrayList<Student> list = null;
SqlSession sqlSession = null;
InputStream is = null;
try{
//1.加载核心配置文件
is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentDao接口的实现类对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//5.调用实现类对象的方法,接收结果
list = mapper.findAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//7.返回结果
return list;
}
@Override
public Student findById(Integer sid) {
Student stu = null;
SqlSession sqlSession = null;
InputStream is = null;
try{
//1.加载核心配置文件
is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentDao接口的实现类对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//5.调用实现类对象的方法,接收结果
stu = mapper.findById(sid);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//7.返回结果
return stu;
}
@Override
public void save(Student student) {
SqlSession sqlSession = null;
InputStream is = null;
try{
//1.加载核心配置文件
is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentDao接口的实现类对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//5.调用实现类对象的方法,接收结果
mapper.insert(student);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void update(Student student) {
SqlSession sqlSession = null;
InputStream is = null;
try{
//1.加载核心配置文件
is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentDao接口的实现类对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//5.调用实现类对象的方法,接收结果
mapper.update(student);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void delete(Integer sid) {
SqlSession sqlSession = null;
InputStream is = null;
try{
//1.加载核心配置文件
is = Resources.getResourceAsStream(&#34;MyBatisConfig.xml&#34;);
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentDao接口的实现类对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//5.调用实现类对象的方法,接收结果
mapper.delete(sid);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} |
|