MyBetis框架

 

1.MyBetis环境搭建

1.1新建项目

java项目web 项目。

1.2 导入JAR

mybatis和数据库驱动包日志包(配置日志配置文件)。

1.3创建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>

<!--可设置多个运行环境,满足不同需要,例如 测试、生产环境上不同一配置 -->

<environments default="development">

<environment id="development">

<!--事务管理类型主要有jdbcmanaged,者依赖于数据源获得的连接,后者依赖于容器 -->

<transactionManager type="JDBC" />

<!-- type="POOLED"表示使用连接池, type="UNPOOLED"表示不使用连接池 -->

<dataSource type="POOLED">

<property name="driver" value="com.mysql.jdbc.Driver" />

<!-- 如果数据库设置为UTF-8,URL参数连接需要添加?useUnicode=true&characterEncoding=UTF-8,如下 -->

<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8" />

<property name="username" value="root" />

<property name="password" value="root" />

</dataSource>

</environment>

</environments>

</configuration>

1.4创建数据库及表

drop database if exists mybatis;

create database mybatis CHARACTER SET UTF8;

use mybatis;

 

create table dept(

    dept_id int primary key auto_increment,

    dept_name varchar(50),

    dept_address varchar(50)

);

insert into dept(dept_name,dept_address) values('研发部一部','广州');

insert into dept(dept_name,dept_address) values('研发部二部','广州');

insert into dept(dept_name,dept_address) values('研发部三部','深圳');

select * from dept;

1.5创建实体类:Dept.java

public class Dept implements Serializable {

private Integer deptId; //部门编号

private String deptName;//部门名称

private String deptAddress;//部门地址

1.6创建SQL映射文件及修改主配置文件

SQL映射文件DeptMapper.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="cn.itcast.entity.DeptMapper">

<!--  一般在查询使用--><!-- type指定的是对应的实体类 -->

<resultMap type="cn.itcast.entity.Dept" id="deptResultMap">

<!-- id用来配置表的主键与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->

<id property="deptId" column="dept_id"/>

<!-- result用来配置 普通字段与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->

<result property="deptName" column="dept_name"/>

<result property="deptAddress" column="dept_address"/>

</resultMap>

<!-- 定义插入的sql语句,通过命名空间+id方式被定位 -->

<insert id="insertDept" parameterType="cn.itcast.entity.Dept">

<!-- #{} 用来获取传过来的参数 -->

insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress});

</insert>

</mapper>

 

修改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>

<environments default="development">

…………

</environments>

 

<mappers>

<mapper resource="cn/itcast/entity/DeptMapper.xml" />

</mappers>

 

</configuration>

 

1.7编写数据库操作

包括操作接口及实现,接口略,实现类为:DeptDaoImpl.java

public class DeptDaoImpl {

/**

 * 用于插入数据到dept表。

 * @param dept 部门信息

 * @return 表示受影响的行数

 */

public int insert(Dept dept){

/*

 * 1.读取配置信息

 * 2.构建session工厂

 * 3.创建session

 * 4.启动事务(可选)

 * 5.数据处理

 * 6.提交事务、回滚事务(可选)

 * 7.关闭session  

 */

int i=0;

SqlSession session=null;

String config="myBatis-config.xml";

       Reader reader = null;

try {

reader=Resources.getResourceAsReader(config);

SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);

session=sqlSessionFactory.openSession();

//事务默认自动启动

//(SQL映射文件定义的命名空间.SQL语句的ID)定位SQL语句,例如下的:cn.itcast.entity.DeptMapper.insertDept

i=session.insert("cn.itcast.entity.DeptMapper.insertDept",dept);

session.commit();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

session.rollback();

}finally{

//关闭reader对象,这里略

session.close();

}

return i;

}

}

1.8编写测试类

需要导入junit

public class DeptTest {

private static DeptDaoImpl deptDaoImpl;

@BeforeClass

public static void setUpBeforeClass() throws Exception {

deptDaoImpl=new DeptDaoImpl();

}

@AfterClass

public static void tearDownAfterClass() throws Exception {

deptDaoImpl=null;

}

@Test

public void testInsert() {

Dept dept=new Dept();

dept.setDeptName("市场部");

dept.setDeptAddress("深圳");

int i=deptDaoImpl.insert(dept);

System.out.println("受影响行数:"+i);

}

}

2.基本CRUD操作

2.1自定义别名

2.1.1 内置别名

对常用的 java 类型,已经内置了一些别名支持。这些别名都是不区分大小写的。(详细参看用户手册

2.1.2 自定义别名

myBatis主配置文件给cn.itcast.entity.Dept类创建别名Dept,继的DeptMapper.xml配置文件中可以使用别名

<!-- 通过别名简化对类的使用 -->

<typeAliases>

<typeAlias type="cn.itcast.entity.Dept" alias="Dept" />

</typeAliases>

2.2  MyBatisUtil工具类

public class MyBatisUtil {

private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();

    private static SqlSessionFactory sessionFactory;

    private static String CONFIG_FILE_LOCATION = "myBatis-config.xml";

static {

     try {

     buildSessionFactory();

} catch (Exception e) {

System.err.println("%%%% Error Creating SessionFactory %%%%");

e.printStackTrace();

}

    }

/**

     * Returns the ThreadLocal Session instance.  Lazy initialize

     * the <code>SessionFactory</code> if needed.

     *  @return Session

     *  @throws Exception

     */

    public static SqlSession getSession() throws Exception {

        SqlSession session = (SqlSession) threadLocal.get();

if (session == null) {

if (sessionFactory == null) {

buildSessionFactory();

}

session = (sessionFactory != null)?sessionFactory.openSession():null;

threadLocal.set(session);

}

        return session;

    }

// build  session factory

public static void buildSessionFactory() {

Reader reader=null;

try {

reader=Resources.getResourceAsReader(CONFIG_FILE_LOCATION);

sessionFactory = new SqlSessionFactoryBuilder().build(reader);

} catch (Exception e) {

System.err.println("%%%% Error Creating SessionFactory %%%%");

e.printStackTrace();

}finally{

try {

reader.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

// Close the single  session instance.

    public static void closeSession(){

        SqlSession session = (SqlSession) threadLocal.get();

        threadLocal.set(null);

        if (session != null) {

            session.close();

        }

    }

// return session factory

public static SqlSessionFactory getSessionFactory() {

return sessionFactory;

}

}

2.3 CRUD操作

1)新增操作

配置文件DeptMapper.xml使用别名, DeptDaoImpl.java新增方法使用工具类

修改配置文件DeptMapper.xml(使用别名):

<!--parameterType="Dept"不写时,也能自动根据代码传递的参数自动匹配-->

<insert id="insert" parameterType="Dept">

insert into dept(dept_name) values(#{deptName});

</insert>

2)修改操作

修改配置文件deptMapper.xml,添加

<update id="update" parameterType="Dept">

update dept set dept_name=#{deptName} ,dept_address=#{deptAddress} where dept_id=#{deptId} 

</update>

3)删除操作

修改配置文件deptMapper.xml,添加

<delete id="delete" parameterType="Dept">

delete from dept  where dept_id=#{deptId}

</delete>

4)查询操作返回单条记录

配置deptMapper.xml文件resultMap元素及SQL查询语句

<!—返回单条记录,表字段和对应实体属性命名一致时可以不使用resultMap属性配置,直接使用resultType="返回的全类名或别名",建议使用前者;查询结果为所有字段时,也可以用*表示  -->

<select id="selectOne" parameterType="int" resultMap="deptResultMap"  >

select dept_id, dept_name from dept where dept_id=#{deptId}

</select>

5)查询操作返回多条记录

修改配置文件deptMapper.xml,添加

<!-- 返回多条记录,返回结果配置的不是集合类型,而是集合元素的类型参数也可通过Map等方式封装  -->

<select id="selectList" parameterType="Map"  resultMap="deptResultMap">

select * from dept where dept_name like #{deptName}

</select>

 

3.动态SQL操作

3.1准备工作

创建表及库实体类,配置文件(参考上章节内容),以下为建表和库的SQL

3.2  IF语句

修改配置文件deptMapper.xml,添加

<!-- 动态IF条件 -->

<select id="selectListUseIf" parameterType="Dept"  resultMap="deptResultMap">

select * from dept where 1=1

<if test="deptId!=null">

and dept_id=#{deptId}

</if>

<if test="deptName!=null">

and dept_name=#{deptName}

</if>

<if test="deptAddress!=null">

and dept_address=#{deptAddress}

</if>

</select>

3.3  WHERE语句

修改配置文件deptMapper.xml,添加

<!-- 动态Where条件 ,一般也需要与if结合使用,与纯if比较,省略了where 1=1-->

<select id="selectListUseWhere" parameterType="Dept"  resultMap="deptResultMap">

select * from dept

<where>

<if test="deptId!=null">

and dept_id=#{deptId}

</if>

<if test="deptName!=null">

and dept_name=#{deptName}

</if>

<if test="deptAddress!=null">

and dept_address=#{deptAddress}

</if>

</where>

</select>

3.4  choose(when,otherwise)语句

修改配置文件deptMapper.xml,添加

<select id="selectListUseChoose" parameterType="Dept" resultMap="deptResultMap">

select * from dept where 1=1

<choose>

<when test="deptId!=null">and dept_id=#{deptId}</when>

<when test="deptName!=null">and dept_name=#{deptName}</when>

<when test="deptAddress!=null">and dept_address=#{deptAddress}</when>

<otherwise>and !1 = 1</otherwise>

</choose>

</select>

3.5  SET语句

修改配置文件deptMapper.xml,添加

<!--动态set语句可以用来更新数据 -->

<update id="updateUseSet" parameterType="Dept">

update dept

<set>

<if test="deptName!=null">dept_name=#{deptName},</if>

<if test="deptAddress!=null">dept_address=#{deptAddress},</if>

</set>

where dept_id=#{deptId}

</update>

3.6  ForEach语句

批量更新:需要修改mybatis-config.xml文件相关数据库连接的信息(主要红色部分)

<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true" />

 

< <!-- 定义根据个部门ID查询部门相关部门信息的SQL语句 ,resultMap的值是指集合里元素的类型,parameterType不用指定 -->

<select id="selectListUseForeach" parameterType="Integer[]" resultMap="deptResultMap">

select * from dept where dept_id in

<!-- collection"arraylist",array用来对应参数为数组,list对应参数为 集合 -->

<foreach collection="array" item="deptId" open="(" separator="," close=")">

#{deptId}

</foreach>

</select>

3.7  include语句

修改配置文件deptMapper.xml,添加

<!-- 使用include语句动态插入表的字段及对应的值 -->

<sql id="key">

<!--suffixOverrides="," 可以忽略最后-->

<trim suffixOverrides=",">

<if test="deptName!=null">

dept_name,

</if>

<if test="deptAddress!=null">

dept_address,

</if>

</trim>

</sql>

<sql id="value">

<trim suffixOverrides="," >

<if test="deptName!=null">

#{deptName},

</if>

<if test="deptAddress!=null">

#{deptAddress},

</if>

</trim>

</sql>

使用include语句

<insert id="insertUseInclude" parameterType="Dept">

insert into dept(<include refid="key" />) values(<include refid="value"/>)

</insert>

4关联查询

4.1准备工

1创建项目并导入

2配置myBatis-config.xml

3创建数据及表

drop database if exists mybatis;

create database mybatis CHARACTER SET UTF8;

use mybatis;

create table dept(

    dept_id int primary key auto_increment,

    dept_name varchar(50),

    dept_address varchar(50)

);

create table emp(

    emp_id varchar(18) primary key,

    emp_name varchar(50),

    emp_sex char(1),

    dept_id int

);

insert into dept(dept_name,dept_address) values('研发部一部','广州');

insert into dept(dept_name,dept_address) values('研发部二部','广州');

insert into dept(dept_name,dept_address) values('研发部三部','深圳');

 

insert into emp(emp_id,emp_name,emp_sex,dept_id) values('44152199507052110','张大',"","1");

insert into emp(emp_id,emp_name,emp_sex,dept_id) values('44152199507052111','张一',"","1");

insert into emp(emp_id,emp_name,emp_sex,dept_id) values('44152199507052112','张二',"","1");

select * from dept;

select * from emp;

4.2  基于association查询用于多对一一对一

4.2.1 创建实体类Dept.java/Emp.java

部门实体类:Dept.java

public class Dept implements Serializable{

private String deptAddress;

private String deptName;

private Integer deptId;

员工实体类:Emp.java

public class Emp implements Serializable{

private String empId;

private String empName;

private String empSex;

private Dept dept;

4.2.2 配置DeptMapper.xml/EmpMapper.xml

 (重点加入级联的查询语句,并映射文件信息到mybatis-config.xml中:

DeptMapper.xml

<mapper namespace="cn.itcast.entity.DeptMapper">

<!-- 表字段和对应实体属性命名一致时可以不配置 -->

<resultMap id="deptResultMap" type="Dept">

<id property="deptId" column="dept_id" />

<result property="deptName" column="dept_name" />

<result property="deptAddress" column="dept_address" />

</resultMap>

</mapper>

 

EmpMapper.xml,配置多对一的关联

<mapper namespace="cn.itcast.entity.EmpMapper">

<!-- 表字段和对应实体属性命名一致时可以不配置 -->

<resultMap id="empResultMap" type="Emp">

<id property="empId" column="emp_id" />

<result property="empName" column="emp_name" />

<result property="empSex" column="emp_sex" />

<!-- association配置对一关联 -->

<association property="dept" column="dept_id" javaType="Dept" resultMap="cn.itcast.entity.DeptMapper.deptResultMap" />

</resultMap>

 

<!--根据部门名称查询员工(包括员工所在部门)信息 -->

<select id="selectEmpDeptList" parameterType="Emp" resultMap="empResultMap">

<!-- 访问emp.dept.deptName, 前面不用写emp, 直接写 dept.deptName-->

select e.*,d.* from emp e inner join dept d on

e.dept_id=d.dept_id where d.dept_name like #{dept.deptName}

</select>

</mapper>

4.2.3 配置文件myBatis-config.xml

<!-- 通过别名简化对类的使用 -->

<typeAliases>

<typeAlias type="cn.itcast.entity.Dept" alias="Dept" />

<typeAlias type="cn.itcast.entity.Emp" alias="Emp" />

</typeAliases>

 …….

<!--导入SQL映射文件 -->

<mappers>

<mapper resource="cn/itcast/entity/DeptMapper.xml" />

<mapper resource="cn/itcast/entity/EmpMapper.xml" />

</mappers>

4.2.4 编写EmpDaoImpl.java实现查询

public class EmpDaoImpl {

SqlSession session;

public List<Emp> selectEmpDeptList(Emp emp){

List<Emp> emps=null;

try{

session=MyBatisUtil.getSession();

emps=session.selectList("cn.itcast.entity.EmpMapper.selectEmpDeptList",emp);

//session.commit();

}catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

//session.rollback();

}finally{

MyBatisUtil.closeSession();

}

return emps;

}

}

4.2.5 编写测试类

EmplTest.java

@Test

public void selectEmpDeptList() {

Emp emp=new Emp();

Dept dept=new Dept();

dept.setDeptName("%%");

emp.setDept(dept);

List<Emp> emps=empDaoImpl.selectEmpDeptList(emp);

for(Emp emp1:emps){

System.out.println("emp="+emp1);

//System.out.println("dept"+emp1.getDept());

}

}

4.3  基于collection查询对多多对多)

1编写 Dept.java/Emp.java实体

Dept.java

public class Dept implements Serializable{

private String deptAddress;

private String deptName;

private Integer deptId;

private List<Emp> emps;

//省略setget方法

Emp.java

public class Emp implements Serializable{

private String empId;

private String empName;

private String empSex;

//省略setget方法

2)配置DeptMapper.xml

DeptMapper.xml文件,配置resultMap(重是collection配置)和查询SQL语句:

<mapper namespace="cn.itcast.entity.DeptMapper">

 

<!-- 表字段和对应实体属性命名一致时可以不配置 -->

<resultMap id="deptResultMap" type="Dept">

<id property="deptId" column="dept_id" />

<result property="deptName" column="dept_name" />

<result property="deptAddress" column="dept_address" />

<!-- collection中resultMap引用的是其它文件的map 需要命名空间+id,例如cn.itcast.entity.EmpMapper.empResultMap -->

<collection property="emps"  ofType="Emp" resultMap="cn.itcast.entity.EmpMapper.empResultMap"/>

</resultMap>

 

<select id="selectDeptEmpList" parameterType="Dept" resultMap="deptResultMap">

select d.*, e.* from dept d inner join emp e on d.dept_id=e.dept_id where d.dept_name like #{deptName}

</select>

</mapper>

 

4.4  对多向关联查询示

4.4.1 编写实体类:Dept.java/Emp.java

Dept.java

public class Dept implements Serializable{

private String deptAddress;

private String deptName;

private Integer deptId;

private List<Emp> emps;

//省略setget方法

Emp.java

public class Emp implements Serializable{

private String empId;

private String empName;

private String empSex;

private Dept dept;

//省略set/get方法

 

4.4.2 编写DeptMapper.xml/EmpMapper.xml文件

DeptMapper.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="cn.itcast.entity.DeptMapper">

 

<!-- 表字段和对应实体属性命名一致时可以不配置 -->

<resultMap id="deptResultMap" type="Dept">

<id property="deptId" column="dept_id" />

<result property="deptName" column="dept_name" />

<result property="deptAddress" column="dept_address" />

</resultMap>

 

<!-- 一对多时,的关联属性可独立配置resultMap采用extends继承基本属性的resultMap -->

<resultMap id="deptExtResultMap" type="Dept" extends="deptResultMap">

<!-- collectionresultMap引用的是其它文件的map 需要命名空间+id,例如:cn.itcast.entity.EmpMapper.empResultMap -->

<collection property="emps" ofType="Emp"

resultMap="cn.itcast.entity.EmpMapper.empResultMap" />

</resultMap>

 

<!--用于部门和员工关联查询,返回部门信息(包含部门员工信息)列表采用extends继承基本属性的resultMap -->

<select id="selectDeptEmpList" parameterType="Dept" resultMap="deptExtResultMap">

select d.*, e.* from dept d inner join emp e on d.dept_id=e.dept_id

where d.dept_name like #{deptName}

</select>

 

</mapper>

 

EmpMapper.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="cn.itcast.entity.EmpMapper">

 

<!-- 表字段和对应实体属性命名一致时可以不配置 -->

<resultMap id="empResultMap" type="Emp">

<id property="empId" column="emp_id" />

<result property="empName" column="emp_name" />

<result property="empSex" column="emp_sex" />

<!--注意association元素的resultMap的值为没有配置的属性映射的deptResultMap,如下  -->

<association property="dept" column="dept_id" resultMap="cn.itcast.entity.DeptMapper.deptResultMap"/>

</resultMap>

 

<!-- 用于员工和部门关联查询,返回员工信息(包含部门信息)列表 -->

<select id="selectEmpDeptList" parameterType="Emp" resultMap="empResultMap">

select e.*,d.* from emp e inner join dept d on

e.dept_id=d.dept_id where d.dept_name like #{dept.deptName}

</select>

 

</mapper>

4.4.3 编写数据操作类:DeptDaoImpl.java/EmpDaoImpl.java

DeptDaoImpl.java,查询部门工信息,返回类型为List<Dept>,关键代码

public List<Dept> selectDeptEmpList(Dept dept){

SqlSession session=null;

List<Dept> deps=null;

try{

session=MyBatisUtil.getSession();

deps=session.selectList("cn.itcast.entity.DeptMapper.selectDeptEmpList",dept);

session.commit();

}catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

session.rollback();

}finally{

MyBatisUtil.closeSession();

}

return deps;

}

EmpDaoImpl.java

查询员其所在部门信息,返回类型为List< Emp >,关键代码

public List<Emp> selectEmpDeptList(Emp emp){

SqlSession session=null;

List<Emp> emps=null;

try{

session=MyBatisUtil.getSession();

emps=session.selectList("cn.itcast.entity.EmpMapper.selectEmpDeptList",emp);

session.commit();

}catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

session.rollback();

}finally{

MyBatisUtil.closeSession();

}

return emps;

}

 

4.4.4 编写测试类:DeptTest.java/EmpTest.java

DeptTest.java关键代码

//测试部门员工的关联查询,并遍历装载部门类型的结果集

@Test

public void selectDeptEmpList() {

Dept paramDept=new Dept();

paramDept.setDeptName("%%");

List<Dept> depts=deptDaoImpl.selectDeptEmpList(paramDept);

for(Dept dept:depts){

System.out.println("dept:"+dept);

}

}

 

EmpTest.java关键代码

//测试员工和部门的关联查询,并遍历装载员工类型的结果集

@Test

public void selectEmpDeptList() {

Emp emp=new Emp();

Dept dept=new Dept();

dept.setDeptName("%%");

emp.setDept(dept);

List<Emp> emps=empDaoImpl.selectEmpDeptList(emp);

for(Emp emp1:emps){

System.out.println("emp="+emp1);

System.out.println("dept"+emp1.getDept());

}

}

 

5. 缓存

Mybatishibernate样,也使用缓存;缓存分为一级缓存和二级缓存,一缓存指在SqlSession内;二级缓存能被所有的SqlSession共享默认开启一级缓存,不启用二级缓存。

 

配置:

使用二级缓存机制:需要开启全局缓存,文件级缓存(默认没有开启) ,语句级缓存,才能使用二级缓存。

5.1 局缓存配置

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>

<settings>

<!-- 默认有启用全局缓存的,禁用可以把value设为false,如果这里设为falseMapper.xmlSQL语句级的缓存配置不再起作用 -->

<setting name="cacheEnabled" value="true"/>

</settings>

<!—省略其它配置信息 -->

</configuration>

5.2 Mapper文件级缓存配置

<?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="cn.itcast.entity.DeptMapper">

<!--

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="false"/>

创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。可用的收回策略有以下几种, 默认的是 LRU:

eviction:缓存策略

1. LRU – 最近最少使用的:移除最长时间不被使用的对象(默认)。

2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

flushInterval:刷新间隔时间,可以被设置为任意的正整数,单位毫秒。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size:内存资源数目,可以被设置为任意正整数。默认值是1024

readOnly(只读)属性可以被设置为 true false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false

 -->

<cache eviction="FIFO" size="2" readOnly="false" />

</mapper>

5.3 SQL语句缓存配置

相关的Mapper.xml文件中配置SQL查询,关键代码如下(示例

<!--  useCache默认值为true,设为false时缓存不起作用 -->

<select id="selectOne" parameterType="int" resultMap="deptResultMap" useCache="true" >

select * from dept where dept_id=#{id}

</select>

6.XML 中的特殊字符处理

    如果 MyBatis 使用 XML 配置,那不可避免地会遇到一些对 XML 来说是特殊的字符。如小于号 “<”,因此要进行转义。主要有两个方式:

6.1 使用转义实体

下面是五个在 XML 文档中预定义好的转义实体:

<     < 小于号

>     > 大于号

&   &

'   ' 单引号

"   " 双引号

小于等于<=”,其转义为:<=

大小等于>=”,转义为:>=

6.2 使用 CDATA 部件

  CDATA 部件以"<![CDATA[" 标记开始,以"]]>"标记结束。在"<![CDATA[""]]>"之间 的特殊字符的意义都不起作用,而转变为普通字符串内容。

    MyBatis XML 映射语句配置文件中,如果 SQL 语句有特殊字符,使用CDTA 部件括起来,如:

<select id= "selectBlog_use_collection"

resultMap= "blogResult" >

<![CDATA[ SELECT id , title, author_id as authored FROM BLOG WHERE ID > 0 and ID < 10 ]]> </select>

 

7. Spring+myBatis整合

7.1 准备工作

建项目并jar

配置mybatis-config.xml

创建库及表

创建实体

编写映射文件修改mybatis-config.xml内容

进行简单测试(除了导入spring相关jar外,上内容可能直接使用上一章节内容)

7.2配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans

xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 

<!-- 配置数据源,记得去掉myBatis-config.xml的数据源相关配置 -->

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

<property name="driverClass" value="com.mysql.jdbc.Driver" />

<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8" />

<property name="user" value="root" />

<property name="password" value="root" />

</bean>

<!-- 配置session工厂 -->

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="configLocation" value="classpath:myBatis-config.xml" />

</bean>

 

<!-- 配置事务管理器,管理数据源事务处理-->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

 

<!-- 配置SessionTemplate封装了繁琐的数据操作-->

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">

<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>

</bean>

</beans>

7.3修改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>

 

<typeAliases>

<typeAlias type="cn.itcast.entity.Dept" alias="Dept" />

</typeAliases>

 

<mappers>

<mapper resource="cn/itcast/entity/DeptMapper.xml" />

</mappers>

 

</configuration>

7.4编写dao接口实现

DeptDao.java

public interface DeptDao {

//根据部门ID查询部门信息

public Dept selectOne(int deptId);

}

修改接口实现类:DeptDaoImpl.java

public class DeptDaoImpl implements DeptDao{

private SqlSessionTemplate sqlSessionTemplate;

public SqlSessionTemplate getSqlSessionTemplate() {

return sqlSessionTemplate;

}

public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {

this.sqlSessionTemplate = sqlSessionTemplate;

}

//根据部门ID查询部门信息

public Dept selectOne(int deptId){

System.out.println("dao :"+deptId);

//SqlSession session=null;

Dept dept=null;

try {

dept=sqlSessionTemplate.selectOne("cn.itcast.entity.DeptMapper.selectOne",deptId);

System.out.println("dao.dept:"+dept);

} catch (Exception e) {

e.printStackTrace();

}

return dept;

}

}

7.5编写业务层代码

业务层接口略,这里只写业务层实现类:DeptServiceImpl.java

public class DeptServiceImpl {

private DeptDao deptDao;

public Dept selectOne(int deptId){

Dept dept=deptDao.selectOne(deptId);

return dept;

}

public DeptDao getDeptDao() {

return deptDao;

}

public void setDeptDao(DeptDao deptDao) {

this.deptDao = deptDao;

}

}

 

7.6 配置bean信息到sping配置文件

<!-- DAO层部门信息表的数据操作对象 -->

<bean id="deptDao" class="cn.itcast.dao.impl.DeptDaoImpl" >

<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>

</bean>

 

<!-- 业务层部门信息业务处理对象 -->

<bean id="deptService" class="cn.itcast.service.impl.DeptServiceImpl">

<property name="deptDao" ref="deptDao"/>

</bean>

7.7编写测试

@Test

public void selectOne() {

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");

DeptServiceImpl deptService=(DeptServiceImpl)context.getBean("deptService");

Dept dept = deptService.selectOne(1);

System.out.println("dept:" + dept);

}

 

7.8简化配置

7.8.1 描式加载SQL映射文件

修改myBatis-config.xml文件,去掉<mappers>配置

<?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>

<typeAlias type="cn.itcast.entity.Dept" alias="Dept" />

</typeAliases>

    <!-- 采用扫描式加载映射文件,以下将不用配置,可以减少映射文件过多时维护的麻烦 -->

<!-- <mappers>

<mapper resource="cn/itcast/entity/DeptMapper.xml" />

</mappers>

    -->

</configuration>

 

修改applicationContext.xml,SqlSessionFactoryBean设置mapperLocations属性

 

<!-- 配置session工厂 -->

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="configLocation" value="classpath:myBatis-config.xml" />

<!-- 配置扫描式加载SQL映射文件 -->

<property name="mapperLocations" value="classpath:cn/itcast/entity/*.xml"/>

</bean>

7.8.2 MapperScannerConfigurer简化配置

1spring配置文件中添加MapperScannerConfigurer 配置并去掉所有的Dao接口实现类配置

<!-- 配置 转换器,对于在basePackage设置的包(包括子包)下的接口类的全类名和在Mapper.xml文件中定义过的命名空间一致,

spring将会生成对应的代理对象(在调用 的地方通过@Autowired方式将可以注入接口实例)-->

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<property name="sqlSessionFactory" ref="sqlSessionFactory"/>

<property name="basePackage" value="cn.itcast.dao"/>

</bean>

<!-- DAO层部门信息表的数据操作对象,上面如果配置MapperScannerConfigurer转换器,DAO接口将不再使用实现类 -->

<!--

 <bean id="deptDao" class="cn.itcast.dao.impl.DeptDaoImpl" >

<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>

</bean>

 -->

<!-- 业务层部门信息业务处理对象 -->

<bean id="deptService" class="cn.itcast.service.impl.DeptServiceImpl">

<!-- 上面如果配置MapperScannerConfigurer转换器,DAO接口将不再使用实现类注入 -->

<!-- <property name="deptDao" ref="deptDao"/>  -->

</bean>

 

 

2 检查或修改DeptMapper.xml文件

注意:命名空间+id和接+方法

<?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">

<!-- 这时的命名空间就需要和dao接口类全类名一致了 -->

<mapper namespace="cn.itcast.dao.DeptDao">

<!-- 表字段和对应实体属性命名一致时可以不配置 -->

<resultMap id="deptResultMap" type="Dept">

<id property="deptId" column="dept_id" />

<result property="deptName" column="dept_name" />

<result property="deptAddress" column="dept_address" />

</resultMap>

<!-- 这时的id就需要和dao接口的方法一致了 -->

<select id="selectOne" parameterType="int" resultMap="deptResultMap">

select * from dept where dept_id=#{id}

</select>

</mapper>

 

3)业务类中,使用@AutowiredDAO注入对象

public class DeptServiceImpl {

@Autowired

private DeptDao deptDao;

//省略其它代码

 

4删除Dao实现(存在也没有意义

 

posted @ 2018-05-13 23:58  风拂生  阅读(307)  评论(0编辑  收藏  举报