个人博客:www.hellocode.top
⭐所有文章均在上方博客首发,其他平台同步更新
本文专栏:《Java Web从入门到实战》
> 如没有Java基础,请先前往《Java零基础指南》专栏学习相应知识
⚡如有问题,欢迎指正,一起学习~~
框架是一款半成品软件,我们可以基于这个半成品软件继续开发,来完成我们的个性化需求
数据库数据准备
导入 jar 包
在src 下创建映射配置文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="StudentMapper">
<select id="selectAll" resultType="mybaits.study.bean.Student">
SELECT * FROM student
select>
mapper>
在 src 下创建核心配置文件
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.23.129:3306/db1"/>
<property name="username" value="root"/>
<property name="password" value="密码"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="StudentMapper.xml">mapper>
mappers>
configuration>
编写测试类完成相关API 的使用
运行测试查看结果
package mybatis.study.dao;
import mybatis.study.bean.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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class StudentTest01 {
/*
* 查询全部
* */
@Test
public void selectAll() throws IOException {
// 1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
// 2. 获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 3.通过SqlSession工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.执行映射配置文件中的sql语句,并接收结果
List<Student> list = sqlSession.selectList("StudentMapper.selectAll");
// 5.处理结果
for(Student stu : list){
System.out.println(stu);
}
// 6.释放资源
sqlSession.close();
is.close();
}
}
Resources
返回值 | 方法名 | 说明 |
---|---|---|
InputStream | getResourcesAsStream(String fileName) | 通过类加载器返回指定资源的字节输入流 |
除了使用这个工具类的方法,还可以使用
类名.class.getClassLoader().getResourceAsStream(配置文件名.xml)
获取到字节输入流对象
SqlSessionFactoryBuilder
返回值 | 方法名 | 说明 |
---|---|---|
SqlSessionFactory | build(InputStream is) | 通过指定资源字节输入流获取SqlSession 工厂对象 |
SqlSessionFactory
返回值 | 方法名 | 说明 |
---|---|---|
SqlSession | openSession() | 获取SqlSession 构建者对象,并开启手动提交事务 |
SqlSession | openSession(boolean autoCommit) | 获取SqlSession构建者对象,如果参数为true,则开启自动提交事务 |
SqlSession
返回值 | 方法名 | 说明 |
---|---|---|
List | selectList(String statement,Object paramter) | 执行查询语句,返回List集合 |
T | selectOne(String statement,Object paramter) | 执行查询语句,返回一个结果对象 |
int | insert(String statement,Object paramter) | 执行新增语句,返回影响行数 |
int | update(String statement,Object paramter) | 执行修改语句,返回影响行数 |
int | delete(String statement,Object paramter) | 执行删除语句,返回影响行数 |
void | commit() | 提交事务 |
void | rollback() | 回滚事务 |
T | getMapper(Classcls) | 获取指定接口的代理实现类对象 |
void | close() | 释放资源 |
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="StudentMapper">
<select id="selectAll" resultType="mybaits.study.bean.Student">
SELECT * FROM student
select>
mapper>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="StudentMapper">
<select id="selectAll" resultType="mybatis.study.bean.Student">
SELECT * FROM student
select>
<select id="selectById" resultType="mybatis.study.bean.Student" parameterType="java.lang.Integer">
SELECT * FROM student WHERE id = #{参数名称}
select>
mapper>
@Test
public void selectById() throws IOException {
InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
Student stu = sqlSession.selectOne("StudentMapper.selectById", 1);
System.out.println(stu);
sqlSession.close();
is.close();
}
注意:属性名要和对象中的成员变量名称一致,才能获取到正确的值
<insert id="insert" parameterType="mybatis.study.bean.Student">
INSERT INTO student VALUES (#{id},#{name},#{age})
insert>
@Test
public void insert() throws IOException {
InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
Student stu = new Student(7,"老八",28);
int result = sqlSession.insert("StudentMapper.insert", stu);
// 如果没有开启自动提交事务,对于增删改,在执行完SQL后还需要提交事务
// sqlSession.commit();
System.out.println(result);
is.close();
sqlSession.close();
}
对于增删改操作,返回的的结果都是int类型的影响行数,故resultType可以省略不写
注意:属性名要和对象中的成员变量名称一致,才能获取到正确的值
<update id="update" parameterType="mybatis.study.bean.Student">
UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}
update>
@Test
public void update() throws IOException {
InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
Student stu = new Student(6,"周七七",37);
int result = sqlSession.insert("StudentMapper.update", stu);
// 如果没有开启自动提交事务,对于增删改,在执行完SQL后还需要提交事务
sqlSession.commit();
System.out.println(result);
is.close();
sqlSession.close();
}
<delete id="delete" parameterType="java.lang.Integer">
DELETE FROM student WHERE id = #{id}
delete>
@Test
public void delete() throws IOException {
InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
int result = sqlSession.delete("StudentMapper.delete", 7);
System.out.println(result);
// 提交事务
sqlSession.commit();
sqlSession.close();
is.close();
}
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.23.129:3306/db1"/>
<property name="username" value="root"/>
<property name="password" value="lh18391794828"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="StudentMapper.xml">mapper>
mappers>
configuration>
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.23.129
username=root
password=密码
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties">properties>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="StudentMapper.xml">mapper>
mappers>
configuration>
<typeAliases>
<typeAlias type="mybatis.study.bean.Student" alias="Student">typeAlias>
typeAliases>
在核心配置文件中起别名后,就可以简化映射配置文件中的全类名
MyBatis自带的一些别名
别名 | 数据类型 |
---|---|
string | java.lang.String |
long | java.lang.Long |
int | java.lang.Integer |
double | java.lang.Double |
boolean | java.lang.Boolean |
… | … |
在MyBatis中,持久层叫mapper
package mybatis.study.mapper;
import mybatis.study.bean.Student;
import java.util.List;
/*
* 持久层
* */
public interface StudentMapper {
// 查询全部
public abstract List<Student> selectAll();
// 根据id查询
public abstract Student selectById(Integer id);
// 新增数据
public abstract Integer insert(Student stu);
// 修改数据
public abstract Integer update(Student stu);
// 删除数据
public abstract Integer delete(Integer id);
}
package mybatis.study.mapper.impl;
import mybatis.study.bean.Student;
import mybatis.study.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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class StudentMapperImpl implements StudentMapper {
@Override
public List<Student> selectAll() {
InputStream is = null;
SqlSession sqlSession = null;
List<Student> list = null;
try{
is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
list = sqlSession.selectList("StudentMapper.selectAll");
}catch (Exception e){
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(sqlSession != null){
sqlSession.close();
}
}
return list;
}
@Override
public Student selectById(Integer id) {
InputStream is = null;
SqlSession sqlSession = null;
Student stu = null;
try{
is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
stu = sqlSession.selectOne("StudentMapper.selectById",id);
}catch (Exception e){
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(sqlSession != null){
sqlSession.close();
}
}
return stu;
}
@Override
public Integer insert(Student stu) {
InputStream is = null;
SqlSession sqlSession = null;
Integer result = null;
try{
is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
result = sqlSession.insert("StudentMapper.insert",stu);
}catch (Exception e){
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(sqlSession != null){
sqlSession.close();
}
}
return result;
}
@Override
public Integer update(Student stu) {
InputStream is = null;
SqlSession sqlSession = null;
Integer result = null;
try{
is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
result = sqlSession.update("StudentMapper.update",stu);
}catch (Exception e){
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(sqlSession != null){
sqlSession.close();
}
}
return result;
}
@Override
public Integer delete(Integer id) {
InputStream is = null;
SqlSession sqlSession = null;
Integer result = null;
try{
is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
result = sqlSession.delete("StudentMapper.delete",id);
}catch (Exception e){
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(sqlSession != null){
sqlSession.close();
}
}
return result;
}
}
package mybatis.study.service;
import mybatis.study.bean.Student;
import java.util.List;
/*
* 业务层
* */
public interface StudentService {
// 查询全部
public abstract List<Student> selectAll();
// 根据id查询
public abstract Student selectById(Integer id);
// 新增数据
public abstract Integer insert(Student stu);
// 修改数据
public abstract Integer update(Student stu);
// 删除数据
public abstract Integer delete(Integer id);
}
package mybatis.study.service.impl;
import mybatis.study.bean.Student;
import mybatis.study.mapper.StudentMapper;
import mybatis.study.mapper.impl.StudentMapperImpl;
import mybatis.study.service.StudentService;
import java.util.List;
public class StudentServiceImpl implements StudentService {
// 创建持久层对象
private StudentMapper mapper = new StudentMapperImpl();
@Override
public List<Student> selectAll() {
return mapper.selectAll();
}
@Override
public Student selectById(Integer id) {
return mapper.selectById(id);
}
@Override
public Integer insert(Student stu) {
return mapper.insert(stu);
}
@Override
public Integer update(Student stu) {
return mapper.update(stu);
}
@Override
public Integer delete(Integer id) {
return mapper.delete(id);
}
}
package mybatis.study.controller;
import mybatis.study.bean.Student;
import mybatis.study.service.StudentService;
import mybatis.study.service.impl.StudentServiceImpl;
import org.junit.Test;
import java.util.List;
/*
* 控制层测试类
* */
public class StudentController {
// 创建业务层对象
private StudentService service = new StudentServiceImpl();
@Test
public void selectAll(){
List<Student> stus = service.selectAll();
for(Student stu : stus){
System.out.println(stu);
}
}
@Test
public void selectById(){
Student stu = service.selectById(5);
System.out.println(stu);
}
@Test
public void insert(){
Student stu = new Student(5,"赵六",46);
Integer result = service.insert(stu);
System.out.println(result);
}
@Test
public void delete(){
Integer result = service.delete(5);
System.out.println(result);
}
@Test
public void update(){
Student stu = new Student(5,"赵六六",36);
Integer result = service.update(stu);
System.out.println(result);
}
}
LOG4J
<settings>
<setting name="logImpl" value="log4j"/>
settings>
# Global logging configuration
# 输出信息的显示。四个级别:ERROR、WARN、INFO、DEBUG
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
传统方式实现Dao层,我们既需要写接口,还要写实现类。而MyBatis 框架可以帮助我们省略编写 Dao层接口实现类的步骤。程序员只需要编写接口,由MyBatis 框架根据接口的定义来创建该接口的动态代理对象
实现规则
代码实现
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mybatis.study.mapper.StudentMapper">
<select id="selectAll" resultType="Student">
SELECT * FROM student
select>
<select id="selectById" resultType="Student" parameterType="int">
SELECT * FROM student WHERE id = #{id}
select>
<insert id="insert" parameterType="Student">
INSERT INTO student VALUES (#{id},#{name},#{age})
insert>
<update id="update" parameterType="Student">
UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}
update>
<delete id="delete" parameterType="int">
DELETE FROM student WHERE id = #{id}
delete>
mapper>
@Override
public List<Student> selectAll() {
InputStream is = null;
List<Student> list = null;
SqlSession sqlSession = null;
try{
// 1.加载核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
// 2. 获取SqlSessionFactory 工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 3. 获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
// 4.获取StudentMapper持久层接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
// 5.通过实现类对象调用方法,接收结果
list = mapper.selectAll();
}catch (Exception e){
e.printStackTrace();
}finally {
// 6.释放资源
if(sqlSession != null){
sqlSession.close();
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return list;
}
通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper()方法最终获取到org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,帮助我们生成了代理实现类对象,从而可以进行相关持久化操作
动态代理实现类对象在执行方法的时候最终调用了 mapperMethod.execute() 方法,这个方法中通过 switch语句根据操作类型来判断是新增、修改、删除、查询操作,最后一步回到了 MyBatis 最原生的 SqlSession 方式来执行增删改查
SELECT * FROM student WHERE id = ? AND name = ? AND age = ?
SELECT * FROM student WHERE id = ? AND name = ?
<if test="条件判断">
查询条件拼接
if>
<select id="selectCondition" resultType="student" parameterType="student">
SELECT * FROM student
<where>
<if test="id != null">
id = #{id}
if>
<if test="name != null">
AND name = #{name}
if>
<if test="age != null">
AND age = #{age}
if>
where>
select>
<foreach collection = "" open = "" close = "" item = "" separator = "">
获取参数
foreach>
<select id="selectByIds" resultType="Student" parameterType="list">
SELECT * FROM student
<where>
<foreach collection="list" open="id IN (" close=")" item="id" separator=",">
#{id}
foreach>
where>
select>
抽取的SQL语句
<sql id="select">SELECT * FROM studentsql>
<select id="selectAll" resultType="Student">
<include refid="select" />
select>
<select id="selectById" resultType="Student" parameterType="int">
<include refid="select" /> WHERE id = #{id}
select>
在企业级的开发中,分页也是一种常见的技术。而目前使用的 MyBatis 是不带分页功能的,如果想实现分页的功能,需要我们手动编写 LIMIT 语句。但是不同的数据库实现分页的 SQL 语句也是不同的,所以手写分页成本较高。这个时候可以借助分页插件来帮助我们实现分页功能
分页插件实现步骤
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
plugins>
分页参数的获取
返回值 | 方法名 | 说明 |
---|---|---|
long | getTotal() | 获取总条数 |
int | getPages() | 获取总页数 |
int | getPageNum() | 获取当前页 |
int | getPageSize() | 获取每页显示条数 |
int | getPrePage() | 获取上一页 |
int | getNextPage() | 获取下一页 |
boolean | isIsFirstPage() | 获取是否是第一页 |
boolean | isIsLastPage() | 获取是否是最后一页 |
@Test
public void selectPaging() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
// 通过分页助手实现分页功能
// 参数:当前页,显示的条数
PageHelper.startPage(1,3);
List<Student> list = mapper.selectAll();
for(Student stu : students){
System.out.println(stu);
}
//获取分页相关参数
PageInfo<Student> info = new PageInfo<>(list);
System.out.println("总条数" + info.getTotal());
System.out.println("总页数" + info.getPages());
System.out.println("当前页" + info.getPageNum());
System.out.println("每页条数" + info.getPageSize());
System.out.println("上一页" + info.getPrePage());
System.out.println("下一页" + info.getNextPage());
System.out.println("是否是第一页:" + info.isIsFirstPage());
System.out.println("是否是最后一页:" + info.isIsLastPage());
sqlSession.close();
is.close();
}
CREATE DATABASE db12;
USE db12;
CREATE TABLE person(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT
);
INSERT INTO person VALUES (NULL,'张三',23),(NULL,'李四',24),(NULL,'王五',25);
CREATE TABLE card(
id INT PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(30),
pid INT,
CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id)
);
INSERT INTO card VALUES (NULL,'12345',1),(NULL,'23456',2),(NULL,'34567',3);
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mybatis.study.table01.OneToOneMapper">
<resultMap id="oneToOne" type="card">
<id column="cid" property="id" />
<result column="number" property="number" />
<association property="p" javaType="person">
<id column="pid" property="id" />
<result column="name" property="name" />
<result column="age" property="age" />
association>
resultMap>
<select id="selectAll" resultMap="oneToOne">
SELECT c.id,number,pid,NAME,age FROM card c,person p WHERE c.pid = p.id;
select>
mapper>
@Test
public void selectAll() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);
List<Card> list = mapper.selectAll();
for(Card card : list){
System.out.println(card);
}
}
CREATE TABLE classes(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO classes VALUES (NULL,'一班'), (NULL,'二班');
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
age INT,
cid INT,
CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
);
INSERT INTO student VALUES (NULL,'张三',23,1),(NULL,'李四',24,1),(NULL,'王五',25,2),(NULL,'赵六',26,2);
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mybatis.study.table02.OneToManyMapper">
<resultMap id="oneToMany" type="classes">
<id column="cid" property="id" />
<result column="cname" property="name" />
<collection property="students" ofType="student">
<id column="sid" property="id" />
<result column="sname" property="name" />
<result column="sage" property="age" />
collection>
resultMap>
<select id="selectAll" resultMap="oneToMany">
SELECT c.id cid,c.name cname,s.id sid, s.name sname,s.age sage FROM classes c,student s WHERE c.id = s.cid;
select>
mapper>
@Test
public void selectAll() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);
List<Classes> classes = mapper.selectAll();
for(Classes cls : classes){
System.out.println(cls.getId() + "," + cls.getName());
List<Student> students = cls.getStudents();
for(Student stu : students){
System.out.println("\t" + stu);
}
}
}
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO course VALUES (NULL,'语文'),(NULL,'数学');
CREATE TABLE stu_cr(
id INT PRIMARY KEY AUTO_INCREMENT,
sid INT,
cid INT,
CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),
CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
);
INSERT INTO stu_cr VALUES (NULL,1,1),(NULL,1,2),(NULL,2,1),(NULL,2,2);
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mybatis.study.table03.ManyToManyMapper">
<resultMap id="manyToMany" type="student">
<id column="sid" property="id" />
<result column="sname" property="name" />
<result column="sage" property="age" />
<collection property="courses" ofType="course">
<id column="cid" property="id" />
<result column="cname" property="name" />
collection>
resultMap>
<select id="selectAll" resultMap="manyToMany">
SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname FROM student s,course c,stu_cr sc WHERE sc.sid = s.id AND sc.cid = c.id;
select>
mapper>
@Test
public void selectAll() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);
List<Student> students = mapper.selectAll();
for(Student stu : students){
System.out.println(stu.getId() + "," + stu.getName() + "," + stu.getAge());
List<Course> courses = stu.getCourses();
for(Course cour : courses){
System.out.println("\t" + cour);
}
}
}
@Select("查询的SQL语句")
:执行查询操作注解@Insert("新增的SQL语句")
:执行新增操作注解@Update("修改的SQL语句")
:执行修改操作注解@Delete("删除的SQL语句")
:执行删除操作注解<mappers>
<package name="mybatis.study.mapper" />
mappers>
@Test
public void selectAll() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectAll();
for (Student student : students) {
System.out.println(student);
}
}
// 新增操作
@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
public abstract Integer insert(Student stu);
@Test
public void insert() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student stu = new Student(null,"周七",27);
Integer result = mapper.insert(stu);
System.out.println(result);
}
修改、删除操作原理相同
一对一
// 查询全部
@Select("SELECT * FROM card")
@Results(
{
@Result(column = "id", property = "id"),
@Result(column = "number", property = "number"),
@Result(
property = "p", //被包含对象的变量名
javaType = Person.class, //被包含对象的实际数据类型
column = "pid", // 根据查询出的card表中的pid查询person表
// one、@One 是一对一操作的固定写法
// select属性:指定调用哪个接口中的哪个方法
one=@One(select = "mybatis.study.one_to_one.PersonMapper.selectById")
)
}
)
public abstract List<Card> selectAll();
// 根据id查询
@Select("SELECT * FROM student WHERE id = #{id}")
public abstract Person selectById(Integer id);
一对多
// 查询全部
@Select("SELECT * FROM classes")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(
property = "students",
javaType = List.class,
column = "id",
/*
* many、@Many 一对多查询的固定写法
* select:指定调用哪个接口中的哪个查询方法
* */
many=@Many(select = "mybatis.study.one_to_many.StudentMapper.selectByCid")
)
})
public abstract List<Classes> selectAll();
//根据cid查询student表
@Select("SELECT * FROM student WHERE cid = #{cid}")
public abstract List<Student> selectByCid(Integer cid);
多对多
// 查询全部
@Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "age",property = "age"),
@Result(
property = "courses",
javaType= List.class,
column = "id",
many = @Many(select = "mybatis.study.many_to_many.CourseMapper.selectBySid")
)
})
public abstract List<Student> selectAll();
// 根据学生id查询所选课程
@Select("SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid = #{id}")
public abstract List<Course> selectBySid(Integer id);
多对多中的一些注解和一对多一样,主要区别就是多对多中使用了第三张中间表
方法名 | 说明 |
---|---|
SELECT(String…column) | 根据字段拼接查询语句 |
FROM(String…table) | 根据表名拼接语句 |
WHERE(String…condition) | 根据条件拼接语句 |
INSERT_INTO(String table) | 根据表名拼接新增语句 |
VALUES(String column,String values) | 根据字段和值拼接插入数据语句 |
UPDATE(String table) | 根据表名拼接修改语句 |
DELETE_FROM(String table) | 根据表名拼接删除语句 |
… … | … … |
public static String getSql(){
String sql = new SQL(){
{
SELECT("*");
FROM("student");
}
}.toString();
return sql;
}
// 查询全部
// @Select("SELECT * FROM student")
@SelectProvider(type = ReturnSql.class, method = "getSelectAll")
public abstract List<Student> selectAll();
// 定义方法,返回新增的sql语句
public String getInsert(Student stu){
return new SQL(){
{
INSERT_INTO("student");
INTO_VALUES("#{id},#{name},#{age}");
}
}.toString();
}
// 新增操作
// @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
@InsertProvider(type = ReturnSql.class,method = "getInsert")
public abstract Integer insert(Student stu);
// 定义方法,返回修改的SQL语句
public String getUpdate(Student stu){
return new SQL(){
{
UPDATE("student");
SET("name=#{name}","age=#{age}");
WHERE("id=#{id}");
}
}.toString();
}
// 修改操作
//@Update("UPDATE student SET name=#{name},age=#{age} WHERE id = #{id}")
@UpdateProvider(type = ReturnSql.class,method = "getUpdate")
public abstract Integer update(Student stu);
// 定义方法,返回删除的sql语句
public String getDelete(Integer id){
return new SQL(){
{
DELETE_FROM("student");
WHERE("id=#{id}");
}
}.toString();
}
// 删除操作
//@Delete("DELETE FROM student WHERE id = #{id}")
@DeleteProvider(type = ReturnSql.class,method = "getDelete")
public abstract Integer delete(Integer id);
推荐阅读:【JavaWEB】JavaScript基础