写在前面
MyBatis
- 数据层/持久层的框架,内部封装了jdbc,只需要关注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="userMapper">
<select id="findAll" resultType="com.java.domain.User">
select * from user;
</select>
</mapper>
<?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 default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///dbtest3"/>
<property name="username" value="root"/>
<property name="password" value="123456789"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/java/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml")
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream)
//获得seesion回话对象
SqlSession sqlSession = sqlSessionFactory.openSession()
//执行操作 参数:映射文件中的namespace.id
List<User> userList = sqlSession.selectList("userMapper.findAll")
System.out.println(userList)
//释放资源
sqlSession.close()
映射文件

<select id="find" resultType="com.java.domain.User" parameterType="java.lang.Integer">
select * from user where id = #{id};
</select>
User user = sqlSession.selectOne("userMapper.find", 1);
//调用
sqlSession.insert("userMapper.save", new User("lisi", "31232141"));
//mybatis默认事务不提交
sqlSession.commit();
//映射文件 传递对象
<insert id="save" parameterType="com.java.domain.User">
insert into user values (#{id}, #{username}, #{password})
</insert>
<update id="update" parameterType="com.java.domain.User">
update user set username=#{username}, password=#{password} where id = #{id};
</update>
//调用
sqlSession.update("userMapper.update",new User(4,"zhangsan","32131"));
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id};
</delete>
//调用
sqlSession.delete("userMapper.delete",4);
动态sql
- Dynamic sql
if根据是否有条件拼接sql语句
<select id="findByCondition" parameterType="user" resultType="user">
select * from user
<where>
<if test="id != 0">
and id =
</if>
<if test="username != null">
and username =
</if>
<if test="password != null">
and password =
</if>
</where>
</select>
select * from user WHERE id in ( ? , ? , ? )
<select id="findByIds" parameterType="list" resultType="user">
select * from user
<where>
<foreach collection="list" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
抽取
<sql id="selectUser">select * from user</sql>
<include refid="selectUser"></include>
核心文件
environments
- 配置环境

transacationManager jDBC类型,框架通过connection进行控制;MANAGED类型,几乎没做什么,从来不提交或回滚,通过容器管理,默认会关闭连接
dataSource POOLED池化;UNPOOLED每次被请求时打开或者关闭连接;JNDI为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用
mappers
- 加载映射文件

properties
<properties resource="jdbc.properties"/>
typeAilases
- 定义别名
- 基本数据类型的包装类可以用小写形式
- 要放在
properties标签后面,会有顺序要求
<typeAliases>
<typeAlias type="com.java.domain.User" alias="user"/>
</typeAliases>
//映射文件的修改
<select id="find" resultType="user" parameterType="int">
select * from user where id =
</select>
<package name="com.java.domain"/>
typeHandlers
- 类型处理器
- 将
Date转换成毫秒值存储在数据库中
- 自定义类型处理器
public class DateTypeHander extends BaseTypeHandler<Date> {
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i, time);
}
@Override
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
long time = resultSet.getLong(s);
Date date = new Date(time);
return date;
}
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long time = resultSet.getLong(i);
Date date = new Date(time);
return date;
}
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long time = callableStatement.getLong(i);
Date date = new Date(time);
return date;
}
}
<typeHandlers>
<typeHandler handler="com.java.handler.DateTypeHander"/>
</typeHandlers>
plugins
- 插件,扩展功能
- 分页助手
pageHelper
- 坐标
pagehelper jsqlparser
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>1.4</version>
</dependency>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
PageHelper.startPage(2,3);
PageInfo<User> pageInfo = new PageInfo<User>(userList);
System.out.println("当前页" + pageInfo.getPageNum());
System.out.println("每条显示条数" + pageInfo.getPageSize());
System.out.println("总条数" + pageInfo.getTotal());
System.out.println("总页数" + pageInfo.getPages());
System.out.println("上一页" + pageInfo.getPrePage());
System.out.println("下一页" + pageInfo.getNextPage());
System.out.println("是否是第一页" + pageInfo.isIsFirstPage());
System.out.println("是否是最后一页" + pageInfo.isIsLastPage());
相关API
SqlSessionFactoryBuilder工厂构建器,通过加载mybatis核心文件的输入流构建
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml")
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream)
sqlSessionFactory工厂对象,创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSessionFactory.openSession(true);
接口代理实现持久层
- 命名空间为接口全路径;方法名相同;方法返回值类型相同

- 映射文件
<mapper namespace="com.java.dao.UserMapper">
<select id="findAll" resultType="user">
select * from user;
</select>
<select id="findById" resultType="user" parameterType="int">
select * from user where id = #{id};
</select>
</mapper>
public interface UserMapper {
List<User> findAll() throws IOException;
User findById(int id);
}
//mapper代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class)
List<User> userList = mapper.findAll()
User user = mapper.findById(2)
System.out.println(userList)
System.out.println(user)
多表操作
一对一
- 订单与用户与一对一
- 通过引用对象,在实体中体现
private User user;
SELECT *, o.id oid, u.id uid FROM orders o, user u WHERE o.uid = u.id;
<resultMap id="orderMap" type="order">
<id column="oid" property="id"/>
<result column="ordertime" property="ordertime"/>
<result column="total" property="total"/>
<result column="uid" property="user.id"/>
<result column="username" property="user.username"/>
<result column="birthday" property="user.birthday"/>
<result column="password" property="user.password"/>
</resultMap>
<select id="findAll" resultMap="orderMap">
SELECT *, o.id oid, u.id uid FROM orders o, user u WHERE o.uid = u.id;
</select>
<resultMap id="orderMap" type="order">
<id column="oid" property="id"/>
<result column="ordertime" property="ordertime"/>
<result column="total" property="total"/>
<association property="user" javaType="user">
<id column="uid" property="id"/>
<id column="username" property="username"/>
<id column="birthday" property="birthday"/>
<id column="password" property="password"/>
</association>
</resultMap>
一对多
- 一个用户对应多个订单
- 通过集合将多个订单封装到一个用户中
private List<Order> orderList;
<resultMap id="userMap" type="user">
<id column="uid" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="birthday" property="birthday"/>
<collection property="orderList" ofType="order">
<id column="oid" property="id"/>
<result column="ordertime" property="ordertime"/>
<result column="total" property="total"/>
</collection>
</resultMap>
<select id="findAll" resultMap="userMap">
SELECT *, o.id oid, u.id uid FROM user u, orders o WHERE u.id = o.uid;
</select>
多对多
- 通过集合封装在实体中
private List<Role> roleList;
<resultMap id="userRoleMap" type="user">
<id column="userId" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phoneNum" property="phoneNum"/>
<collection property="roleList" ofType="role">
<id column="roleId" property="id"/>
<result column="roleName" property="roleName"/>
<result column="roleDesc" property="roleDesc"/>
</collection>
</resultMap>
<select id="findUserAndRole" resultMap="userRoleMap">
SELECT * FROM sys_user u, sys_user_role ur, sys_role r WHERE u.id = ur.userId AND r.id = ur.roleId;
</select>
注解开发
简单实用
@Select("select * from user;")
List<User> findAll();
@Select("select * from user where id = #{id};")
User findById(int id);
@Insert("insert into user values (#{id}, #{username}, #{password}, #{birthday});")
void save(User user);
@Update("update user set username=#{username} where id = #{id};")
void update(User user);
@Delete("delete from user where id = #{id};")
void delete(int id);
<mappers>
<package name="com.java.dao"/>
</mappers>
一对一查询
@Select("select *, o.id oid, u.id uid from orders o, user u where o.uid = u.id;")
@Results({
@Result(column = "oid", property = "id"),
@Result(column = "total", property = "total"),
@Result(column = "ordertime", property = "ordertime"),
@Result(column = "uid", property = "user.id"),
@Result(column = "username", property = "user.username"),
@Result(column = "password", property = "user.password"),
@Result(column = "birthday", property = "user.birthday")
})
List<Order> findAll();
@Select("select * from orders")
@Results({
@Result(column = "id", property = "id"),
@Result(column = "total", property = "total"),
@Result(column = "ordertime", property = "ordertime"),
@Result(
property = "user",
column = "uid",
javaType = User.class,
one = @One(select = "com.java.dao.UserMapper.findById")
)
})
List<Order> findAll();
一对多
@Select("select * from user;")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(column = "birthday", property = "birthday"),
@Result(
property = "orderList",
column = "id",
javaType = List.class,
many = @Many(select = "com.java.dao.OrderMapper.findByUid")
)
})
List<User> findUserAndOrderAll();
多对多
@Select("select * from sys_user;")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(column = "email", property = "email"),
@Result(column = "phoneNum", property = "phoneNum"),
@Result(
property = "roleList",
column = "id",
javaType = List.class,
many = @Many(select = "com.java.dao.RoleMapper.findByUserId")
)
})
List<User> findUserAndRole();
@Select("select * from sys_user_role ur, sys_role r where ur.roleId = r.id and ur.userId =
List<Role> findByUserId(int userId)
实现foreach
@Select("<script> " +
"select * from sys_user where " +
"<foreach collection= 'list' open='id in (' close=')' item='id' separator=','> #{id} </foreach>" +
"</script>"
)
List<User> findByIds(List<Integer> ids);
实现where和if
@Select("<script> " +
"select * from sys_user " +
"<where> " +
"<if test='id != 0'>" +
"and id = #{id} " +
"</if>" +
"<if test='username != null'>" +
"and username = #{username} " +
"</if>" +
"<if test='password != null'>" +
"and password = #{password} " +
"</if>" +
"</where>" +
"</script>")
List<User> findByCondition(User user);
SSM框架整合
- applicationContex.xml配置mybatis.xml,直接在容器中生成mapper的实现类
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:sqlMapConfig-spring.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.java.mapper"/>
</bean>
<typeAliases>
<package name="com.java.domain"/>
</typeAliases>