MyBatis
准备工作
使用 idea 进行开发,(因为 eclipse 崩了,重新安装好多次还是不行,果断放弃!!!)
在 MyBatis 官网 下载 jar 包,新建 JavaWeb 项目,导入如下 jar 包:
在 conf 文件夹下,配置 log4j.xml 配置文件:
log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n"/>
</layout>
</appender>
<logger name="java.sql">
<level value="debug"/>
</logger>
<logger name="org.apache.ibatis">
<level value="info"/>
</logger>
<root>
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</root>
</log4j:configuration>
配置成功后,系统会自动加载 log4j.xml,自动实现日志功能。
搭建流程:
(1)引入 jar 包。
(2)创建核心配置文件:mybatis-config.xml。
(3)创建映射文件:XxxMapper.xml。
(4)创建 XxxMapper 接口,并实现下列绑定:
(a)接口全类名与映射文件的 namespace 一致。
(b)接口的方法名与映射文件中 sql 标签的 id 一致。
(5)获取 SqlSession 对象,通过 getMapper() 获取接口动态代理实现类对象。
项目结构:
核心配置文件
MyBatis 的核心配置文件负责设置全局配置信息、与数据库进行连接等。
-
核心配置文件中的配置信息,必须按照如下标签顺序书写:
<configuration>:配置核心配置文件的配置信息,该标签内部的各个标签必须按照如下方式排列: (properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?, reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)
-
<properties>
:设置或引入资源文件
resource:引入类路径下的资源文件
url:引入网络或磁盘路径下的资源文件 -
<settings>
:设置
mapUnderscoreToCamelCase:下划线格式转换为驼峰格式,如user_name => userName -
<typeAliases>
:设置Java类的别名
<typeAlias>
:设置Java类的别名,设置之后,可以使用别名代替该类的全类名
type:Java类的全类名
alias:该类的别名,该属性可以不写,默认为类名,且不区分大小写
<package>
:为某个包下的所有Java类设置别名
name:包名,为该包下的所有类设置别名,默认为类名,且不区分大小写 -
<environments>
:设置环境
<environment>
:设置某个具体的数据库环境
id:数据库环境的唯一标识
<transactionManager>
:设置事务管理器
type=“JDBC”:使用JDBC管理,提交和回滚都需要手动实现
type=“MANAGED”:被其他框架管理,如Spring
<dataSource>
:设置数据源
type=“POOLED”:在MyBatis自己创建的数据库连接池中获取链接
type=“UNPOOLED”:不使用数据库连接池
type=“JNDI”:在上下文中获取连接
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>
<!--
<configuration>:配置核心配置文件的配置信息,该标签内部的各个标签必须按照如下方式排列:
(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,
reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)
-->
<!--
<properties>:设置或引入资源文件
resource:引入类路径下的资源文件
url:引入网络或磁盘路径下的资源文件
-->
<properties resource="jdbc.properties"/>
<!-- 设置 -->
<settings>
<!-- mapUnderscoreToCamelCase:下划线格式转换为驼峰格式,如user_name => userName -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 设置Java类的别名 -->
<typeAliases>
<!--
<typeAlias>:设置Java类的别名,设置之后,可以使用别名代替该类的全类名
type:Java类的全类名
alias:该类的别名,该属性可以不写,默认为类名,且不区分大小写
<package>:为某个包下的所有Java类设置别名
name:包名,为该包下的所有类设置别名,默认为类名,且不区分大小写
-->
<typeAlias type="com.mcc.MyBatis.bean.User" alias="User"/>
<package name="com.mcc.MyBatis.bean"/>
</typeAliases>
<!-- 配置环境 -->
<environments default="mysql">
<!--
<environment>:设置某个具体的数据库环境
id:数据库环境的唯一标识
-->
<environment id="mysql">
<!--
<transactionManager>:设置事务管理器
type="JDBC":使用JDBC管理
type="MANAGED":被其他框架管理,如Spring
-->
<transactionManager type="JDBC"/>
<!--
<dataSource>:设置数据源
type="POOLED":在MyBatis自己创建的数据库连接池中获取链接
type="UNPOOLED":不使用数据库连接池
type="JNDI":在上下文中获取连接
-->
<dataSource type="POOLED">
<!--
引入了资源文件后,可以使用 ${} 表达式引入资源文件中的属性,
注意:${} 大括号内填写的是properties文件的key值,不能像EL表达式一样多空格,
${ jdbc.driver }:代表key=空格jdbc.driver空格,查找失败,而EL表达式则不会出现这种错误
-->
<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>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=密码
映射文件
namespace:要绑定(关联)的接口的全类名。
id:接口内操作该 sql 语句的方法名。
resultType:查询结果的全类名。
UserMapper.xml
<mapper namespace="com.mcc.MyBatis.mapper.UserMapper">
<select id="getUserById" resultType="com.mcc.MyBatis.bean.User">
<!-- 解决属性名与字段名不匹配问题:使用别名 -->
select userId,user_name userName,password,age,sex from user where userId = #{userId}
</select>
</mapper>
UserMapper.java
package com.mcc.MyBatis.mapper;
import com.mcc.MyBatis.bean.User;
public interface UserMapper {
User getUserById(String userId);
}
SqlSession
Resources.getResourceAsStream()
:加载核心配置文件
new SqlSessionFactoryBuilder().build()
:获取 SqlSessionFactory 对象
sessionFactory.openSession(boolean b)
:获取 SqlSession 对象,b 为 true 时代表自动提交事务,默认为 false。
sqlSession.getMapper()
:获取接口的动态代理实现类对象
@Test
public void testUser() throws IOException {
//加载核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sessionFactory.openSession();
//加载Mapper类,调用Mapper中的方法
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById("1");
System.out.println(user);
}
增删改查
创建表和JavaBean
Employee.java
package com.mcc.MyBatis.bean;
public class Employee {
private Integer id;
private String eName;
private Integer age;
private String sex;
public Employee() {
}
public Employee(Integer id, String eName, Integer age, String sex) {
this.id = id;
this.eName = eName;
this.age = age;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String geteName() {
return eName;
}
public void seteName(String eName) {
this.eName = eName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", eName='" + eName + '\'' +
", age='" + age + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
Mapper 接口
EmployeeMapper.java
package com.mcc.MyBatis.mapper;
import com.mcc.MyBatis.bean.Employee;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface EmployeeMapper {
/**
* 根据id查询Employee
* @param id
* @return Employee
*/
Employee getEmployeeById(String id);
/**
* 查询全部Employee
* @return List<Employee>
*/
List<Employee> getAllEmployees();
/**
* 添加Employee
* @param emp
* @return 受影响行数
*/
Integer addEmployee(Employee emp);
/**
* 根据id,修改Employee
* @param emp
* @return 受影响的行数
*/
Integer updateEmployee(Employee emp);
/**
* 根据id删除Employee
* @param id
* @return 受影响行数
*/
Integer deleteEmployee(Integer id);
}
映射文件
EmployeeMapper.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="com.mcc.MyBatis.mapper.EmployeeMapper">
<!--根据id查询员工信息-->
<select id="getEmployeeById" resultType="com.mcc.MyBatis.bean.Employee">
select * from employee where id = #{id}
</select>
<!--查询全部员工信息-->
<select id="getAllEmployees" resultType="Employee">
select * from employee
</select>
<!--添加员工-->
<insert id="addEmployee">
insert into employee (eName, age, sex) values ('${eName}', '${age}', '${sex}')
</insert>
<!--修改员工信息-->
<update id="updateEmployee">
update employee set eName = #{eName}, age = #{age}, sex = #{sex} where id = #{id}
</update>
<!--删除员工信息-->
<delete id="deleteEmployee">
delete from employee where id = #{id}
</delete>
</mapper>
测试
package com.mcc.MyBatis.test;
import com.mcc.MyBatis.bean.Employee;
import com.mcc.MyBatis.mapper.EmployeeMapper;
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.HashMap;
import java.util.Map;
public class TestEmployee {
@Test
public void testEmp() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//开启事务自动提交
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//根据id查询
// Employee employee = employeeMapper.getEmployeeById("1");
// System.out.println(employee);
//添加
// Employee employee = new Employee(null, "路飞", 21, "男");
// employeeMapper.addEmployee(employee);
// System.out.println(employee.getId());
//修改
// employeeMapper.updateEmployee(new Employee(3, "mcc", 22, "男"));
//删除
// Integer integer = employeeMapper.deleteEmployee(2);
// System.out.println(integer);
//查询全部员工
// List<Employee> employees = employeeMapper.getAllEmployees();
// System.out.println(employees);
}
}
通过 package 引入映射文件
当映射文件很多时,可以使用<package>
标签,引入某个包下的全部 Mapper.xml 文件,但是注意,此时要求 Mapper 接口与映射文件在同一个包下。
idea 操作方法:
(1)将 conf 文件夹设置为 Sources Root。
在 conf 文件夹上右击 => Make Directory as => Sources Root。
(2)在 conf 文件夹下创建包,包名与 Mapper 接口所在的包名相同。
(3)将 Mapper.xml 映射文件放到 conf 中新创建的包下。
(4)idea 在生成项目目录时,会将相同包名的文件放在同一个文件夹下。
mybatis-config.xml
<mappers>
<!-- <mapper resource="UserMapper.xml"/>-->
<!-- <mapper resource="EmployeeMapper.xml"/>-->
<!-- <mapper resource="DepartmentMapper.xml"/>-->
<!--
当映射文件很多时,可以使用package标签,引入某个包下的全部xml文件,
但是注意,此时要求接口与映射文件在同一个包下
-->
<package name="com.mcc.MyBatis.mapper"/>
</mappers>
获取自动生成的主键的值
在向表中插入或修改数据时,可以在<insert>或<update>
标签中使用属性:
useGeneratedKeys="true"
:开启获取自动生成的主键(该属性默认为 true)。keyProperty="xxx"
:将主键的值保存到方法形参的 xxx 参数中。
如,接口方法为:Integer addEmployee(Employee emp);
映射文件为:<insert id="addEmployee" useGeneratedKeys="true" keyProperty="id"></insert>
执行方法后,会将该条数据的主键的值保存到 emp 对象的 id 属性中(通过emp.setId()
实现,若属性不存在,则报错)。
测试:
//添加
Employee employee = new Employee(null, "路飞", 21, "男");
employeeMapper.addEmployee(employee);
System.out.println(employee.getId());
指定传入的参数的类型
可以在映射文件中使用parameterType=""
属性,指定传入方法内的参数的类型,一般不写,MyBatis 会根据传入的参数自动推断所属的类,参数为 Bean 时,会调用 getter() 方法获取属性值。
/**
* 根据id,修改Employee
* @param emp
* @return 受影响的行数
*/
Integer updateEmployee(Employee emp);
<!--修改员工信息-->
<!--parameterType="Employee":指定传入的参数类型,一般不写,MyBatis会根据传入的参数自动推断所属的类,调用getter()方法-->
<update id="updateEmployee" parameterType="Employee">
update employee set eName = #{eName}, age = #{age}, sex = #{sex} where id = #{id}
</update>