文章目录
MyBatis工具类和关联操作
MyBatis工具类
由于我们基础的Mybatis在操作数据库时,虽然不需要写Dao接口的实体类,但是仍然需要重复的操作:通过Mybatis来加载配置文件.构建SqlSession的工厂来创建SqlSession的对象.在通过SqlSession的对象来获取实体类的对象,甚至是对事务的提交,这些操作都是重复的,因此我们设计一个工具类,对Mybatis的操作进行一个封装,将必须要做的事情,将其封装到静态代码块,在类加载时进行执行,将可能会执行的操作封装为一个静态方法,在使用时进行调用就可以了.简化我们的操作,去掉了很多冗余的代码
下面给出MyBatis工具类的详细代码:
package per.util;
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;
/**
* @author 雷雨
* @date 2020/6/16 15:06
*
* mybatis工具类
* 1.加载配置
* 2.创建SqlSession工厂
* 3.创建Session
* 4.事务的管理
* 5.Mapper获取
*/
public class MybatisUtil {
//创建线程工厂
private static SqlSessionFactory sqlSessionFactory;
//创建ThreadLocal绑定当前线程中的SqlSession
private static final ThreadLocal<SqlSession> t1=new ThreadLocal<SqlSession>();
static{
//配置加载信息,构建session工厂
try {
//1.加载配置文件
InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession openSession(){
//注意这里的SqlSession和我们普通的jdbc操作中的Connection对象很相似,是线程唯一,全局不唯一的
//因此我们需要先看看在当前线程池中是否有没有释放的sqlsession对象
SqlSession sqlSession = t1.get();
if (sqlSession ==null){
sqlSession = sqlSessionFactory.openSession();
t1.set(sqlSession);
}
return sqlSession;
}
public static void commit(){
//获取了当前线程中的SqlSession对象
SqlSession sqlSession = openSession();
sqlSession.commit();
close();
}
public static void rollback(){
SqlSession sqlSession = openSession();
sqlSession.rollback();
close();
}
public static void close(){
SqlSession sqlSession = openSession();
sqlSession.close();
}
public static <T> T getMapper(Class<T> mapper){
SqlSession sqlSession = openSession();
return sqlSession.getMapper(mapper);
}
}
映射细节-resultmap使用
数据库中的列名和程序中的属性名不同时 |
---|
数据库中的列名和程序中的属性名不同时,因为MyBatis框架使用的是同名映射,所以我们之前的操作是给数据库中的列名起一个别名的方式来执行我们响应的sql语句
现在我们通过配置文件resultmap
的方式能够完成高级映射
,不仅不需要在sql语句中起别名还可以完成级联查询(多表参与的查询)
resultmap的代码实现
<mapper namespace="per.leiyu.dao.UserDao">
<resultMap id="user_resultmap" type="User">
<!-- 定义一些更加复杂的映射
主键列,用标签 id定义
其他列使用result定义
column数据库中的列名
property 在实体类中要对应的属性名
-->
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="passward" property="passward"/>
<result column="gender" property="gender"/>
<result column="regist_time" property="registTime"/>
</resultMap>
<!-- 那么对应的我们的查询也就需要做一个改动 -->
<!-- 将resultType改为了我们写好的resultMap
另外因为已经使用了resultMap,就不需要再起别名就可以直接查询 -->
<select id="queryUserByUsernameAndPassward" resultMap="user_resultmap">
select id,username,passward,gender,regist_Time
from t_user
where username=#{arg0} and passward=#{arg1}
</select>
</mapper>
其实:如果使用resultmap只是为了实现简单的关系映射,那么是费事费力的
,我们这里使用reslultmap的原因是
:提醒在遇到简单的同名映射关系没办法实现其功能时,我们就使用resultmap的关系映射
另外resultmap的关系映射在关联关系中应用非常广泛
MyBatis处理关联关系-多表连接
实体间的关系:关联关系(拥有has 属于belong)
- OneToOne:一对一(Passenger–Passport)
- OneToMany:一对多(Employee-Department)
- ManyToMany:多对多(Student-Subject)
Table建立外键关系 |
---|
一对一关联关系的处理案列
- 创建数据库
- 编写实体类
- 创建Dao接口,写查询的方法
- 编写关系映射文件
- 测试类
- 结果展示
创建数据库数据
CREATE TABLE t_passengers(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
sex VARCHAR(50),
birthday DATE
)DEFAULT CHARSET = utf8;
CREATE TABLE t_passports(
id INT PRIMARY KEY AUTO_INCREMENT,
nationality VARCHAR(50),
expire DATE,
passenger_id INT UNIQUE,
FOREIGN KEY (passenger_id) REFERENCES t_passengers(id)
)DEFAULT CHARSET =utf8;
INSERT INTO t_passengers VALUES(NULL,'leiyu_1','f','2019-11-11');
INSERT INTO t_passengers VALUES(NULL,'leiyu_2','m','2019-12-12');
INSERT INTO t_passports VALUES(NULL,'China','2050-11-11',1);
INSERT INTO t_passports VALUES(NULL,'America','2050-12-12',2);
数据库表建立完成 |
---|
开始编写实体类
package per.Dao;
import java.util.Date;