MyBatis的搭建
先创建一个Maven工程,使用Maven管理项目依赖,然后在pom.xml文件添加导入依赖
<?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>com.gec.mybatis</groupId>
<artifactId>Mybatis_demo1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> //导入的方式为jar包
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MYSQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.3</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
创建两个properties文件
jdbc.properties(连接数据库)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis??useUnicode=true&characterEncoding=utf8 //数据库名是mybatis
jdbc.username=root //用户名
jdbc.password= //密码(密码可以自行设置,这里设置为空)
log4j.properties(用于方便测试)
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
创建mybatis全局配置文件,默认命名为mybatis-config.xml
官方配置文件代码(未修改)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
这是配置文件中的引入元素顺序
The content of element type " configuration" must match "(properties?,settings?,
typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,
reflectorFactory?,plugins?,environments?,databaseldProvider?,mappers?)".
mybatis-config.xml中引入jdbc文件
<!--引入properties文件 -->
<properties resource="jdbc.properties"/>
配置的环境代码
<!--
environments 配置多个连接数据库的环境
属性:
default:设置默认使用的环境id
-->
<environments default="development">
<!--
environment:配置某个具体的环境
属性:
id:表示连接数据库的环境的唯一标识,不能重复
-->
<environment id="development">
<!-- transactionManager:设置事务管理方式
属性:
type="JDBC/MAMAGED"
JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理
MANAGED:被管理,例如Spring
-->
<transactionManager type="JDBC"/>
<!-- dataSource:配置数据源
属性:
type:设置数据源的类型
type="POOLED/UNPOOLED/JNDI"
POOLED:表示使用数据库连接池缓存数据库连接池
UNPOOLED:表示不使用数据库连接池
JNDI:表示使用上下文中的数据源
-->
<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>
简单配置之后的代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入properties文件 -->
<properties resource="jdbc.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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>
<!-- 引入映射文件 -->
<mappers>
<!-- 暂时先不写 -->
</mappers>
</configuration>
MyBatis的使用步骤
先在管理java文件下创建javaBean对象、mapper接口,然后在resources文件下创建接口对应的映射文件
1.mapper接口写方法(举例:添加方法)
/*
添加用户信息
* */
int insertUser();
2.配置mapper的xml映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gec.mybatis.mapper.UserMapper">
<!-- int insertUser();-->
<insert id="insertUser">
insert into t_user values(3,'admin','1234',23,'男','12345@qq.com')
</insert>
</mapper>
注意:(报错多检查这些地方)
1.映射文件的namespace要和mapper接口的全类名保持一致
2.映射文件中SQL语句的id要和mapper接口中的方法名一致
3.在mybatis-config.xml文件中引入映射文件 (运行报错时,多检查是否引入)
<!-- 引入映射文件 -->
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
4.测试 增删改需要提交事务SqlSession默认不自动提交事务,若需要自动提交事务
可以使用sqlSessionFactory.openSession(true)
public void testMybatis() throws IOException {
//加载核心配置文件
InputStream is =Resources.getResourceAsStream("mybatis-config.xml");
//获取sqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取sqlSessionFactory
SqlSessionFactory sqlSessionFactory= sqlSessionFactoryBuilder.build(is);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//测试功能
int result = mapper.insertUser();
System.out.println("result:"+result);
}
sql语句中如果不想写死参数用${}和#{}
这是MyBatis获取参数值的两种方式:
${}本质字符串拼接 (需要手动添加' ')
#{}本质占位符赋值 (会自动添加' ')
能使用#{}就不使用${}
由于测试类中每个测试出现重复代码,可以写一个工具类封装SqlSession
public class SqlSessionUtils {
public static SqlSession getSqlSession(){
SqlSession sqlSession =null;
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession= sqlSessionFactory.openSession(true);
}catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
当根据用户名进行批量删除时,可以使用${}
接口方法:
/*
* 批量删除
* */
int deleteMore(@Param("ids") String ids); //@Param注解命名参数
mapper.xml文件
<!-- int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
delete from t_user where id in (${ids})
</delete>
Test
@Test
public void testDeleteMore(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
int result = mapper.deleteMore("1,2,3");
System.out.println(result);
}
执行完之后会发现数据库id为1,2,3的数据都被删除。如果没有查询的id,则会执行删除其他的id
在进行查询功能的标签必须设置resultType或者resultMap
resultType:设置默认的映射关系
resultMap:设置自定义的映射关系
xml映射文件中使用resultType
<select id="getAllUser" resultType="com.gec.mybatis.pojo.User">
select * from t_user
</select>
设置别名可以简洁方便(格式:包名.类名)
<typeAliases>
<!--
typeAlias:设置某个类型的别名
属性:
type:设置需要设置别名的类型
alias:射中某个类型的别名,若不设置该属性,则该类型默认的别名是类名 且不区分大小写
-->
<typeAlias type="com.gec.mybatis.pojo.User" alias="User"></typeAlias>
</typeAliases>
在处理多对一或者一对多关系时需要使用resultMap
多对一映射方式有三种(这里使用员工对部门的关系)
1.级联属性赋值
先写sql语句
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid}
</select>
resultMap的id与sql中的resultMap映射关系对应
<resultMap id="empAndDeptResultMapOne" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
//部门表的属性
<result property="dept.did" column="did"></result>
<result property="dept.deptName" column="dept_name"></result>
</resultMap>
2.association
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid}
</select>
id对应resultMap
<resultMap id="empAndDeptResultMapTwo" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<!--
association:处理多对一的映射关系
property:需要处理的处理多对一的映射关系属性名
javaType:该属性的类型
-->
<association property="dept" javaType="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
</association>
</resultMap>
3.分步查询
写两个接口,一个是在Emp属性的mapper接口,另一个是Dept属性
/*
* 通过分布查询查询员工以及员工所对应的部门信息
* 分布查询第一步:根据eid查询员工信息
* */
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
/*
* 通过分步查询查询员工以及员工所对应的部门信息
* 分步查询第二步:通过did查询员工所对应的部门
*
* */
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
xml映射文件中 实现分步查询
<resultMap id="empAndDeptByStepResultMap" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<!--
select:设置分步查询的sql的唯一标识(name.SQLid或mapper接口的全类名.方法名)
column:设置分步查询的条件
fetchType:当开启了全局的延迟加载之后,可以通过此属性手动控制延迟加载的效果
fetchType="lazy/eager":lazy表示延迟加载,eager表示立即加载
-->
<association property="dept"
select="com.gec.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
column="did"
fetchType="eager"></association>
</resultMap>
<!-- Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
select * from t_emp where eid = #{eid}
</select>
<!-- Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);-->
<select id="getEmpAndDeptByStepTwo" resultType="Dept">
select * from t_dept where did = #{did}
</select>
一对多关系可以用collection(根据部门id查询所在员工的信息)
/*
* 通过分步查询查询部门以及部门中所有员工信息
* 分步查询第一步:查询部门信息
*
* */
Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
/*
* 通过分步查询查询部门以及部门中所有员工信息
* 分步查询第二步:根据did查询员工信息
*
* */
List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
xml映射文件
<resultMap id="deptAndEmpResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<!--
collection:处理一对多关系的映射
ofType:表示该属性对应的集合中存储数据的类型
-->
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<!-- Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>
<!-- Dept getDeptAndEmpByStepOne(@Param("did") Integer did);-->
<resultMap id="deptAndEmpByStepResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps"
select="com.gec.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
column="did"></collection>
</resultMap>
<select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpByStepResultMap">
select * from t_dept where did = #{did}
</select>
<!-- List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepTwo" resultType="Emp">
select * from t_emp where did = #{did}
</select>