1. MyBatis常用API详细分析
1.1. SqlSessionFactoryBuilder
通过读取配置文件,创建sessionFactory String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); |
1.2. SqlSessionFactory
会话工厂,用来创建会话
SqlSession openSession = sqlSessionFactory.openSession();
|
1.3. SqlSession
是一个面向用户的接口, sqlSession中定义了数据库操作方法。 每个线程都应该有它自己的SqlSession实例。 SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是方法范围。 打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。 |
2. Dao封装
2.1. 定义UserDao
public interface UserDao {
public List<User> queryUser();
public User queryUserById();
public void saveUser(User user);
public void updateUser(User user);
public void deleteUser(int id);
}
|
2.2. 定义UserDaoImpl
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl() {
// 配置文件
try {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据用户id删除用户
*/
@Override
public User queryUserById() {
SqlSession openSession = sqlSessionFactory.openSession();
User user = openSession.selectOne("test.selectUserById", 5);
openSession.close();
return user;
}
/**
* 删除用户
*/
@Override
public void deleteUser(int id) {
SqlSession openSession = sqlSessionFactory.openSession();
int delete = openSession.delete("test.deleteUser", id);
System.out.println(delete);
openSession.commit();
openSession.close();
}
|
3. 动态代理方式封装
3.1. 编写规范
Mapper接口开发需要遵循以下规范: Mapper.xml文件中的namespace与mapper接口的类路径相同。 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同 |
3.2. 配置UserMapper.xml
<mapper namespace="com.example.batis.dao.UserMapper">
其他配置和上述bean一致
|
3.3. 创建UserMapper对象
public interface UserMapper {
public List<User> selectUser() throws Exception;
public User selectUserById() throws Exception;
public void saveUser(User user) throws Exception;
public void updateUser(User user) throws Exception;
public void deleteUser(int id) throws Exception;
}
|
3.4. 测试
@Test
public void testMapperQuery() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> queryUser = userMapper.selectUser();
for (User user : queryUser) {
System.out.println(user.toString());
}
}
|
4. 配置详解
4.1. SqlMapConfig.xml中配置的内容和顺序
properties |
(属性) |
settings |
(全局配置参数)
|
typeAliases |
(类型别名)
|
typeHandlers |
(类型处理器) |
objectFactory |
(对象工厂) |
plugins |
(插件)
|
environments |
(环境集合属性对象)
|
transactionManager |
(事务管理) |
dataSource |
(数据源) |
mappers |
(映射器) |
4.2. properites关联properties文件
<properties resource="db.properties"/> MyBatis 将按照下面的顺序来加载属性:
在 properties 元素体内定义的属性首先被读取。 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
|
4.3. typeAliases(类型别名)
4.3.1. Mybatis别名
别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map
|
4.3.2. 自定义别名
指定具体的类
<typeAlias type="com.example.batis.domain.User" alias="user" />
指定包名,会扫描所有的bean类,别名以类名大小写定义即可
<package name="com.example.batis.domain" />
|
4.4. Mappes配置
4.4.1. 使用相对于类路径的资源
<mapper resource="com/example/batis/dao/UserMapper.xml" />
|
4.4.2. 类路径
<mapper class="com.example.batis.dao.UserMapper" />
此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
|
4.4.3. 包路径
<package name="com.example.batis.dao" />
|
5. 输入映射和输出映射
5.1. 普通方式输入映射
回顾前边所学内容的parameterType
5.2. vo方式输入映射 VOvalue Object
5.2.1. 定义vo对象,用来放置输入的数据
public class QueryVO {
User user;
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
}
|
5.2.2. Mapper.xml
<select id="getUserByUserNameAndSex" resultType="user"
parameterType="com.example.mybatis.domain.QueryVO">
select * from t_user where username=#{user.username}
and sex=#{user.sex}
</select>
|
5.2.3. 测试类中
@Test
public void testQueryVO() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
QueryVO queryVO = new QueryVO();
User user = new User();
user.setUsername(" 王小九");
user.setSex(" 女");
queryVO.setUser(user);
List<User> selectUserLike = userMapper.getUserByUserNameAndSex(queryVO);
for (User user2 : selectUserLike) {
System.out.println(user2);
}
}
|
5.3. 输出映射
5.3.1. 普通方式输出映射
回顾知识
5.3.2. resultMap类型数据
特点:当列和字段不一致时,可以指定列和字段的对应关系
<select id="getUserListResultMap" resultMap="userListResultMap">
select id
_id,username _username,password _password,sex _sex from t_user
</select>
如果返回类型配置为 resultType="user",由于查询出来的column列名称不能和user中字段名名称对应,会导致出现错误
指定对象和数据库列的映射关系
<resultMap type="user" id="userListResultMap">
<id column="_id" property="id" />
<result column="_username" property="username" />
<result column="_password" property="password" />
<result column="_sex" property="password" />
</resultMap>
|
6. MyBatis框架原理分析
Configuration MyBatis所有的配置信息都维持在Configuration对象之中。
SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
MappedStatement MappedStatement维护了一条<select|update|delete|insert>节点的封装,
封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所需要的参数,
ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换
· SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
· BoundSql 表示动态生成的SQL语句以及相应的参数信息
7. 动态SQL
通过mybatis提供的各种标签方法实现动态拼接sql。
7.1. if 条件判断某些语句添加或者不添加
7.1.1. 回顾JDBC代码写法
String sql="select * from t_user where 1=1";
if(user.getUsername()!=null&&user.getUsername()!=""){
sql=sql+"and username like "+user.getUsername();
}
if(user.getSex()!=null&&user.getSex()!=""){
sql=sql+"and sex=" +user.getSex();
}
|
7.1.2. mybatis中mapper.xml中配置
select id="getConditionUser" resultType="user" parameterType="user">
select * from t_user where 1=1
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
<if test="sex!=null and sex!=''">
and sex=#{sex}
</if>
</select>
|
7.1.3. where 代替sql中的where
select id="getConditionUser" resultType="user" parameterType="user">
select * from t_user where 1=1
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
<if test="sex!=null and sex!=''">
and sex=#{sex}
</if>
</select>
|
7.2. foreach 用法 通过遍历方式映射参数
7.2.1. xml中写法
<select id="getUserByIds" parameterType="com.example.mybatis.domain.QueryVO"
resultType="user">
select * from t_user where 1=1
<foreach collection="ids" open="and id in(" close=")"
separator="," item="id">
#{id}
</foreach>
</select>
* 参数名称
collection 代表集合
open 代表开始sql语句
close 代表sql结束
seperator 代表分割符
item 代表集合遍历过程中的对象
|
7.2.2. QueryVO中定义
public class QueryVO {
public List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
|
|
7.2.3. 测试代码
public class QueryVO {
public List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
|