目录
3.1 mybatis环境配置文件mybatis-config.xml
1.mybatis介绍
mybaits是对jdbc的操作数据库过程进行封装,使用户只关注SQL本身。是通过XML或者注解方式将各种statement进行配置,最后通过mybait将java对象的sql映射成最终执行的sql语句,并且有mybaits框架执行sql并且将结果返回。
总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决了JDBC将结果集封装位Java对象的麻烦。
2.准备工作
2.1 数据库表准备
首先我们准备mysql数据库,并且创建表emp.
信息如下:
可以自行在表中放入一些数据
2.2 maven工程创建
我们需要创建maven工程(普通java工程也是可以的),创建工程目录如下所示:
在上图中,main/java中主要存放相关的class文件,main/resources中存放相关的配置文件。
在pom文件中添加相应的依赖包。pom文件示例如下,添加的依赖包主要有junit、mysql、slf4j和mybatis.
<?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>org.example</groupId>
<artifactId>Mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.31</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
</properties>
</project>
2.3 Emp.class的创建
接下来创建一个类,Emp.Class,添加属性id,job,name,salary,并添加get、set和toString方法。
package com.tedu;
public class Emp {
private Integer id;
private String name;
private String job;
private Integer salary;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getJob() {
return job;
}
public Integer getSalary() {
return salary;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setJob(String job) {
this.job = job;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", Job='" + job + '\'' +
", salary=" + salary +
'}';
}
}
在Emp类中,要求成员变量的名称和数据库表中的列名保持一致。
3.mybatis配置文件解析
3.1 mybatis环境配置文件mybatis-config.xml
mybatis-config.xml文件主要是对mybatis进行的一些基本的配置,其放在sre/main/resources下,包括环境配置和引入SQL语句所在的文件。其中相应的配置的说明,已经在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>
<!-- 1.配置开发环境,可以配置多个environment,每一个 environment是一个独立的开发环境 -->
<!--default指向哪个id就表明用哪个 -->
<environments default="develop">
<environment id="develop">
<!--配置事物管理方式
JDBC:将事物交给JDBC管理(推荐)
MANAGED:自己管理事物-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)
POOLED:使用连接池
UNPOOLED:不使用连接池
JNDI:已过时-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///yonghedb?characterEncoding=utf-8&ser verTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="duang521"/>
</dataSource>
</environment>
</environments>
<!--2.导入mapper.xml文件的(其中包含了要执行的sql语句) -->
<mappers>
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>
3.2 SQL语句配置文件Mapper.xml
Mapper.xml文件所存放的位置和mybatis-config.xml在同一目录下,通常情况下,数据库中的一张表对应java中的一个类,例如上述创建的Emp类和emp表。同时,一个类有一个“类名+Mapper.xml”文件(就是Mapper.xml文件),文件中包含所有对和此类对应的表的操作的SQL语句。
Mapper.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="EmpMapper">
<!--
select标签
update标签
delete标签
insert标签
-->
</mapper>
在Mapper.xml文件中,常用的标签有select、update和一些操作符的标签如:where、set等(后续根据实例来价绍)。
一个带有SQL语句的Mapper.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="EmpMapper">
<!--
select标签
update标签
delete标签
insert标签
-->
<!-- resultType结果类型-->
<select id="findAll" resultType="com.tedu.Emp">
select * from emp;
</select>
</mapper>
其中namespace通常为“包名+类名”,namespace+id可以精确定位到一个sql语句,resultType则为返回数据类型,为一个类(一个类对应一张表)的全路径。
一般情况下,select和update两个标签就够用了。
4.mybatis操作数据库
在这里介绍两个mybatis操作:
4.1 查询操作
首先在EmpMapper中添加如下内容,
<select id="findAll" resultType="com.tedu.Emp">
select * from emp;
</select>
那么mybatis的执行操作如下:
@Test
public void findAll() throws IOException {
//1.读取mybaits核心配置文件myybatis-config
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.通过配置获取SqlSessionFactory
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
//3.通过工厂获取SqlSession对象(类似于connection)
SqlSession session =factory.openSession();
//4.执行sql语句(namespace+id对sql语句进行定位),返回结果
//增删改都用update
List<Emp> list= session.selectList("EmpMapper.findAll");
for(Emp e:list){
System.out.println(e);
}
}
代码中已经有详细的解释。
其中session类似于一个connection连接,其提供的方法有selectOne、selectList、update等,只凭字面意思,我们就能理解其作用。
4.2 插入操作
首先在EmpMapper中添加如下内容(删除、修改操作类似):
<update id="insert">
insert into emp values(null ,'张三','瓦工',400)
</update>
@Test
public void testInsert() {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
int c = session.update("EmpMapper.insert");
//提交事物
session.commit();
System.out.println("影响了"+c+"行");
}
可以发现,在插入操作中多了一个session.commit,是进行事物提交。
5.mybatis #{}占位符
在数据库的操作中,以插入为例,我们在业务中需要插入的数据往往是从前端或者其他模块中获取来的,那么就需要能够实现传参插入的方法,而不是将值、条件等像第四节那样写死在SQL中。mybatis提供了#{}占位符(类似于JDBC中的“?”),见下例:
XML文件中增加:
<update id="updateById">
update emp set name=#{name},
job=#{job},
salary=#{salary}
where id=#{id};
</update>
java程序:
@Test
public void testUpdateById(){
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
//对象封装不了用map
Emp e= new Emp();
e.setId(1);
e.setName("张三666");
e.setJob("总经理");
e.setSalary(1000);
System.out.println(e);
int rows = session.update("EmpMapper.updateById",e);
session.commit();
System.out.println(rows);
}
在上述代码中,我们可以用map来进行传参
如将上述Emp e = new Eep()等类代码用下Map e = new HashMap()替代,同时在map中设置相应的键值对,如e.put("name","总经理"),可以看出map的方法比类封装的方法麻烦一点,因为属性名也要自己进行填写。
在上述代码中,我们传递了id、name等一共四个参数,在只传递一个参数的时候,可以直接进行传递,不用封装,并且,接收时可以用任意的属性名进行接收:
<!-- 只有一个参数时,用任意变量都可以进行接收 -->
<select id="findById" resultType="com.tedu.Emp">
select * from emp where id=#{id};
</select>
@Test
public void testFindById(){
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
//只有一个变量时可以直接传
Emp e = session.selectOne("EmpMapper.findById",1);
session.commit();
System.out.println(e);
}
6.mybatis ${}占位符
${}占位符(可以认为是jstl中的el)。
#{}占位符在接收参数时会对值进行处理,如将对字符串加上""等。
但是在业务中我们如果需要根据参数来选择不同的列的时候,那么值外层的""在SQl中其实是会进行报错的。
${}占位符的作用就是将"aaa"去掉引号接收为aaa。
下面是一个列子:
<select id="findAll" resultType="com.tedu.Emp">
select ${cols} from emp;
</select>
@Test
public void testFindAll(){
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
Map m = new HashMap();
m.put("cols","id,name");
List<Emp> list = session.selectList("EmpMapper.findAll",m);
for(Emp e:list){
System.out.println(e);
}
}
7.mapper.xml中的标签介绍
mapper中常用的标签有if、where、set等。
其中where、set等标签能够根据情况处理sql语句中的","、"and"、"or"等符号。
7.1 if标签
if标签通常会和where、set等标签联合使用,因此在这里不进行举例,只是介绍语法。
<if test="minSal != null">
and salary >= #{minSal}
</if>
上述是一个完整的if标签的使用,test中的意思为:参数中是否存在minSal参数,如果存在就将if标签中的内容加入到sql语句中。
7.2 where标签
在这里举例一个场景,如范围查找,比如我们可能查找成绩大于60的学生,也可能查找成绩在60-80之间的学生,同时也可能查找成绩小于60的学生。因此,在传值的过程中,我们可能传一个最大值,也能传一个最小值,也可能将区间左右值都进行传参,也可能什么也不传。因此,where和if标签的联合使用,将能够解决问题:
<select id="findBySalary" resultType="com.tedu.Emp">
select * from emp
<where>
<if test="minSal != null">
and salary >= #{minSal}
</if>
<if test="maxSal != null">
and salary <![CDATA[<=]]> #{maxSal}
</if>
</where>
</select>
@Test
public void testBySalary(){
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
Map m = new HashMap();
m.put("minSal",500);
m.put("maxSal",6000);
List<Emp> list = session.selectList("EmpMapper.findBySalary",m);
for(Emp e:list){
System.out.println(e);
}
}
在上述XML文件中,可以发现,可以发现如果只传入一份参数的话,那么and符号则是没有用的,而where则能够根据传值情况对and符号进行处理。<![CDATA[<=]]>是对特殊符号<进行处理。
7.3 set标签
set标签和where标签的使用方法差不多,见如下示例:
<update id="updateById2">
update emp
<set>
<if test="name != null">
name = #{name},
</if>
<if test="job != null">
name = #{job},
</if>
<if test="salary != null">
name = #{salary},
</if>
</set>
where id = #{id}
</update>
@Test
public void testUpdateById2(){
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
Emp emp = new Emp();
emp.setId(1);
emp.setName("updateById2");
int rows = session.update("EmpMapper.updateById2",emp);
session.commit();
System.out.println(rows);
}
7.4 foreach标签
forearch标签结合sql中的in进行使用:
<!-- array表示数组,list表示列表-->
<update id="deleteByIds">
delete from emp where id in
<foreach collection="array"
open="("
item="id"
separator=","
close=")">
#{id}
</foreach>
</update>
@Test
public void testDeleteByIds(){
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(in);
SqlSession session =factory.openSession();
Integer[] ids = {1,2,3};
int rows = session.update("EmpMapper.deleteByIds",ids);
session.commit();
System.out.println(rows);
}
8.slf4j打印日志
slf4j是一个日志插件,和mybatis配套使用,可以在控制台打印出翻译后的SQL结果等信息,同时其使用也非常简单,只需要在mybatis-config.xml同目录下添加配置文件log4j.properties,mybatis就会启用它。
log4j.properties
log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5 [%t] - %m%n
控制 台输出信息如下所示:
途中红框内容即为mybaits翻译后的sql,类似于jdbc中的sql。