API
Mybatis 到底解决了什么问题,持久化框架是什么,没出现 Mybatis 之前我们又是怎么来操作数据库的呢?
对于 Java语言 来说,JDBC标准 是比较底层的了,但并非最底层的,可以说 JDBC 是 Java 对于数据库操作的一层封装。
先来看看 JDBC 实现 Mysql 数据库操作:
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("url", "username", "password");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("sql");
int age = rs.getInt("age");
String name = rs.getString("name");
获取到所有的字段数据以后,然后自己封装到相应的实体类里面。
ChannelManageDto u = new ChannelManageDto();
u.setUserName(name);
u.setAge(age);
是不是很麻烦,确实有点。这里还没涉及到事务问题,不然更复杂了。
再来看看 Mybatis 实现 Mysql 数据库操作:
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("");
dataSource.setUrl("");
dataSource.setUsername("");
dataSource.setPassword("");
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.setLazyLoadingEnabled(true);
configuration.setEnhancementEnabled(true);
configuration.getTypeAliasRegistry().registerAlias(Blog.class);
configuration.getTypeAliasRegistry().registerAlias(Post.class);
configuration.getTypeAliasRegistry().registerAlias(Author.class);
configuration.addMapper(CommonMapper.class);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);
SqlSession session = factory.openSession();
List<ChannelManageDto> list = session.selectList("com.rockcode.www.mapper.CommonMapper.queryAllChannels");
这样看,好像代码多了,看不出有什么好处呢,暂时还看不出来,有一个疑问,没有 SQL语句 吗?看下面
public interface CommonMapper {
@Select("select * from t_distributor")
List<ChannelManageDto> queryAllChannels();
}
好处其实很明显,Mybatis 把返回的数据做了封装,不用自己再去封装 ChannelManageDto 了。实质上做了映射,这就是持久化框架做的事。
但是,感觉数据源和业务没有完全分离,很乱。
XML
先来看看 JDBC 实现 Mysql 数据库操作:
创建 spring-db.xml,里面包含
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="url"></property>
<property name="username" value="name"></property>
<property name="password" value="password"></property>
</bean>
这里呢,以前是写在代码里面的,现在放到配置文件里面。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-db.xml");
DataSource dataSource = (DataSource) context.getBean("dataSource");
Connection con = (Connection) dataSource.getConnection();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from t_distributor");
接下来处理和上面 API 是一样,自己封装 ChannelManageDto。
还可以用 JdbcTemplate、SimpleJdbcTemplate、NamedParameterJdbcTemplate 来处理,spring-db.xml 加入
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
<bean id="namedJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
这里和上面又有些不一样了,这三种一般 SimpleJdbcTemplate 用的多。会一种就行了
List<ChannelManageDto> list = simpleJdbcTemplate.query("select * from t_distributor", new RowMapper<ChannelManageDto>() {
@Override
public ChannelManageDto mapRow(ResultSet rs, int rowNum)
throws SQLException {
ChannelManageDto dto = new ChannelManageDto();
dto.setChannelName(rs.getString("name"));
/**
* TODO
*/
return dto;
}
}, 1);
其实呢,这种方式还是得自己封装 ChannelManageDto,总之 JDBC 需要自己动手。
再来看看 Mybatis 实现 Mysql 数据库操作:
创建 mybatis-config.xml,里面包含
<configuration>
<properties>
<property name="url" value="url" />
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="username" value="username" />
<property name="password" value="password" />
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- mybatis 3.2.1 及以上版本 -->
<package name="com.rockcode.www.mapper"></package>
</mappers>
</configuration>
那么和 API 方式有什么不同呢?来看看
String resource = "mybatis-config.xml";
Reader inputStream;
try {
inputStream = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
List<Map<String,Object>> list = session.selectList("com.rockcode.www.mapper.CommonMapper.queryAllChannels");
} catch (IOException e) {
}
还有另外一种方式,将上面的 <package name="com.rockcode.www.mapper"></package> 改成 <mapper resource="mappers/CommonMapper.xml"/>
这种方式,彻底将 SQL语句 和 Mapper 接口分离了,像 CommonMapper
public interface CommonMapper {
// @Select("select * from t_distributor")
List<ChannelManageDto> queryAllChannels();
}
已经不需要 @Select 了
再来看看 CommonMapper.xml,这里面配置了 SQL语句。
<mapper namespace="com.rockcode.www.mapper.CommonMapper">
<select id="queryAllChannels" resultType="com.rockcode.www.po.ChannelManageDto">
select * from t_distributor
</select>
</mapper>
好了,通过上面的文字,我们仅仅实现了 API 和 XML 方式,但是还有更简单的。那就是 Mybatis-Spring。