mybatis简单实例
在这个实例中主要总结了以下几点:
1. 映射器——接口和XML文件的关系
2. mybatis配置文件的编写
3. SqlSessionFactoryUtils的单例设计模式
4. SqlSession的try … finally 结构,确保其正确关闭
目录结以及log4j配置
目录结构:
log4j配置:
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.lly.mybatis.example.mapper.RoleMapper=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
映射器
首先,我先给出映射器接口的代码
package lly.mybatis.example.mapper;
import java.util.List;
import lly.mybatis.example.pojo.Role;
public interface RoleMapper {
public int insertRole(Role role);
public int deleteRole(Long id);
public int updateRole(Role role);
public Role getRole(Long id);
public List<Role> findRoles(String roleName);
}
接下来是映射器的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="lly.mybatis.example.mapper.RoleMapper">
<insert id="insertRole" parameterType="long">
INSERT INTO
role {roleName,note}
VALUE
(#{roleName},#{note})
</insert>
<delete id="deleteRole" parameterType="long">
DELETE FROM
role
WHERE
id=#{id}
</delete>
<update id="updateRole" parameterType="role">
UPDATE
role
SET
roleName = #{roleName} , note = #{note}
WHERE
id = #{id}
</update>
<select id="getRole" parameterType="role" resultType="role">
SELECT
id,roleName , note
FROM
role
WHERE
id = #{id}
</select>
<select id="findRoles" parameterType="string" resultType="role">
SELECT
id,
roleName,
note
FROM
role
WHERE
roleName
LIKE
CONCAT
('%',#{roleName},'%')
</select>
</mapper>
映射器的接口和XML关系主要有以下几点:
1. xml中mapper标签的namespace属性值为映射器接口的全限定名。
2. xml中的每个sql语句的id属性对应的是接口的方法名。
3. xml中的每个sql语句的参数属性对应的是接口中相应方法的参数类型(在Mybatis中相应的对应规则)。
正是有了以上几点对应规则,映射器的动态代理才能被创建。
mybatis配置文件
<?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>
<!-- 别名 -->
<typeAliases>
<!--typeAliases 标签下可以定义多个 typeAlias 标签, 其中每一个代表定义了一个别名。
下面的例子意味着:
定义一个别名为role 代表了 lly.mybatis.example.pojo.Role 这个全限定名-->
<typeAlias alias="role" type="lly.mybatis.example.pojo.Role"/>
</typeAliases>
<!-- 数据库环境 -->
<environments default="development">
<!-- environments 标签下可以定义多个 environment 标签, 其中每一个代表定义了一种数据库环境。 -->
<environment id="development">
<!--transactionManager 配置事务管理器 -->
<transactionManager type="JDBC"/>
<!-- dataSource 配置数据库信息 POOLED 代表采用Mybatis内部提供连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<!-- mappers 标签下可以定义多个 mapper 标签, 其中每一个代表配置一个mapper文件。 -->
<mapper resource="lly/mybatis/example/mapper/RoleMapper.xml"/>
</mappers>
</configuration>
SqlSessionFactoryUtils
package lly.mybatis.example.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class SqlSessionFactoryUtils {
private final static Class<SqlSessionFactoryUtils> LOCK = SqlSessionFactoryUtils.class;
private static SqlSessionFactory sqlSessionFactory = null;
private SqlSessionFactoryUtils(){} //构造方法私有化,单例
//单例模式获得SqlSessionFactory
public static SqlSessionFactory getSqlSessionFactory(){
//线程锁,防止在多线程多次实例化sqlSessionFactory
synchronized (LOCK) {
if(sqlSessionFactory != null){
return sqlSessionFactory;
}
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return sqlSessionFactory;
}
}
//获得SqlSession
public static SqlSession openSession(){
if(sqlSessionFactory == null){
getSqlSessionFactory();
}
return sqlSessionFactory.openSession();
}
}
通过inputStream读取到mybatis配置文件,然后通过SqlSessionFactoryBuilder对象创建了SqlSessionFactory。整个过程看似十分简单,其中内部代码被Builder模式也就是建造者模式隐藏(SqlSessionFactoryBuilder)。
测试代码
package lly.mybatis.example.main;
import lly.mybatis.example.mapper.RoleMapper;
import lly.mybatis.example.pojo.Role;
import lly.mybatis.example.utils.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
public class TestMain {
public static void main(String[] args) {
Logger log = Logger.getLogger(TestMain.class);
SqlSession sqlSession= null;
try {
sqlSession = SqlSessionFactoryUtils.openSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1L);
log.info(role.getRoleName());
}finally{
if(sqlSession != null){
sqlSession.close();
}
}
}
}
在测试代码中,Logger 为日志对象,用于输出结果以及打印mybatis日志。值得一提的是sqlSession的getMapper()方法,其中参数为映射器接口的class对象,正是通过了这个方法,才使得映射器的动态代理对象产生。
其中try…finally结构在finally中确保了SqlSession对象的关闭,避免了资源的浪费。