一、什么是Mybatis
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的
JDBC代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口
和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
二、Mybatis框架原理
1.框架图
2.分析结论
2.1 mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事物处理等信息;
映射文件配置了sql执行相关的信息
2.2 mybatis通过读取配置文件信息,构造出SqlSessionFactory。
2.3 通过SqlSessionFactory可以构建SqlSession,mybatis通过SqlSession操作数据库
2.4 SqlSession本身不能直接操作数据库,是通过底层Executor执行器操作数据库
2.5 Executor执行器要处理的sql信息是封装到一个底层对象MapperStatement中,该对象包括:sql语句、输入参数映射信息、输出结果集映射 信息,其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型
三、代码示例
3.1 所需要的jar包
3.2 配置文件
db.properties
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
db.username=root
db.password=123456
log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
SqlMapConfig.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>
<!-- 加载java的配置文件或者声明属性信息 -->
<properties resource="db.properties"/>
<!-- 配置mybatis的环境信息 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,采用mybatis连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers >
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
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">
<mapper namespace="com.wz.mybatis.mapper.UserMapper">
<!-- 1.根据用户Id查询用户信息 -->
<!--
select : 表示一个MapperStatement对象
id : statement的唯一标示
#{} : 表示一个占位符
#{id} : 里面的id表示输入参数的参数名称
parameterType : 输入参数的java类型
resultType : 输出结果的所映射的java类型
-->
<select id="findUserById" parameterType="int" resultType="com.wz.mybatis.po.User">
SELECT * FROM USER WHERE id =#{id}
</select>
<!-- 2.根据用户名称模糊查询用户列表 -->
<!--
${} : 表示一个sql的连接符
${value} : 里面的value便是输入参数的参数名称,如果该参数是简单类型,那么${}里面的参数名称必须是value
-->
<select id="findUsersByName" parameterType="java.lang.String" resultType="com.wz.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<!-- 3.添加用户 -->
<!--
keyProperty : 查询主键,在标签内需要输入查询主键的sql
order : 指定查询主键的sql和insert语句的执行顺序,相当于insert语句来说
LAST_INSERT_ID() : 该函数是mysql的函数,获取自增主键的id,必须配合insert语句一起使用
-->
<insert id="insertUser" parameterType="com.wz.mybatis.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER
(username,birthday,sex,address)
VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 定义sql片段 -->
<!-- sql片段内,可以定义sql语句中任何部分
sql片段内,最好不用将where和select关键字声明在内
-->
<sql id="whereClause">
<!--
if标签 : 可以对输入的参数进行判断
test : 指定判断表达式
-->
<if test="user != null">
<if test="user.username != null and user.username != ''">
AND username LIKE '%${user.username}%'
</if>
<if test="user.sex != null and user.sex != ''">
AND sex = #{user.sex}
</if>
</if>
<if test="idList != null">
AND id IN
<!--
collection : 表示pojo中集合属性的属性名称
item : 为遍历出的结果声明一个变量名称
open : 遍历开始时,需要拼接的字符串
close : 遍历结束时,需要拼接的字符串
separator : 遍历中间需要拼接的连接符
-->
<foreach collection="idList" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
</sql>
<!-- 综合查询用户列表 -->
<select id="findUserList" parameterType="com.wz.mybatis.po.UserQueryVo" resultType="com.wz.mybatis.po.User">
SELECT * FROM user
<!-- where标签:默认去掉后面第一个AND,如果没有参数,则把自己干掉 -->
<where>
<!-- 引入sql片段 -->
<include refid="whereClause" />
</where>
</select>
<!-- 综合查询用户总数 -->
<select id="findUserCount" parameterType="com.wz.mybatis.po.UserQueryVo" resultType="int">
SELECT count(*) FROM user
<!-- where标签:默认去掉后面第一个AND,如果没有参数,则把自己干掉 -->
<where>
<!-- 引入sql片段 -->
<include refid="whereClause" />
</where>
</select>
</mapper>
User.java
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
//get、set方法
}
UserQueryVo.java
public class UserQueryVo {
//用户信息
public User user;
//商品ID集合
private List<Integer> idList;
//get set方法
}
UserMapper.java
package com.wz.mybatis.mapper;
import java.util.List;
import com.wz.mybatis.po.User;
import com.wz.mybatis.po.UserQueryVo;
public interface UserMapper {
/**
* 根据用户ID查询用户信息
* @param id
* @return
* @throws Exception
*/
public User findUserById(int id) throws Exception;
/**
* 根据用户名字模糊查询用户列表
* @param name
* @return
* @throws Exception
*/
public List<User> findUsersByName(String name) throws Exception;
/**
* 添加用户
* @param user
* @throws Exception
*/
public void insertUser(User user) throws Exception;
/**
* 综合查询
* @param vo
* @return
*/
public List<User> findUserList(UserQueryVo vo);
/**
* 综合查询用户总数
* @param vo
* @return
*/
public int findUserCount(UserQueryVo vo);
}
MybatisTest.java
package com.wz.mybatis.test;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Before;
import org.junit.Test;
import com.wz.mybatis.mapper.UserMapper;
import com.wz.mybatis.po.User;
import com.wz.mybatis.po.UserQueryVo;
public class MybatisTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
// 读取配置文件
// 全局配置文件的路径
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserByIdTest() throws Exception {
// 创建UserMapper对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//由mybatis通过sqlSession来创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void InsertUserTest() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("张三");
user.setAddress("上海");
user.setSex("男");
userMapper.insertUser(user);
System.out.println(user.getId());
sqlSession.commit();
sqlSession.close();
}
@Test
public void findUserByName() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.findUsersByName("王");
System.out.println(users);
sqlSession.close();
}
@Test
public void findUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo vo = new UserQueryVo();
List<Integer> idList = new ArrayList<>();
idList.add(24);
idList.add(25);
idList.add(26);
vo.setIdList(idList);
List<User> users = userMapper.findUserList(vo);
int count = userMapper.findUserCount(vo);
System.out.println("-------users : " + users);
System.out.println("-------count : " + count);
sqlSession.close();
}
}