mybatis的使用
一、准备条件
1.创建maven工程(quickstart)
2.更改字符集 utf-8(三处地方 :pom.xml module处 java compiler)
3.导入需要使用的依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
二、创建实体类(sql中一条数据映射出来的实体)
注:实体类的属性即是sql表中的字段名,名称可以不一致(但不一致后续userMapper.xml中要设置parameterMap,避免麻烦一般都写成相同的)
eg:如图是根据kb12数据库中的studentinfo表来映射数据,因此创建Student实体类,并构造有参构造方法、无参构造方法,setter/getter方法,重写toString方法
ps:主要注意的是resources 下的userMapper.xml 文件所在的目录结构需要和所写的userMapper
接口的目录结构相同
如下为Student类中的方法
参数类型都写成引用数据类型,是为了后期的xml文件中进行判断时能更方便的写
package org.example.entity;
public class Student {
private Integer stuId;
private String stuName;
private Integer stuAge;
private String stuGender;
private String mobile;
private Double tuition;
private Integer fkClassId;
public Student(Integer stuId, String stuName, Integer stuAge, String stuGender, String mobile, Double tuition, Integer fkClassId) {
this.stuId = stuId;
this.stuName = stuName;
this.stuAge = stuAge;
this.stuGender = stuGender;
this.mobile = mobile;
this.tuition = tuition;
this.fkClassId = fkClassId;
}
public Student() {
}
public Integer getStuId() {
return stuId;
}
public String getStuName() {
return stuName;
}
public Integer getStuAge() {
return stuAge;
}
public String getStuGender() {
return stuGender;
}
public String getMobile() {
return mobile;
}
public Double getTuition() {
return tuition;
}
public Integer getFkClassId() {
return fkClassId;
}
public void setStuId(Integer stuId) {
this.stuId = stuId;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public void setStuAge(Integer stuAge) {
this.stuAge = stuAge;
}
public void setStuGender(String stuGender) {
this.stuGender = stuGender;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public void setTuition(Double tuition) {
this.tuition = tuition;
}
public void setFkClassId(Integer fkClassId) {
this.fkClassId = fkClassId;
}
@Override
public String toString() {
return "Student{" +
"stuId=" + stuId +
", stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
", stuGender='" + stuGender + '\'' +
", mobile='" + mobile + '\'' +
", tuition=" + tuition +
", fkClassId=" + fkClassId +
'}';
}
}
创建UserMapper接口 内容如下:
接口中的方法就是定义对sql数据需要做的增删改查等操作
package org.example.mapper;
import org.example.entity.Student;
import java.util.List;
public interface UserMapper {
//增删改返回值为affectrows,select的语句在不做分组的时候聚合返回也是一个数字
int add(Student student);
int addBatch(List<Student> list);
//学号的数组
int delete(int[] array);
int update(Student student);
List<Student> findBy(Student student);
}
三、配置配置文件【重点:相当于把jdbc中的方法都封装到这个文件中来完成】
1按找第一张的截图的要点,创建好目录结构,创建userMapper.xml文件[跟对应的接口名字相同,只是首字母要小写]
userMapper.xml文件头的格式是固定的 如下:
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserMapper">
//此处填写接口方法中的具体实现
</mapper>
增加数据
insert id=“接口中设定方法名称”
parameterType=“输入参数的类型” [若实体类的属性和sql中的列名不一致,则需要使用parameterMap]
resultType=“返回值的类型”[当返回值是带有泛型的集合时,此处要填写的时泛型的类型,本文下文中的返回值类型所填写的就是Student]
foreach的作用相当于循环
<insert id="add" parameterType="Student">
insert into studentinfo(stuId,stuName,stuAge,stuGender,mobile,tuition,fkClassId) values
(#{stuId},#{stuName},#{stuAge},#{stuGender},#{mobile},#{tuition},#{fkClassId})
</insert>
<insert id="addBatch">
insert into studentinfo(stuId,stuName,stuAge,stuGender,mobile,tuition,fkClassId) values
<foreach collection="list" item="stu" separator=",">
(#{stu.stuId},#{stu.stuName},#{stu.stuAge},#{stu.stuGender},#{stu.mobile},#{stu.tuition},#{stu.fkClassId})
</foreach>
</insert>
删除操作
输入参数未带泛型的list,int[ ], map时,这里无需指定类型
open “(”
close")"
指定了循环开始和结束的位置上拼接这两个符号(因此可以成为一个完整的sql语句)
#{xxx} 是xml文件中取得对应属性值的写法,是我们在写sql时输入的值
<delete id="delete">
delete from studentinfo where stuId in
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
更改操作
set标签:复杂动态的修改 多条件时自动除去最后一个逗号【注意,此处的代码后面都有一个逗号】
if标签:相当于单分支条件,当满足这个条件时,才会进入执行相对应的操作。
实体类的属性使用引用数据类型是为了在此处判断的时候可以全部写成如下 null != xxxx 的格式;
<update id="update" parameterType="Student" >
update studentinfo
<set>
<if test="null != stuName">
stuName=#{stuName},
</if>
<if test="null != stuAge">
stuAge=#{stuAge},
</if>
<if test="null != stuGender">
stuGender=#{stuGender},
</if>
<if test="null != mobile">
mobile=#{mobile},
</if>
<if test="null != tuition">
tuition=#{tuition},
</if>
<if test="fkClassId != null">
fkClassId=#{fkClassId},
</if>
</set>
where stuId=#{stuId}
</update>
查询操作
where标签用于动态的复杂查询,内部嵌套choose,when,otherwise标签用于多分支的查询;
需要注意的是:when 内部写的是配有主键或唯一键的选择,当sql语句中有该条件时,otherwise中的条件不会再去匹配,简单意义理解为,这样写的情况下只能筛选一个条件的数据。若想实现多条件的组合筛选,内部需要写成if 标签组成的但分支结构【此时 if 标签需要写上and,动态组合时会自动删除第一个and】
<select id="findBy" resultType="Student" parameterType="Student">
select * from studentinfo
<where>
<choose>
<when test="null != stuId">
stuId=#{stuId}
</when>
<when test="null != mobile">
mobile=#{mobile}
</when>
<otherwise>
<if test="stuAge != null">
and stuAge=#{stuAge}
</if>
<if test="null != stuName">
and stuName like concat(#{stuName},%)
</if>
<if test="null != stuGender">
and stuGender=#{stuGender}
</if>
<if test="null != fkClassId">
and fkClassId=#{fkClassId}
</if>
<if test="null != tuition">
and tuition>=#{tuition}
</if>
</otherwise>
</choose>
</where>
</select>
</mapper>
四、配置mybatis的主配置文件【文件头格式固定,内部configuration需要指定】
文件头固定,configuration内部的配置需要自己指定【大致格式相同】
properties resouce 指向datasource.properties文件,内容是jdbc连接mysql的相关配置 内容如下:
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://192.168.17.130:3306/kb12?&useSSL=false&useUnicode=true
mysql.username=root
mysql.password=12345678
typeAliases 中的package neme 指像java中所写的实体类
mappers中的 package name 指向mapper接口所在的包。好处在于
该包下之后添加的文件都不需要二次指定,但若mapper标签使用的是 resource|class ,那二者二选一,且之后添加的需要二次指定
<?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 resource="datasource.properties"/>
<typeAliases>
<package name="org.example.entity"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="org.example.mapper"/>
</mappers>
</configuration>
五、测试
测试类大抵相同,主要靠UserMapper对象来操作,且sqlSession是需要手动关闭的
package org.example;
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.example.entity.Student;
import org.example.mapper.UserMapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Hello world!
*
*/
public class App {
public static void main( String[] args ) throws IOException {
final String RESOURCES = "mybatis.xml";
InputStream stream = Resources.getResourceAsStream(RESOURCES);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
SqlSession sqlSession = factory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
/* add的实验
Student a = new Student(59,"batis",59,"男","11311311311",55555.2,3);
mapper.add(a);*/
/*
addBatch的实验
Student a = new Student(59,"batis",59,"男","11311311311",55555.2,3);
List<Student> list = new ArrayList<>();
list.add(a);
mapper.add(list);*/
// delete的实验
// mapper.delete(new int[]{1,2,3});
/*
update 操作的实验
Student b = new Student();
b.setStuId(59);
b.setStuAge(33);
b.setFkClassId(6);
b.setStuGender("女");
mapper.update(b);
*/
Student c = new Student();
//c.setFkClassId(6);
c.setStuId(6);
// c.setTuition(23000.00);
// c.setStuName("batis");
// c.setStuGender("女");
// c.setStuAge(33);
List<Student> by = mapper.findBy(c);
for (Student student : by) {
System.out.println(student);
}
sqlSession.close();
}
}