SqlSession作用范围
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是以工具类方式来使用,需要创建sqlSessionFactory就new一个SqlSessionFactoryBuilder。sqlSessionFactory
正常开发时,以单例方式管理sqlSessionFactory,整个系统运行过程中sqlSessionFactory只有一个实例,将来和spring整合后由spring以单例方式管理sqlSessionFactory。SqlSession
sqlSession是一个面向用户(程序员)的接口,程序员调用sqlSession的接口方法进行操作数据库。
由于sqlSession是线程不安全,(查看MyBatis的源码,Executor的实现类中currentSql、currentStatement等为成员变量),所以sqlSession最佳应用范围在方法体内,在方法体内定义局部变量使用sqlSession。
持久层开发的两种方法
原始的DAO开发方式
DAO接口和实现
UserDao
public interface UserDao {
public User findUserById(int id) throws Exception;
public List<User> findUserByUsername(String username) throws Exception;
public void insertUser(User user) throws Exception;
}
UserDaoImpl
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.close();
return user;
}
@Override
public List<User> findUserByUsername(String username) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByName", username);
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
}
测试类
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException {
String resource = "SqlMapConfig.xml";
//MyBatis提供了Resources读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserById(1);
System.out.println(user);
}
}
User.xml同上一篇博文
mapper自动代理的开发方式
mapper开发规范
- mapper.xml中namespace指定为mapper接口的全限定名
此步骤目的:通过mapper.xml和mapper.java进行关联。 - mapper.xml中statement的id就是mapper.java中方法名
- mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
- mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.
mapper开发的主要mapper.xml和mapper接口
mapper映射文件的命名方式建议:类名+Mapper.xml
mapper接口(相当于DAO接口)的命名方式建议:类名+Mapper
UserMapper
public interface UserMapper {
public User findUserById(int id) throws Exception;
public List<User> findUserByName(String username) throws Exception;
}
UserMapper.xml
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id= #{id}
</select>
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
select * from user where username like '%${value}%'
</select>
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
测试类:
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
}
@Test
public void testFindUserByUsername() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByName("小明");
System.out.println(list);
}
@Test
public void testInsertUser() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("李奎");
userMapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
}
补充SqlMapConfig中几个配置
typeAliases
单个别名定义:
alias:别名,type:别名映射的类型
<typeAliases>
<typeAlias type="cn.itcast.mybatis.po.User" alias="user"/>
</typeAliases>
批量别名定义
指定包路径,自动扫描包下边的pojo,定义别名,别名默认为类名(首字母小写或大写)
<typeAliases>
<package name="cn.itcast.mybatis.po"/>
</typeAliases>
mappers配置
resource引用
<mappers>
<mapper resource="sqlmap/User.xml" />
</mappers>
class引用mapper接口
class:配置mapper接口全限定名
要求:需要mapper.xml和mapper.java同名并且在一个目录中
<mappers>
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
</mappers>
批量mapper配置
通过package进行自动扫描包下边的mapper接口,
要求:需要mapper.xml和mapper.java同名并且在一个目录 中
<mappers>
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
输入输出映射
parameterType
parameterType传递POJO包装对象,可以定义POJO包装类型扩展mapper接口输入参数的内容。
(使用场景:自定义查询等)
resultType
指定输出结果的类型(简单类型、POJO、HashMap…),将SQL查询结果映射为Java对象 。
**注意:**SQL查询的列名要和resultType指定POJO的属性名相同,指定相同属性方可映射成功,如果SQL查询的列名和resultType指定POJO的属性名全部不相同,list中无法创建POJO对象的。
resultMap
将SQL查询结果映射为java对象。
如果SQL查询列名和最终要映射的POJO的属性名不一致,使用resultMap将列名和POJO的属性名做一个对应关系 (列名和属性名映射配置)
定义resultMap
id:mapper.xml中的唯一标识
type:最终要映射的pojo类型
列名和属性名映射配置
id:要映射结果集的唯 一标识 ,称为主键
result:就是普通列的映射配置
column:结果集的列名
property:type指定的哪个属性中
<resultMap id="userListResultMap" type="user" >
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="birthday_" property="birthday"/>
</resultMap>
动态SQL
SQL片段
通过sql片段可以将通用的sql语句抽取出来,单独定义,在其它的statement中可以引用sql片段。
通用的sql语句,常用:where条件、查询列。
SQL片段定义
<sql id="query_user_where">
</sql>
SQL片段引用
<include refid="query_user_where"></include>
if和where
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex = #{userCustom.sex}
</if>
</if>
</sql>
foreach
在statement通过foreach遍历parameterType中的集合类型。
collection:集合的属性
open:开始循环拼接的串
close:结束循环拼接的串
item:每次循环取到的对象
separator:每两次循环中间拼接的串
<sql id="query_user_where">
<if test="userCustom!=null">
<foreach collection="ids" open=" AND id IN ( " close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</sql>