Mybatis notes(1)基础配置

mybatis的jar包
这里写图片描述
工程结构
这里写图片描述

1.mybatis的基本构成:
SqlSessionFactoryBuilder(构造器):根据配置信息或者代码来生成SqlSessionFactory

SqlSessionFactory(工厂接口):依靠工厂来生成SqlSession

SqlSession(会话):是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口

SQL Mapper:有一个Java接口和xml文件或者注解构成,需要给出对应的SQL和映射规则。负责发送sql去执行,并返回结果

注意:使用xml配置文件是为了避免硬编码(hard code)

xml配置文件读取后的信息主要是保存在Configuration(org.apache.ibatis.session.Configuration)该对象中

注意:mybatis提供了两个SqlSessionFactory的实现类:DefaultSQLSessionFactory(主要是使用这个)和SqlSessionManager
这里写图片描述

2.xml配置
DataSource(获取数据库连接实例的数据源)
TransactionManager(决定事务范围和控制方式的事务管理器)
SQL Mapper(映射器)

<?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><!-- 设置pojo对象的别名 -->
        <typeAlias alias="Emp" type="com.unicorn.mybatishw.pojo.Emp"/>
    </typeAliases>
     <!--定义数据库的信息,默认使用development数据库构建环境-->
    <environments default="development">
        <!-- 采用JDBC事务管理 -->
        <environment id="development">
        <transactionManager type="JDBC"/>
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8"/>
            <property name="username" value="Ben"/>
            <property name="password" value="220401"/>
            </dataSource>
        </environment>
    </environments>2
    <!-- 定义映射器 -->
    <mappers>
        <mapper resource="com/unicorn/mybatishw/dao/EmpDaoMapper.xml"/>
    </mappers>
</configuration>


MybatisUtils

package com.unicorn.mybatishw.utils;
​
import java.io.Reader;
​
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 MyBatisUtil {

    private MyBatisUtil(){

    }

    private static final String RESOURCE = "mybatis-config.xml";
    private static SqlSessionFactory sqlSessionFactory = null;
    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();

    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(RESOURCE);
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            sqlSessionFactory = builder.build(reader);
        } catch (Exception e1) {
            throw new ExceptionInInitializerError("初始化MyBatis错误,请检查配置文件或数据库");
        }
    }

    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }

    public static SqlSession getSession(){
        //sessionTL的get()方法根据当前线程返回其对应的线程内部变量,
        //也就是我们需要的Session,多线程情况下共享数据库链接是不安全的。
        //ThreadLocal保证了每个线程都有自己的Session。
        SqlSession session = threadLocal.get();
        // 如果session为null,则打开一个新的session
        if (session == null){
            session = (sqlSessionFactory !=null) ?sqlSessionFactory.openSession():null;
            threadLocal.set(session); // 5
        }
        return session;
    }
    public static void closeSession(){
        SqlSession session = (SqlSession) threadLocal.get(); // 2
        threadLocal.set(null);
        if (session !=null){
            session.close();
        }
    }
}


读取xml配置文件,生成SqlSessionFactory

String resource = "mybatis-config.xml";
InputStream is = Resource.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = null;
SqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

流程:
①输入流(InputStream)读取配置文件(Resource.getResourceAsStream(“”))->
②SqlSessionFactoryBuilder通过InputStream创建SqlSessionFactory->
③SqlSessionFactory

其次还能通过Java代码实现配置

//创建数据库连接池
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/数据库名称?characterEncoding=utf8");
dataSource.setUsername("数据库管理员名称");
dataSource.setPassword("xxxx");
//构建数据库事务方式
TransactionFactory transctionFactory = new JdbcTransctionFactory();
//创建数据库的运行环境
Environment environment = newEnvironment("development", transctionFactory, dataSource);
//构建Configuration对象
Configuration configuration = new Configuration(environment);
//注册别名alias
configuration.getTypeAlisRegistry().registerAlias("Emp", Emp.class);
//加入映射器
configuration.addMapper(EmpMapper.class);
//使用SqlSessionFactoryBulider构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

SqlSession属于数据库资源,在一次使用完之后应该及时关闭(即在finally中关闭),避免占用数据库资源
伪代码

SqlSession sqlSession = null;
try{
    sqlSession = sqlSessionFactory.openSession();//getCurrentSession?
    //some code ...
    sqlSession.commit();//提交事务
} catch(Exception ex){
    System.err.println("");
    sqlsession.rollback();//事务回滚
} finally {
    if(null != sqlSession)
        sqlSession.close();
}

3.实体对象的映射配置
Emp.class

package com.unicorn.mybatishw.pojo;
​
import java.io.Serializable;
import java.sql.Date;
​
public class Emp implements Serializable {/**
     * 实现序列化接口
     */
    private static final long serialVersionUID = 1L;
​
    /**
     * 雇员的数据成员
     */
//  雇员的工号
    private Integer empno;
//  雇员姓名
    private String empName;
//  雇员的工作类型
    private String job;
//  雇员的薪水
    private Double salary;
//  雇员的奖金
    private Double comm;
//  雇员的入职事件
    private Date hireDate;
//  雇员的经理的工号
    private Integer mgr;
//  雇员的部门
    private String deptno;

    public Emp() {
        // TODO Auto-generated constructor stub
    }
​
//  settrt and getter
    public Integer getEmpno() {
        return empno;
    }
​
    public void setEmpno(Integer empno) {
        this.empno = empno;
    }
​
    public String getEmpName() {
        return empName;
    }
​
    public void setEmpName(String empName) {
        this.empName = empName;
    }
​
    public String getJob() {
        return job;
    }
​
    public void setJob(String job) {
        this.job = job;
    }
​
    public Double getSalary() {
        return salary;
    }
​
    public void setSalary(Double salary) {
        this.salary = salary;
    }
​
    public Double getComm() {
        return comm;
    }
​
    public void setComm(Double comm) {
        this.comm = comm;
    }
​
    public Date getHireDate() {
        return hireDate;
    }
​
    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }
​
    public Integer getMgr() {
        return mgr;
    }
​
    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }
​
    public String getDeptno() {
        return deptno;
    }
​
    public void setDeptno(String deptno) {
        this.deptno = deptno;
    }
​
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
​
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.getEmpName()+":"+this.getJob()+"<--> salary:"+this.getSalary()+
                " comm:"+ this.getComm();
    }
}


IEmpDao.interface

package com.unicorn.mybatishw.dao;
​
import java.util.List;
​
import com.unicorn.mybatishw.pojo.Emp;
​
public interface IEmpDao {

//  添加新的雇员
    int addNewEmp(Emp newEmp);

//  删除一个雇员
    boolean deleteEmp(Emp emp);

//  修改雇员信息
    boolean updateEmpByEmpno(Emp emp);

//  多条件合并查找雇员
    List<Emp> queryEmpBySomeCondition(Emp emp);

//  查询所有雇员
    List<Emp> queryEmps();

}


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.unicorn.mybatishw.dao.IEmpDao">
    <!-- 利用别名代替 -->
    <resultMap type="Emp" id="empResultMap">
        <id property="empno" column="empno" /><!-- id绑定主键 -->
        <result property="empName" column="ename" />
        <result property="hireDate" column="hiredate" />
        <result property="job" column="job" />
        <result property="comm" column="comm" />
        <result property="salary" column="sal" />
        <result property="deptno" column="deptno" /> <!-- pojo 与数据库表column名设计一致可以不用使用resultmap -->
    </resultMap>
​
    <!-- <select resultType="int" id="countAll">
        这里的SQL结尾不能加分号,否则报"ORA-00911错误"
        SELECT count(*) FROM emp
    </select>

    <select resultType="Emp" id="selectOneEmp" resultMap="empResultMap"> 
        SELECT *
        FROM 
            emp
        WHERE
            empno=1002
    </select>

    <delete id="deleteEmpByEmpno" parameterType="int">
        DELETE FROM 
            emp
        WHERE
            empno= #{empno}
    </delete>

    <update id="updateEmpByEmpno" parameterType="Emp">
        UPDATE 
            emp e
        SET
            e.ename=#{empName}, e.job=#{job}, e.sal=#{salary}, e.comm=#{comm}
        WHERE
            e.empno=#{empno}
    </update>

    <select id="dynamicQueryEmp" parameterType="Emp" resultType="Emp" resultMap="empResultMap">
        SELECT e.* FROM
            emp e
        <where>
            <if test="mgr != null">
                and e.mgr=#{mgr}
            </if>   
            <if test="empName != null">
                and e.ename like '%${empName}%'
            </if>
        </where>
    </select>

    <select resultType="Emp" id="queryEmpByEmpNo" parameterType="int" resultMap="empResultMap"> 
        SELECT *
        FROM 
            emp
        WHERE
            empno= #{empno}
    </select>

    <select resultType="Emp" id="queryAllEmp" resultMap="empResultMap"> 
        SELECT *
        FROM 
            emp
    </select>

    <select resultType="Emp" id="queryEmpByDeptno" resultMap="empResultMap"> 
        SELECT e.*
        FROM 
            emp e
        WHERE
            e.deptno=#{deptno}
    </select>

    <select resultType="Emp" id="queryEmpByDeptnoLike" parameterType="String" resultMap="empResultMap"> 
        SELECT e.*
        FROM 
            emp e
        WHERE
            e.deptno like  concat('%', #{deptno})利用字符拼接 
    </select>

    <insert id="addNewEmp" parameterType="Emp" useGeneratedKeys="true" keyProperty="empno">useGeneratedKeys="true" keyProperty="empno"可以使对像直接获取自增的值
        INSERT INTO emp
            (empno, ename, job, sal, comm, mgr, deptno)
        VALUES
            (#{empno}, #{empName}, #{job}, #{salary}, #{comm}, #{mgr}, #{deptno})
    </insert> -->

    <insert id="addNewEmp" parameterType="Emp" useGeneratedKeys="true" keyProperty="empno">
        INSERT INTO emp
            (empno, ename, job, sal, comm, mgr, deptno, hiredate)
        VALUES
            (#{empno}, #{empName}, #{job}, #{salary}, #{comm}, #{mgr}, #{deptno}, #{hireDate})
    </insert>

    <select id="queryEmpBySomeCondition" parameterType="Emp" resultType="Emp" resultMap="empResultMap">
        SELECT e.* FROM
            emp e
        <where>
            <if test="empno != null">
                and e.empno=#{empno}
            </if>
            <if test="empName != null">
                and e.ename like '%${empName}%'
            </if>
            <if test="deptno != null">
                and e.deptno like '%${deptno}%'
            </if>
            <if test="job != null">
                and e.job like '%${job}%'
            </if>
            <if test="mgr != null">
                and e.mgr like '%${mgr}%'
            </if>
            <if test="salary != null">
                and e.sal=#{salary}
            </if>
        </where>
    </select>

    <select resultType="Emp" id="queryEmps">
        SELECT * FROM emp
    </select>
​
</mapper>

参考:注解配置

public interface EmpMapper{
    @Select(value="select id, job, salary, empName from emp where id=#{id}");//相当于<select>
                                                                             //</select>
    public Emp getEmpById(Long id);
}

最好使用类对象的mapper接口(interface)进行开发,个人的经验来看注解的方式来写mybatis的sql难以做到对数据判断,如下面这条select

 <select id="queryEmpBySomeCondition" parameterType="Emp" resultType="Emp" resultMap="empResultMap">
        SELECT e.* FROM
            emp e
        <where>
            <if test="empno != null">
                and e.empno=#{empno}
            </if>
            <if test="empName != null">
                and e.ename like '%${empName}%'
            </if>
            <if test="deptno != null">
                and e.deptno like '%${deptno}%'
            </if>
            <if test="job != null">
                and e.job like '%${job}%'
            </if>
            <if test="mgr != null">
                and e.mgr like '%${mgr}%'
            </if>
            <if test="salary != null">
                and e.sal=#{salary}
            </if>
        </where>
    </select>

使用xml的mapper是很容易做到的,而使用注解就比较麻烦

相应的project链接
环境:eclipse Java Oxygen(June 2017)
转载请注明出处,谢谢!
感谢杨开振先生所著的《深入浅出Mybatis技术原理与实战》,笔者博客的内容一部分是自己实战中的经验,另一部分是学习这本书籍内容的总结。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值