提示:Mybatis的快速上手
文章目录
一、 MyBatis
- MyBatis本是Apache软件基金会的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了Google Code,并且改名为Mybatis。2013年11月迁移到GitHub。
- MyBatis是一个优秀的基于Java的持久层框架,支持自定义SQL,存储过程和高级映射。
- MyBatis对原有JDBC操作进行了封装,几乎消除了所有JDBC代码,使开发者只需关注SQL本身。
- MyBatis可以使用简单的XML或Annotation来配置执行SQL,并自动完成ORM操作,将执行结果返回
1.1创建MyBatis配置文件
创建并配置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">
<!--MyBatis配置-->
<configuration>
<!--JDBC环境配置、选中默认环境-->
<environments default="development">
<!--MySQL数据库环境配置-->
<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>
<!--Mapper注册-->
<mappers>
<!--注册Mapper文件的所在位置-->
<mapper resource="com/nemo/dao/UserMapper.xml"/>
</mappers>
</configuration>
- 注意:mapper.xml默认建议存放在resources中,路径不能以/开头
1.2 开发步骤
- 建表 定义实体类(所需CURD操作的实体类)
- 定义DAO接口(根据所需DAO定义接口、已经方法)
- 编写Mapper.xml
- 注册Mapper
- 测试(MyBatis的API操作方式)
测试案例
- UserMapper
package com.nemo.dao;
import com.nemo.pojo.User;
import java.util.List;
/*
Mapper接口类
*/
public interface UserMapper {
//查询全部用户
List<User> selectUser();
//根据ID查询用户
User getUserById(int id);
//insert一个用户
int addUser(User user);
//修改用户
Integer updateUser(User user);
//删除用户
Integer deleteUser(int id);
}
- 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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<!--select查询语句-->
<select id="selectUser" resultType="com.nemo.pojo.User">
select * from mybatis.user
</select>
<select id="getUserById" parameterType="int" resultType="com.nemo.pojo.User">
select * from mybatis.user where id = #{id}
</select>
<!--对象中的属性可以直接取出来-->
<insert id="addUser" parameterType="com.nemo.pojo.User">
insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="com.nemo.pojo.User">
update mybatis.user set name = #{name} , pwd = #{pwd} where id = #{id};
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id};
</delete>
</mapper>
- UserDaoTest
package com.nemo.dao;
import com.nemo.pojo.User;
import com.nemo.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
SqlSession session = MybatisUtils.getSession();
//方法一:
//List<User> users = session.selectList("com.kuang.mapper.UserMapper.selectUser");
//方法二:
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
@Test
public void getUserById(){
//获取session的执行对象
SqlSession session = MybatisUtils.getSession();
//实现绑定的接口类
UserMapper mapper = session.getMapper(UserMapper.class);
//得到实例就可用了,mapper
User user = mapper.getUserById(1);
//输出
System.out.println(user);
//关闭
session.close();
}
/**
* 增删改需要提交事务
*/
@Test
public void addUser(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.addUser(new User(6, "迪迦", "325641"));
if (i>0){
System.out.println("插入成功 ");
}
//提交事务
session.commit();
session.close();
}
/**
* 更行操作
*/
@Test
public void updateUser(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.updateUser(new User(4,"1奥特曼","5269874"));
session.commit();
session.close();
}
/**
* 删除操作
*/
@Test
public void deleteUser(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUser(6);
session.commit();
session.close();
}
}
2.1 模板型增删改查
2.1.1 //接口类编写的
//查询全部用户
@Select("select id,dataname from mydata") //sql语句
List<HeaderMation> getAllUser();
//根据id查询用户
@Select("select * from mydata where id = #{id}")//sql语句
HeaderMation selectUserById(@Param("id") int id);
//添加一个用户
@Insert("insert into mydata (id,dataname) values (#{id},#{dataname})")//sql语句
int addUser(HeaderMation user);
//修改一个用户
@Update("update mydata set name=#{dataname},where id = #{id}")//sql语句
int updateUser(HeaderMation user);
//根据id删除用
@Delete("delete from mydata where id = #{id}")//sql语句
int deleteUser(@Param("id")int id);
2.1.2 //测试类编写
package com.nemo.dao;
import com.nemo.pojo.HeaderMation;
import com.nemo.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class HeaderMationTest {
@Test //通过List集合查询全部用户
public void testGetAllUser() {
SqlSession session = MybatisUtils.getSession();
//本质上利用了jvm的动态代理机制
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
List<HeaderMation> headerMations = mapper.getAllUser();
for (HeaderMation headerMation : headerMations){
System.out.println(headerMation);
}
session.close();
}
@Test //根据用户id查询单个用户
public void testSelectUserById() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
HeaderMation headerMation = mapper.selectUserById(1);
System.out.println(headerMation);
session.close();
}
@Test //通过id,name增加新的用户
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
HeaderMation headerMation = new HeaderMation(7, "迪迦");
mapper.addUser(headerMation);
session.close();
}
@Test //通过id,name更新用户
public void testUpdateUser() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
HeaderMation headerMation = new HeaderMation(5, "hello");
mapper.updateUser(headerMation);
session.close();
}
@Test //通过id删除对应的用户
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
mapper.deleteUser(7);
session.close();
}
}
3.1 Log4j
- 导入log4j依赖
- 创建并配置log4j.properties
log4j依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
4.1 CRUD操作
4.11 查询
标签 < select id="" resultType="">
- UserMapper
package com.nemo.dao;
import com.nemo.pojo.User;
import java.util.List;
import java.util.Map;
/*
Mapper接口类
*/
public interface UserMapper {
//查询全部用户
List<User> selectUser();
//根据ID查询用户
User getUserById(int id);
//选择全部用户实现分页
List<User> selectUser(Map<String,Integer> map);
}
- 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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<!--别名-->
<resultMap id="UserMap" type="User">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<!--select查询语句-->
<select id="selectUser" resultType="com.nemo.pojo.User">
select * from mybatis.user
</select>
<select id="getUserById" parameterType="int" resultType="com.nemo.pojo.User">
select * from mybatis.user where id = #{id}
</select>
<select id="selectUser" parameterType="map" resultMap="UserMap">
select * from user limit #{startIndex},#{pageSize}
</select>
</mapper>
注:@param可以进行参数绑定,更方便
4.13 模糊查询
- UserMapper
package com.nemo.dao;
import com.nemo.pojo.User;
import java.util.List;
import java.util.Map;
/*
Mapper接口类
*/
public interface UserMapper {
List<User> selectAllById(@Param("id") int id);
}
- 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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<!--别名-->
<resultMap id="UserMap" type="User">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<select id="selectAllById" resultMap="UserMap">
select * from user
where name like concat('%',#{id},'%') --拼接'%'
</select>
</mapper>
4.14 删除
标签 < delete id="" parameterType="" >
- UserMapper
package com.nemo.dao;
import com.nemo.pojo.User;
import java.util.List;
import java.util.Map;
/*
Mapper接口类
*/
public interface UserMapper {
//删除用户
Integer deleteUser(int id);
}
- 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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id};
</delete>
</mapper>
4.15 修改
标签 < update id="" parameterType="" >
- UserMapper
package com.nemo.dao;
import com.nemo.pojo.User;
import java.util.List;
import java.util.Map;
/*
Mapper接口类
*/
public interface UserMapper {
//修改用户
Integer updateUser(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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<update id="updateUser" parameterType="com.nemo.pojo.User">
update mybatis.user set name = #{name} , pwd = #{pwd} where id = #{id};
</update>
</mapper>
4.16 添加
标签 < insert id="" parameterType="" >
- UserMapper
package com.nemo.dao;
import com.nemo.pojo.User;
import java.util.List;
import java.util.Map;
/*
Mapper接口类
*/
public interface UserMapper {
//insert一个用户
int addUser(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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<!--对象中的属性可以直接取出来-->
<insert id="addUser" parameterType="com.nemo.pojo.User">
insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
</mapper>
5.1 缓存
内存中的一块存储空间,服务于某个应用程序,皆在将频繁读取的数据临时保存在内存中,便于二次快速访问。
5.1.1 一级缓存
SqlSession级别的缓存,同一个SqlSession的发起多次同构查询,会将数据保存在一级缓存中。
- 注意 :无需任何配置,默认开启一级缓存。
5.1.2 二级缓存
SQLSessionFactory级别的缓存,同一个SqlSessionFactory构建的SqlSession发起的多次同构查询,会将数据保存在二级缓存中。
- 注意:在sqlSession.commit()或者sqlSession.close()之后生效。
6.1 MyBatis工具类
- Resource:用于获得读取配置文件的IO对象,耗费资源,建议通过 IO一次性读取所有所需要的数据。
- SqlSessionFactory:SqlSession工厂类,内存占用多,耗费资源,建议每一个应用只创建一个对象。
- SqlSession:相当于Connection,可控制事务,应为线程私有,不被多线程共享。
- 将获得连接、关闭连接、提交事务、回滚事务、获得接口实现类等方法进行封装。
- MabatisUtils
package com.nemo.utils;
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;
//sqlSessionFactory --> sqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 使用Mybatis第一步获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession连接
public static SqlSession getSession(){
return getSession(true); //事务自动提交
}
public static SqlSession getSession(boolean flag){
return sqlSessionFactory.openSession(flag);
}
}
- 测试方法(通用模板)
package com.nemo.dao;
import com.nemo.pojo.HeaderMation;
import com.nemo.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class HeaderMationTest {
@Test
public void testGetAllUser() {
SqlSession session = MybatisUtils.getSession();
//本质上利用了jvm的动态代理机制
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
List<HeaderMation> headerMations = mapper.getAllUser();
for (HeaderMation headerMation : headerMations){
System.out.println(headerMation);
}
session.close();
}
/**
* 查询
*/
@Test
public void testSelectUserById() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
HeaderMation headerMation = mapper.selectUserById(1);
System.out.println(headerMation);
session.close();
}
/**
* 增加
*/
@Test
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
HeaderMation headerMation = new HeaderMation(7, "迪迦");
mapper.addUser(headerMation);
session.close();
}
/**
* 更新
*/
@Test
public void testUpdateUser() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
HeaderMation headerMation = new HeaderMation(5, "hello");
mapper.updateUser(headerMation);
session.close();
}
/**
* 删除
*/
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
HearderMationMapper mapper = session.getMapper(HearderMationMapper.class);
mapper.deleteUser(7);
session.close();
}
}
7.1 ORM映射
MyBatis只能自动维护库表“列名”与“属性名”相同时的一一对应关系,二者不同时,无法自动ORM。
7.1.1 结果集映射
通过< resultMap id="" type="">映射,匹配列名与属性名
<?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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.nemo.dao.UserMapper">
<!--定义resultMap标签-->
<resultMap id="UserMap" type="User">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<!--使用resultMap作为ORM映射依据-->
<select id="selectUserById" resultMap="UserMap">
select id , name , pwd from user where id = #{id}
</select>
</mapper>
8.1 MyBatis-多表
- 一对一关系
- 一对多关系
- 多对多关系
8.1.1 一对一
8.1.2 一对多
8.1.3 多对多
9.1 动态SQL
MyBatis的映射文件中支持在基础SQL上添加一些逻辑操作,并动态凭借完整的SQL之后在执行,以达到SQL复用、简化编程的效果。
9.1.1 < sql>
<sql id="Base_Column_List"><!--定义SQL片段-->
log_id, activity_id, activity_name, review_type, status, fail_type, failure, review_id,
review_time, description, log_time
</sql>
<!--通过Id引用SQL片段-->
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from log_activity_review
where log_id = #{logId,jdbcType=BIGINT}
</select>
9.1.2< where>
<select id="selectAllByActivityIdAndActivityName" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from log_activity_review
where activityId = #{activityId,jdbcType=VARCHAR}
and activityName = #{activityName,jdbcType=VARCHAR}
</select>
9.1.3 < set>
<update id="updateByPrimaryKeySelective" parameterType="com.orangelin.nemo.pojo.LogActivityReview">
update log_activity_review
<set>
<if test="activityId != null">
activity_id = #{activityId,jdbcType=VARCHAR},
</if>
<if test="activityName != null">
activity_name = #{activityName,jdbcType=VARCHAR},
</if>
</set>
where log_id = #{logId,jdbcType=BIGINT}
</update>
9.1.4 < trim>
< trim prefix="" suffix="" perfixOverrides="" suffixOverrides="">代替< where>、< set>。
<insert id="insertSelective" parameterType="com.orangelin.nemo.pojo.LogActivityReview">
insert into log_activity_review
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="logId != null">
log_id,
</if>
<if test="activityId != null">
activity_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="logId != null">
#{logId,jdbcType=BIGINT},
</if>
<if test="activityId != null">
#{activityId,jdbcType=VARCHAR},
</if>
</trim>
</insert>
9.1.5 < foreach>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
select * from blog where 1=1 and (id=1 or id=2 or id=3)
-->
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
参数 | 描述 | 取值 |
---|---|---|
collection | 容器类型 | list、array、map |
open | 起始符 | ( |
close | 结束符 | ) |
separate | 分隔符 | , |
index | 下标号 | 从0开始,依次递增 |
item | 当前项 | 任意名称(循环中通过#{任意名称} 表达式访问) |