一、SqlSessionFactory
1、使用xml构建SqlSessionFactory
Mybatis中的xml分为两类:一类是基础配置文件,通常只有一个,主要是配置一些最基本的上下文参数以及环境;另外一列是映射文件,它可以配置映射关系,SQL,参数等信息。
下列定义了一个jdbc.properties文件,用来保存jdbc的信息:
#jdbc.properties
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=******
以下是mybatis-config.xml文件:
<?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>
<properties resource="com/learn/ssm/chapter3/pojo/jdbc.properties"/> <!--引入jdbc.properties文件-->
<typeAliases><!--别名-->
<typeAlias alias="role" type="com.learn.ssm.chapter3.pojo.Role"/>
</typeAliases>
<!--数据库环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager> <!--数据库操作包-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/> <!-- 数据库驱动 -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/learn/ssm/chapter3/mapper.RoleMapper.xml"/> <!-- 映射配置文件 -->
</mappers>
</configuration>
- 元素定义了一个别名role,这样在mybatis的上下文环境中就可以用它代替
- 元素的定义,元素是配置事物管理器,这里采用mybatis的jdbc的管理方式,然后采用了配置数据库,其中属性type=“POOLED” 代表采用了Mybatis内部提供的连接池,最后定义了JDBC的属性
- 映射器配置文件
然后根据xml文件构建SqlSessionFactory,流程如下
实现代码如下:
public class Main {
public static void main(String[] args){
SqlSessionFactory sqlSessionFactory = null;
String resource = "mybatis-config.xml"; //mybatis配置文件
InputStream inputStream;
try{
inputStream = Resources.getResourceAsStream(resource); //用流读取配置文件
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //根据配置文件生成sqlSessionFactory
}catch (IOException e){
e.printStackTrace();
}
}
}
2、使用代码构建SqlSessionFactory
不推荐这种方式
//数据库连接池信息
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/ssm");
dataSource.setUsername("root");
dataSource.setPassword("*****");
dataSource.setDefaultAutoCommit(false);
//采用Mybatis的JDBC方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development",transactionFactory,dataSource);
//创建Configuration对象
Configuration configuration = new Configuration(environment);
configuration.getTypeAliasRegistry().registerAlias("role",Role.class);
//加入一个映射器
configuration.addMapper(RolerMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
二、SqlSession
SqlSession的作用类似于JDBC中的一个Connection对象,代表着一个资源的启用,它的作用如下:
- 获取Mapper接口
- 发送Sql给数据库
- 控制数据库事务
创建SqlSession方法,用SqlSessionFactory创建,如下:
SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession只是一个门面接口,有很多方法,可以直接发送sql,在Mybatis中,真正干活的是Executor。
SqlSession控制数据库事务的方法,如下:
try{
sqlSession = sqlSessionFactory.openSession();
//some code
sqlSession.commit();
}catch (Exception e){
sqlSession.rollback();
}finally {
//在finally语句中确保资源被顺利关闭
if(sqlSession != null){
sqlSession.close();
}
}
三、映射器
映射器是由一个接口和一个xml文件组成,它可以配置以下内容:
-
描述映射规则
-
提供Sql语句,并可以配置SQL参数类型,返回类型,缓存刷新的信息
-
配置缓存
-
提供动态sql
有两种实现映射器的方式,xml文件形式和注解形式,这是一个POJO文件:
package com.learn.ssm.chapter3.pojo;
public class Role {
private Long id;
private String roleName;
private String note;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
映射器主要作用是将Sql查询到的结果映射成为一个POJO,或者将POJO的数据插入数据库中,并定义一个关于缓存的内容。
注意,开发只是一个接口,而不是一个实现类,Mybatis运用动态代理使接口能够运行。
1、用xml实现映射器
用xml实现映射器分为两个部分,接口和mapper,先定义一个映射器接口,如下:
package com.learn.ssm.chapter3.mapper;
import com.learn.ssm.chapter3.pojo.Role;
public interface RoleMapper {
public Role getRole(Long id);
}
<!-- RoleMapper.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="com.learn.ssm.chapter3.mapper.RoleMapper"> <!-- 接口 -->
<select id="getRole" parameterType="long" resultType="role"><!-- role 在先前已经用typeAliaes重定义 -->
SELECT id,role_name as roleName,note
FROM t_role where id=#{id}
</select>
</mapper>
这样就完成了一个映射器的定义
- 元素中的namespace代表着接口的名字,mybatis通过上下文找到接口
- 元素表明这是一条查询语句,属性id标识这个SQL,跟RoleMapper接口的getRole对应,parameterType说明了传递的参数,resultType说明了返回值的类型。
- #{id}代表着穿进去的参数
这里没有配置SQL执行后和role对应关系,这里采用了自动映射关系,只要返回的列名跟Role属性名相等就可以了,这样可以添加对应关系:
<resultMap id="studentMapper" type="entity.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
</resultMap>
2、通过注解实现映射器
public interface RoleMapper2{
@Select("select id,role_name as roleName,note from t_role where id=#{id}")
public Role getRole(int id);
}
这完全等同于xml创建方式,但是xml方式和注解同时使用,xml会覆盖掉这个。
如果要实现下面这条sql:
select * from t_user u
left join t_user_role ur on u.id = ur.user_id
left join t_role r on ur.role_id = r.id
left join t_user_info ui on u.id = ui.user_id
where u.user_name like concat('%',${user_name},'%')
and u.sex = 1
如果使用注解就很复杂,xml可以相互引入,但是注解是不可以的。
3、用mapper接口发送sql
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1);
三、实例
| 文件 | 作用 |
|---|---|
| Chapter3Main.java | 程序入口,拥有main方法 |
| RoleMapper.java | 映射器接口 |
| RoleMapper.xml | 映射器xml文件,描述映射关系,SQL内容 |
| Role.java | POJO对象 |
| SqlSessionFactoryUtil.java | 一个工具类,用于创建SqlSessionFactory或获取SqlSession对象 |
| log4j.properties | 日志配置文件,让后台日志数据Mybatis运行的过程日志 |
| mybatis-config.xml | Mybatis的配置文件 |
log4j.properties
log4j.rootLogger=DEBUG,stdout
log4j.logger.org.mybatis=DEBUG
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
定义一个xml文件和mapper接口:
RoleMapper.java
package com.learn.ssm.chapter3.instance.mapper;
import com.learn.ssm.chapter3.instance.pojo.Role;
import java.util.List;
public interface RoleMapper {
public int insertRole(Role role);
public int deleteRole(int id);
public int updateRole(Role role);
public Role getRole(int id);
public List<Role> findRoles(String roleName);
}
RoleMapper.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="com.learn.ssm.chapter3.instance.mapper.RoleMapper">
<select id="getRole" parameterType="int" resultType="role">
select id,role_name as roleName,note
from t_role
where id=#{id}
</select>
<select id="findRoles" parameterType="string" resultType="role">
select id,role_name as roleName,note
from t_role
where roleName like concat('%',#{roleName},'%')
</select>
<insert id="insertRole" parameterType="role">
insert into t_role(role_name,note)
values (#{roleName},#{note})
</insert>
<delete id="deleteRole" parameterType="int">
delete
from t_role
where id=#{id}
</delete>
<update id="updateRole" parameterType="role">
update t_role
set role_name=#{roleName},note=#{note}
where id=#{id}
</update>
</mapper>
mybatis配置文件: mybatis-config.xml
<?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>
<properties resource="com/learn/ssm/chapter3/instance/resource/jdbc.properties"/>
<typeAliases>
<typeAlias type="com.learn.ssm.chapter3.instance.pojo.Role" alias="role"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/learn/ssm/chapter3/instance/mapper/RoleMapper.xml"/>
</mappers>
</configuration>
SqlSessionFactoryUtil.java
package com.learn.ssm.chapter3.instance.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtils {
private final static Class<SqlSessionFactoryUtils> LOCK = SqlSessionFactoryUtils.class;
private static SqlSessionFactory sqlSessionFactory = null;
private SqlSessionFactoryUtils(){}
public static SqlSessionFactory getSqlSessionFactory(){
synchronized (LOCK){
if (sqlSessionFactory != null){
return sqlSessionFactory;
}
String resource = "com/learn/ssm/chapter3/instance/resource/mybatis-config.xml";
InputStream inputStream;
try{
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}catch (IOException e){
e.printStackTrace();
return null;
}
return sqlSessionFactory;
}
}
public static SqlSession openSqlSession(){
if(sqlSessionFactory == null){
getSqlSessionFactory();
}
return sqlSessionFactory.openSession();
}
}
Chapter3Main.java
package com.learn.ssm.chapter3.instance;
import com.learn.ssm.chapter3.instance.mapper.RoleMapper;
import com.learn.ssm.chapter3.instance.pojo.Role;
import com.learn.ssm.chapter3.instance.utils.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
public class Chapter3Main {
public static void main(String[] args){
Logger logger = Logger.getLogger(Chapter3Main.class);
SqlSession sqlSession = null;
try{
sqlSession = SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1);
roleMapper.deleteRole(3);
sqlSession.commit();
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally{
if(sqlSession != null){
sqlSession.close();
}
}
}
}