一. Mybatis入门案例
# 入门案例的步骤
1. 在pom文件中导入依赖
2. 编写配置文件
3. 编写接口和实体类
4. 测试类
0. 数据准备
create database day08;
use day08;
create table user (
id int primary key auto_increment,
username varchar(20) not null,
birthday date,
sex char(1) default '男',
address varchar(50)
);
insert into user values (null, '孙悟空','1980-10-24','男','花果山水帘洞');
insert into user values (null, '白骨精','1992-11-12','女','白虎岭白骨洞');
insert into user values (null, '猪八戒','1983-05-20','男','福临山云栈洞');
insert into user values (null, '蜘蛛精','1995-03-22','女','盤丝洞');
select * from user;
1. 在pom文件中导入依赖
<dependencies>
<!--mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<!--logback日志包: mybatis底层使用的日志框架,用于打印mybatis运行信息-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!--mysql驱动 : mybatis底层封装了JDBC(接口),所以驱动(实现类)必须要有 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<!--
junit单元测试框架
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2. 编写配置文件
logback.xml
logback日志框架的配置文件,规定了mybatis输出日志的格式
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n</pattern>
</encoder>
</appender>
<!-- File是输出的方向通向文件的 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--日志输出路径-->
<file>C:/code/itheima-data.log</file>
<!--指定日志文件拆分和压缩规则-->
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--通过指定压缩文件名称,来确定分割文件方式-->
<fileNamePattern>C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.gz</fileNamePattern>
<!--文件拆分大小-->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
</appender>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="ALL">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>
mybatis-config.xml
mybatis核心配置文件: 待会详解!!!
<?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>
<!--mybatis环境的配置-->
<environments default="development">
<!--通常我们只需要配置一个就可以了, id是环境的名字 -->
<environment id="development">
<!--事务管理器:由JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源的配置:mybatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/day08"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载映射文件,放到src下即可-->
<mapper resource="userMapper.xml"/>
</mappers>
</configuration>
userMapper.xml
UserMapper接口的sql映射文件(待会详解!!!)
<?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="com.itheima.sh.dao.UserMapper">
<!--
查询语句
resultType:返回的实体类的类型,类全名
-->
<select id="findAllUsers" resultType="com.itheima.sh.pojo.User">
select * from user
</select>
</mapper>
3. 编写接口和实体类
package com.itheima.sh.dao;
import com.itheima.sh.pojo.User;
import java.util.List;
public interface UserMapper {
/**
查询所有的用户
*/
List<User> findAllUsers();
}
package com.itheima.sh.pojo;
import java.util.Date;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public User() {
}
public User(Integer id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
4. 测试类
package com.itheima.sh.test;
import com.itheima.sh.dao.UserMapper;
import com.itheima.sh.pojo.User;
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;
public class MyBatisTest01 {
//从MySQL中查询所有的用户
@Test
public void test02() throws Exception{
//1.从xml文件中构建SqlSessionFactory
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.从SqlSessionFactory中获取session
SqlSession session = sqlSessionFactory.openSession();
//3.使用session获取接口的动态代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
//4.使用接口对象调用接口中的方法
List<User> userList = mapper.findAllUsers();
//5.遍历集合
for (User user : userList) {
// System.out.println(user); // 打印黑字: 普通信息
System.err.println(user); // 打印红字: 一般用来打印异常信息
}
//关闭会话
session.close();
}
}
运行结果
二. 入门案例运行原理
从测试类入手
package com.itheima.sh.test;
import com.itheima.sh.dao.UserMapper;
import com.itheima.sh.pojo.User;
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;
/*
建造者模式: 创建对象
工厂设计模式: 创建对象
代理模式: 动态代理(a. 创建代理对象 b. 基于接口)
*/
public class MyBatisTest01 {
//从MySQL中查询所有的用户
@Test
public void test02() throws Exception{
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
SqlSession session = sqlSessionFactory.openSession();
//TODO: 3.使用session获取接口的动态代理对象
//接口类型 变量 = 接口的实现类对象
//在源码里面并没看到实现类在哪里, 那说明实现类是运行时动态生成的(动态代理)
// invoke方法的实现: 根据 接口映射文件 编写的(jdbc)
UserMapper mapper = session.getMapper(UserMapper.class);
//TODO: 4.使用接口类型的对象调用接口中的方法
List<User> userList = mapper.findAllUsers();
//5.遍历集合
for (User user : userList) {
// System.out.println(user); // 打印黑字: 普通信息
System.err.println(user); // 打印红字: 一般用来打印异常信息
}
//关闭会话
session.close();
}
}
第三章 mybatis核心配置
【mybatis全局配置介绍】
mybatis-config.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。
1. mybatis全局配置文件是mybatis框架的核心配置,整个框架只需一个;
2. mybatis全局配置文件中的配置顺序:注意如果配置多项,必须按照以下顺序进行配置(dtd约束)
1). properties:属性配置
2). settings:设置
3). typeAliases:类型别名设置
4). environments:环境配置
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
5). mappers:映射器
1. enviroments标签
<!-- TODO: environments标签 : mybatis环境的配置
1. mybatis可以配置多个环境 (复数)
1). 实际工作中可能会有多个环境
I. 开发环境
II. 测试环境
III. 生产环境
2).environments标签可以有多个environment子标签
3). 具体的使用哪个环境 由environments的 default指定
2. environment标签
1). id属性 : 当前环境的标识
2). transactionManager子标签 : 事务管理器(不用的,后续会被spring的声明式事务所替代)
3). dataSource子标签 (连接池)
type=POOLED : 用mybatis自带连接池(如果要切换其他连接池,比如druid,在spring学习)
driver用来配置驱动
url用来配置数据库的地址
username数据库的用户名
password数据库的密码
-->
<environments default="development">
<!--通常我们只需要配置一个就可以了, id是环境的名字 -->
<environment id="development">
<!--事务管理器:由JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源的配置:mybatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/day08"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<!-- <environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/day09"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>-->
</environments>
2. properties标签
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day09
jdbc.username=root
jdbc.password=root
<!--
environments标签内目前只有jdbc四项配置能够切换,
这个切换直接放在核心配置文件中,很不方便,mybatis可以将这4个变量抽取出去
TODO: properties标签
1. 作用: 加载properties配置文件
2. 后续可以使用mybatis的通配符,引用properties配置文件中的数据
${properties中的key}
3. 作用: 将变量从核心配置文件中解耦出去
-->
<properties resource="jdbc.properties"/>
<environments default="development">
<!--通常我们只需要配置一个就可以了, id是环境的名字 -->
<environment id="development">
<!--事务管理器:由JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源的配置:mybatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
3. mappers标签
<!--
TODO: mappers标签(用于指定dao层接口对应的sql映射文件)
-->
<mappers>
<!--加载映射文件,得让mybatis知道有这个配置文件
缺陷: 如果有多个dao层接口就需要编写多个映射
-->
<!-- <mapper resource="userMapper.xml"/>
<mapper resource="xx.xml"/>-->
<!--
包扫描: 扫描所有指定包下的接口与其对应的sql映射文件
对接口的映射文件要求:
1). 文件名必须和接口名一致
2). 文件名的路径必须和接口路径一致
-->
<package name="com.itheima.sh.dao"/>
</mappers>
4. settings标签
<!--
TODO: settings标签(用于设置)
1. 内部可作多项配置
2. 目前只需要掌握一项配置: 驼峰映射
对象的属性名为 小驼峰 那么映射 表中字段名 单词_单词...
比如说: 对象的属性名为 userName 那么映射 表中字段名 user_name
passWordString pass_word_string
sex sex
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
5.typeAliases标签
<!--
TODO: typeAliases标签: 用于设置类型别名
1. package : 扫描哪个包
比如我们这里的pojo包被扫描了, 那么pojo包下所有的类都自动起别名
com.itheima.sh.pojo.User -> User/user
-->
<typeAliases>
<package name="com.itheima.sh.pojo"/>
</typeAliases>
完整核心配置文件
<?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>
<!--
environments标签内目前只有jdbc四项配置能够切换,
这个切换直接放在核心配置文件中,很不方便,mybatis可以将这4个变量抽取出去
TODO: properties标签
1. 作用: 加载properties配置文件
2. 后续可以使用mybatis的通配符,引用properties配置文件中的数据
${properties中的key}
3. 作用: 将变量从核心配置文件中解耦出去
-->
<properties resource="jdbc.properties"/>
<!--
TODO: settings标签(用于设置)
1. 内部可作多项配置
2. 目前只需要掌握一项配置: 驼峰映射
对象的属性名为 小驼峰 那么映射 表中字段名 单词_单词...
比如说: 对象的属性名为 userName 那么映射 表中字段名 user_name
passWordString pass_word_string
sex sex
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
TODO: typeAliases标签: 用于设置类型别名
1. package : 扫描哪个包
比如我们这里的pojo包被扫描了, 那么pojo包下所有的类都自动起别名
com.itheima.sh.pojo.User -> User/user
-->
<typeAliases>
<package name="com.itheima.sh.pojo"/>
</typeAliases>
<!-- TODO: environments标签 : mybatis环境的配置
1. mybatis可以配置多个环境 (复数)
1). 实际工作中可能会有多个环境
I. 开发环境
II. 测试环境
III. 生产环境
2).environments标签可以有多个environment子标签
3). 具体的使用哪个环境 由environments的 default指定
2. environment标签
1). id属性 : 当前环境的标识
2). transactionManager子标签 : 事务管理器(不用的,后续会被spring的声明式事务所替代)
3). dataSource子标签 (连接池)
type=POOLED : 用mybatis自带连接池(如果要切换其他连接池,比如druid,在spring学习)
driver用来配置驱动
url用来配置数据库的地址
username数据库的用户名
password数据库的密码
-->
<environments default="development">
<!--通常我们只需要配置一个就可以了, id是环境的名字 -->
<environment id="development">
<!--事务管理器:由JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源的配置:mybatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!-- <environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/day09"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>-->
</environments>
<!--
TODO: mappers标签(用于指定dao层接口对应的sql映射文件)
-->
<mappers>
<!--加载映射文件,得让mybatis知道有这个配置文件
缺陷: 如果有多个dao层接口就需要编写多个映射
-->
<!-- <mapper resource="userMapper.xml"/>
<mapper resource="xx.xml"/>-->
<!--
包扫描: 扫描所有指定包下的接口与其对应的sql映射文件
对接口的映射文件要求:
1). 文件名必须和接口名一致
2). 文件名的路径必须和接口路径一致
-->
<package name="com.itheima.sh.dao"/>
</mappers>
</configuration>
第四章 mybatis 增删改查
基本环境
pom.xml
<dependencies>
<!--mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<!--logback日志包: mybatis底层使用的日志框架,用于打印mybatis运行信息-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!--mysql驱动 : mybatis底层封装了JDBC(接口),所以驱动(实现类)必须要有 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<!--
junit单元测试框架
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
mybatis-config.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>
<properties resource="jdbc.properties"/>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
扫描pojo所在的包: 起别名
-->
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<environments default="development">
<!--通常我们只需要配置一个就可以了, id是环境的名字 -->
<environment id="development">
<!--事务管理器:由JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源的配置:mybatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--
扫描接口所在的包
1. sql映射文件名必须和接口一致
2. 路径必须一致
-->
<mappers>
<package name="com.itheima.dao"/>
</mappers>
</configuration>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day08
jdbc.username=root
jdbc.password=root
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n</pattern>
</encoder>
</appender>
<!-- File是输出的方向通向文件的 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--日志输出路径-->
<file>C:/code/itheima-data.log</file>
<!--指定日志文件拆分和压缩规则-->
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--通过指定压缩文件名称,来确定分割文件方式-->
<fileNamePattern>C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.gz</fileNamePattern>
<!--文件拆分大小-->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
</appender>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="ALL">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>
重点
/*
TODO mybatis的orm思想要求: 实例类 (pojo: Plain Old Java Object 简单的 Java 对象)
一. 硬性规范(不能违背,违背会报错)
1. 属性名必须要和字段名一致
2. 必须要有get/set方法
3. public 空参构造
二. 软性规范(可以违背,推荐你这么做)
1. 类名跟表名一致
2. 字段类型如果没有特殊要求,直接写String
3. 基本类型不要用,用对应包装类型
*/
public class User {
private Integer id;
private String username;
private String birthday;
private String sex;
private String address;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday='" + birthday + '\'' +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.itheima.dao;
import com.itheima.pojo.User;
import java.util.Date;
import java.util.List;
/*
TODO 需求: 用mybatis完成user表的crud(增删改查)
1. 编写一个接口
1). 接口名: 表名Mapper 或者 表名Dao
2). 定义抽象方法
I. 参数
II. 返回值
2. 编写接口的sql映射文件
1). 位置: 一定要注意
*/
public interface UserMapper {
//查询全部 : select * from user;
List<User> findAllUsers();
//根据id查询用户: select * from user where id = ?
//参数: int类型的id,返回值是User类型
User findUserById(Integer id);
//查询用户总数: select count(*) from user;
//参数: 无 , 返回值: int类型
Integer findUserTotal();
//根据id删除用户: delete from user where id = ?;
//参数需要int类型的id,返回值是被影响的行数int
// id = 3
int deleteById(Integer id);
//增加一条用户数据: insert into user values(null,?,?,?,?);
//参数: User对象 ,返回值是被影响的行数int
// int addUser(String username, Date birthday,String sex,String address);
int addUser(User user);
//根据id修改用户: update user set username=?,birthday=?,sex=?,address=? where id = ?
// 参数: User对象 ,返回值是被影响的行数int
int updateUserById(User user);
}
userMapper.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">
<!--
TODO: UserMapper接口的sql映射文件
1. mapper根标签的namespace : 接口类型的全路径名(包名+接口名)
-->
<mapper namespace="com.itheima.dao.UserMapper">
<!--
查询语句
id : 对应接口的方法名
resultType:结果集类型
1. 返回的User或者List<User>类型,一般要写类全名
1). 类全名: com.itheima.sh.pojo.User
2). 如果有设置 "typeAliases" 包扫描,可以直接写User或 user
2. 返回的基本类型或string
直接写即可
-->
<select id="findAllUsers" resultType="user">
select * from user
</select>
<select id="findUserById" resultType="user">
select * from user where id = #{id}
</select>
<select id="findUserTotal" resultType="int">
select count(*) from user
</select>
<!--
delete标签用于编写删除方法对应的sql
1. id 方法名
2. 返回值: 固定就是int, 返回被影响行数
3. mybatis的通配符
#{变量名}
-->
<delete id="deleteById">
delete from user where id = #{id}
</delete>
<!--
insert标签用于编写添加方法对应的sql
1. id 方法名
2. 返回值: 固定就是int, 返回被影响行数
3. mybatis的通配符
#{变量名}
1). 如果方法的参数只有一个,且为基本类型或String
#{参数变量名}
2). 如果方法的参数只有一个,且为pojo类型
#{pojo的属性名}
#{username} 相当于 user.getUsername();
-->
<insert id="addUser">
insert into user values(null,#{username},#{birthday},#{sex},#{address})
</insert>
<update id="updateUserById">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id = #{id}
</update>
</mapper>
测试类
package com.itheima.test;
import com.itheima.dao.UserMapper;
import com.itheima.pojo.User;
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 TestDemo {
@Test
public void add() throws IOException {
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
SqlSession session = sqlSessionFactory.openSession();
//TODO: 3.使用session获取接口的动态代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
//TODO: 4.使用接口类型的对象调用接口中的方法
User user = new User();
user.setUsername("张三");
user.setBirthday("1998-01-01");
user.setAddress("杭州");
user.setSex("女");
mapper.addUser(user);
//关闭会话
session.commit();
session.close();
}
@Test
public void update() throws IOException {
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
SqlSession session = sqlSessionFactory.openSession();
//TODO: 3.使用session获取接口的动态代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
//TODO: 4.使用接口类型的对象调用接口中的方法
User user = new User();
user.setId(6);
user.setUsername("张三丰");
user.setBirthday("1998-01-01");
user.setAddress("杭州");
user.setSex("女");
int count = mapper.updateUserById(user);
System.out.println("被影响的行数:" + count);
//关闭会话
session.commit();
session.close();
}
@Test
public void delete() throws IOException {
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
SqlSession session = sqlSessionFactory.openSession();
//TODO: 3.使用session获取接口的动态代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
//TODO: 4.使用接口类型的对象调用接口中的方法
int count = mapper.deleteById(6);
System.out.println("被影响的行数:" + count);
//关闭会话
session.commit();
session.close();
}
}
package com.itheima.test;
import com.itheima.dao.UserMapper;
import com.itheima.pojo.User;
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 TestDemo2 {
@Test
public void add() throws IOException {
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
SqlSession session = sqlSessionFactory.openSession();
//TODO: 3.使用session获取接口的动态代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
//TODO: 4.使用接口类型的对象调用接口中的方法
// List<User> list = mapper.findAllUsers();
// for (User user : list) {
// System.err.println(user);
// }
// User user = mapper.findUserById(1);
// System.err.println(user);
Integer count = mapper.findUserTotal();
System.err.println(count);
//关闭会话
session.commit();
session.close();
}
}
第五章 敏捷开发
1. 工具类
package com.itheima.com.itheima.util;
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;
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static{
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
try {
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//传入true,表示自动提交事务,传入false,手动提交
public static SqlSession openSession(boolean flag){
SqlSession session = sqlSessionFactory.openSession(flag);
return session;
}
//需要手动提交事务
public static SqlSession openSession(){
SqlSession session = sqlSessionFactory.openSession();
return session;
}
//配套手动提交事务使用: 成功提交
public static void commitAndClose(SqlSession session){
session.commit();
session.close();
}
//配套手动提交事务使用: 失败回滚
public static void rollbackAndClose(SqlSession session){
session.rollback();
session.close();
}
}
测试
package com.itheima.test;
import com.itheima.com.itheima.util.MyBatisUtil;
import com.itheima.dao.UserMapper;
import com.itheima.pojo.User;
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;
/*
TODO 事务
1. 事务操作
1. 开启事务
2. 增删改 操作
3. 成功提交 或 失败回滚
2. 注意: 如果事务开之后, 进行操作 , 不提交数据是不会保存到数据库
*/
public class TestDemo03 {
@Test
public void add() throws IOException {
//TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
//定义核心配置文件路径
String resource = "mybatis-config.xml";
//加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
//手动操作事务 开启事务
SqlSession session = sqlSessionFactory.openSession();
//自动操作事务: 默认自动提交
// SqlSession session = sqlSessionFactory.openSession(true);
//TODO: 3.使用session获取接口的动态代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
//TODO: 4.使用接口类型的对象调用接口中的方法
User user = new User();
user.setUsername("张三");
user.setBirthday("1998-01-01");
user.setAddress("杭州");
user.setSex("女");
mapper.addUser(user);
//5. 关闭会话: 提交会回滚,最后释放连接
session.commit(); // 成功提交
// session.rollback(); // 失败回滚
session.close();
}
@Test
public void method01(){
//获取自动提交事务的连接会话
SqlSession session = MyBatisUtil.openSession(true);
//操作
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("张三");
user.setBirthday("1998-01-01");
user.setAddress("杭州");
user.setSex("女");
mapper.addUser(user);
//用完释放
session.close();
}
@Test
public void method02(){
//获取需要手动提交事务的连接会话
// SqlSession session = MyBatisUtil.openSession(false);
SqlSession session = MyBatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("张三");
user.setBirthday("1998-01-01");
user.setAddress("杭州");
user.setSex("女");
mapper.addUser(user);
// session.commit();
// session.close();
MyBatisUtil.commitAndClose(session);
}
}
2. 模板
<?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="jdbc.properties"/>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
扫描pojo所在的包: 起别名
-->
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<environments default="development">
<!--通常我们只需要配置一个就可以了, id是环境的名字 -->
<environment id="development">
<!--事务管理器:由JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源的配置:mybatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--
扫描接口所在的包
1. sql映射文件名必须和接口一致
2. 路径必须一致
-->
<mappers>
<package name="com.itheima.dao"/>
</mappers>
</configuration>
第六章 mybatis单表查询
1. 结果集映射
public class User {
private Integer id;
//TODO 发现,类中的属性名mingzi 跟 表中字段名username 不一致
private String mingzi;
private String birthday;
private String sex;
private String address;
@Override
public String toString() {
return "User{" +
"id=" + id +
", mingzi='" + mingzi + '\'' +
", birthday='" + birthday + '\'' +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMingzi() {
return mingzi;
}
public void setMingzi(String mingzi) {
this.mingzi = mingzi;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public interface UserMapper {
List<User> findAllUsers();
}
<?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="com.itheima.query.dao.UserMapper">
<!--
TODO: 结果集映射
1. 自动映射
1). 只要类的属性名和表的字段名一致, mybatis会自动加你个结果集的每一行映射一个对象
2). resultType属性 : user
2.手动映射
1). 类的属性名和结果集的字段名不一致, 需要手动映射
2). resultMap标签 (结果集映射)
I. 属性
a. id 此标签的标识
b. type 此映射结果的类型
II. 子标签
id 标签 : 指定类中的属性和结果集中主键字段的映射关系
result标签 : 指定类中的属性和结果集中非主键字段的映射关系
比如user类的id属性跟结果集的id字段映射(主键)
比如user类的mingzi属性跟结果集的username字段映射(非主键)
III. 简易写法
a. 主键映射必须要写
b. 非主键字段如果跟属性名一致,可以不写 autoMapping="true"
3). 运用:
单表查询,基本都是自动映射
多表查询, 可能用上手动映射
-->
<!-- <resultMap id="userMap" type="user">
<id property="id" column="id"/>
<result property="mingzi" column="username"/>
<result property="birthday" column="bt"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
</resultMap>-->
<resultMap id="userMap" type="user" autoMapping="true">
<id property="id" column="id"/>
<result property="mingzi" column="username"/>
<result property="birthday" column="bt"/>
</resultMap>
<select id="findAllUsers" resultMap="userMap">
select id,username ,birthday as bt,sex,address from user
</select>
<!--<select id="findAllUsers" resultType="user">
select * from user
</select>-->
</mapper>
2. 参数映射
public interface UserMapper {
List<User> findAllUsers();
//根据用户名和性别查询用户
List<User> findUserByUsernameAndSex(@Param("xx") String username,
@Param("sex")String sex);
// List<User> findUserByUsernameAndSex(User user);
//根据用户名查询用户
List<User> findUserByUsername(String username);
}
<?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="com.itheima.query.dao.UserMapper">
<resultMap id="userMap" type="user2" autoMapping="true">
<id property="id" column="id"/>
<result property="mingzi" column="username"/>
<result property="birthday" column="bt"/>
</resultMap>
<select id="findAllUsers" resultMap="userMap">
select id,username ,birthday as bt,sex,address from user
</select>
<!--<select id="findAllUsers" resultType="user">
select * from user
</select>-->
<!--
TODO: 参数映射
1. 自动映射
1). 前提: 接口方法的参数列表有且仅有一个参数
2). 规则
I. 基本类型 + string
#{参数变量名}
II. pojo:
#{pojo对象的属性名}
2. 手动映射
1). 前提: 几个参数无所谓
2). 语法:
@Param("xx") String username
mybatis知道变量 xx 对应的username参数
#{xx} 就会读取到 username参数
3. 运用
1). 一个参数就不用写 @Param
2). 两个参数以及以上必须要写@Param
-->
<!-- <select id="findUserByUsernameAndSex" resultType="user">
select * from user where username = #{username} and sex = #{sex}
</select>-->
<select id="findUserByUsernameAndSex" resultType="user">
select * from user where username = #{xx} and sex = #{sex}
</select>
<select id="findUserByUsername" resultType="user">
select * from user where username = #{username}
</select>
</mapper>
package com.itheima.test;
import com.itheima.query.dao.UserMapper;
import com.itheima.query.pojo.User;
import com.itheima.query.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class TestDemo {
@Test
public void method01(){
SqlSession session = MyBatisUtil.openSession(true);
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findAllUsers();
for (User user : list) {
System.err.println(user);
}
session.close();
}
@Test
public void method02(){
SqlSession session = MyBatisUtil.openSession(true);
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findUserByUsernameAndSex("张三", "女");
// List<User> list = mapper.findUserByUsername("张三");
// User param = new User();
// param.setUsername("张三");
// param.setSex("女");
// List<User> list = mapper.findUserByUsernameAndSex(param);
for (User user : list) {
System.err.println(user);
}
session.close();
}
}