mybatis

1. Mybatis介绍

市场上所用的框架

Ø Hibernate

Ø jdbcTemplate

Ø ibatis

Ø mybatis

mybatis的优点

Ø jdbc做了很好的封装

Ø 容易掌握

Ø 灵活性强

Mybatis的安装包

 

lib:第三方的依赖包

mybatis-3.1.1.jar:核心包

mybatis-3.1.1.pdf:说明文档

mybatis-3.1.1-javadoc.jar:mybatisapi

mybatis-3.1.1-source.jar:源代码

2. mybatis的第一个例子

1. 第一步创建java项目

2. 导入所需要的jar

 

3. 建表

4. 建立实体类

5. 创建配置文件

sqlMapConfig.xml

 

6. 库表的mapping映射文件

PersonMapper.xml

 

7. 编写测试代码

 

public class PersonTest {

/**

 * 创建session工厂

 */

SqlSessionFactory sqlSessionFactory;

@Before

public void setUp() throws Exception {

String resource = "sqlMapConfig.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

}

 

/**

 * 根据id查询person

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void selectPersonById() {

//创建session

SqlSession session = sqlSessionFactory.openSession();

try {

//第一个参数namespace+"."+sqlid,第二个参数就是sql所需要的参数

Person person = session.selectOne(

"cn.itcast.model.Person.selectPersonById", 1);

System.out.println(person);

}finally {

//关闭连接

session.close();

}

}

 

}

3. Select 的语句的基本使用

1. List实体类的方式集合的查询

 

/**

 * 查询person的集合

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void selectPersonList(){

//创建session

SqlSession session = sqlSessionFactory.openSession();

try {

//第一个参数namespace+"."+sqlid,第二个参数就是sql所需要的参数

List<Person> personList = session.selectList(ns+"selectPersonList");

for(Person person : personList){

System.out.println(person);

}

}finally {

//关闭连接

session.close();

}

}

2. map方式返回实体

 

/**

 * 根据id查询person返回map实体

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void selectPersonByIdForMap(){

//创建session

SqlSession session = sqlSessionFactory.openSession();

try {

//第一个参数namespace+"."+sqlid,第二个参数就是sql所需要的参数

Map<String, Object> person = session.selectOne(

"cn.itcast.model.Person.selectPersonByIdForMap", 1);

System.out.println(person);

}finally {

//关闭连接

session.close();

}

}

3. 返回map的集合

 

/**

 * 返回map的集合

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void selectPersonListForMap(){

//创建session

SqlSession session = sqlSessionFactory.openSession();

try {

//第一个参数namespace+"."+sqlid,第二个参数就是sql所需要的参数

List<Map<String, Object>> personMapList = session.selectList(ns+"selectPersonListForMap");

System.out.println(personMapList);

}finally {

//关闭连接

session.close();

}

}

4. ResultMap的使用

 

 

5. resultMapresultType的区别

6. 模糊查询

4. insert的使用

1. 基本插入

 

/**

 * insert

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void insert(){

//创建session

SqlSession session = sqlSessionFactory.openSession();

Person person = new Person();

person.setPersonName("张三");

person.setPersonAge(300);

person.setPersonAddress("盘丝洞");

try {

//瞬间改了mysql的数据库的隔离级别,把它变成可提交读,需要手动的提交

session.insert(ns + "insert", person);

//手动提交

session.commit();

} catch (Exception e) {

session.rollback();

}finally{

session.close();

}

}

2. 主键的返回

 

5. update的使用

注意:某些不设置会出现值被置空的情况

 

/**

 * update

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void update(){

//创建session

SqlSession session = sqlSessionFactory.openSession();

Person person = new Person();

person.setPersonId(2);

person.setPersonName("李四");

//如果某些字段不设置会出现值被置空的情况,需要使用动态sql来解决

//person.setPersonAge(100);

//person.setPersonAddress("花果山");

try {

//瞬间改了mysql的数据库的隔离级别,把它变成可提交读,需要手动的提交

session.update(ns + "update", person);

//clazz.setclassId(person.getPersonId());

//手动提交

session.commit();

} catch (Exception e) {

e.printStackTrace();

session.rollback();

}finally{

session.close();

}

}

6.  delete使用

 

/**

 * update

 * @author:  

 * @email:renliang@itcast.com

 * @qq交流群:208879353

 * @companycn.itcast

 */

@Test

public void delete(){

//创建session

SqlSession session = sqlSessionFactory.openSession();

try {

//瞬间改了mysql的数据库的隔离级别,把它变成可提交读,需要手动的提交

session.delete(ns + "delete", 2);

//手动提交

session.commit();

} catch (Exception e) {

e.printStackTrace();

session.rollback();

}finally{

session.close();

}

}

7. 别名的定义

1. 

 

 

2. 定义一端sql

 

 

8. 动态sql

8.1 select动态组合条件查询

注意:1. <where>会给我们自动的处理第一个and

2.当实体类里面定义了基本的数据类型,where里面的判断空就不起作用了

 

8.2update动态更新

注意:1. <set>会给我们自动的处理最后一个逗号

2.当实体类里面定义了基本的数据类型,where里面的判断空就不起作用了

 

 

8.3foreach

l In查询

 

@Test

public void queryUserByForEachTest(){

//打开一个会话

SqlSession session = sqlSessionFactory.openSession();

try{

//Integer [] ids = {6, 7, 8};

//List ids = new ArrayList();

/*ids.add(6);

ids.add(7);

ids.add(8);*/

/*ids.add("6");

ids.add("7");

ids.add("8");*/

//更改当前代码下面的所有相同变量名Shift+Alt+R

Set ids = new HashSet();

ids.add(6);

ids.add(7);

ids.add(8);

Map<String, Object> map = new HashMap<String, Object>();

map.put("ids", ids);

List<User> uList = session.selectList("cn.itcast.User.queryUserByForEach", map);

for(User user : uList){

System.out.println(user);

}

}catch(Exception ex){

ex.printStackTrace();

session.rollback();

}finally{

session.close();

}

}

批量插入

<insert id="insertBatch">

<selectKey keyProperty="userId" order="AFTER" resultType="int">

select LAST_INSERT_ID()

</selectKey>

insert into USER (USER_ID, USERNAME, PASSWORD, BIRTHDAY, USER_ADDR)

values

<foreach collection="uList" item="user" separator=",">

(#{user.userId},#{user.username}, #{user.password}, #{user.birthday}, #{user.userAddr})

</foreach>

</insert>

 

l 批量删除

<delete id="delete" parameterType="map">

delete from user where user_id in

<foreach collection="ids" open="(" close=")" item="userId" separator=",">

#{userId}

</foreach>

</delete>

9. 联合查询

1. 建表

2. 创建mapping的文件

Mybatis generator使用方法

安装mybatis generator插件

Help—>install from site...

 

点击add

 

输入namelocation后点击ok

 

http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/

 

创建generator的核心文件

 

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

<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >

<generatorConfiguration>

<!-- 制定mysql的驱动包的路径 千万别放中文路径下 -->

<classPathEntry location="D:\mysql-connector-java-5.0.8-bin.jar" />

<!-- 配置数据源和生成的代码所存放的位置 -->

<context id="context1">

 

<commentGenerator>

<!-- 去除自动生成的注释 -->

<property name="suppressAllComments" value="true" />

</commentGenerator>

 

<jdbcConnection driverClass="com.mysql.jdbc.Driver"

connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis" userId="root"

password="root" />

<!-- 所生成的实体类的位置默认资源包src -->

<javaModelGenerator targetPackage="cn.itcast.model"

targetProject="mybatis-3" />

<!-- 所生成的sqlMap的影射文件的位置,默认资源包src -->

<sqlMapGenerator targetPackage="mybatis.sqlMap"

targetProject="mybatis-3" />

 

<!-- 为哪些表生成代码 tableName:表名 schema:不用填写,其余属性是禁用例子查询的生成 -->

<table schema="" tableName="person" enableCountByExample="false"

enableUpdateByExample="false" enableDeleteByExample="false"

enableSelectByExample="false" selectByExampleQueryId="false">

</table>

</context>

</generatorConfiguration>

 

 

l 处理多余的文件

l 多对一的关联查询

 

 

l 一对多的关联映射

 

 

l 多对多关联映射即使特殊的一对多

10. 延迟加载

在做联合查询是查出首层实体对象,具体实体对象内部的关联对象只有用到的时候才去查询使用。

首先在mybatis核心配置文件中配置:

lazyLoadingEnabledtrue使用延迟加载,false禁用延迟加载。默认为true

aggressiveLazyLoadingtrue启用时,当延迟加载开启时访问对象中一个懒对象属性时,将完全加载这个对象的所有懒对象属性。false,当延迟加载时,按需加载对象属性(即访问对象中一个懒对象属性,不会加载对象中其他的懒对象属性)。默认为true

 

<settings>

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

 <setting name="aggressiveLazyLoading" value="false"/>

</settings>

10.1 一对多延迟加载

需要两条sql语句配合使用

第一步配置resultMap

Collection:person内部的集合,

select:延迟加载的sql语句

column:延迟加载sql语句的查询条件的列名

<resultMap type="cn.itcast.model.Person" id="personLazyRM" extends="personRM">

<collection property="ordersList" column="person_id" select="mybatis.sqlMap.OrdersMapper.selectOrderByPersonId">

</collection>

</resultMap>

查询语句

<select id="selectForLazy" parameterType="int" resultMap="personLazyRM">

select * from person p where p.person_id = #{personId}

</select>

延迟加载的查询语句

<select id="selectOrderByPersonId" parameterType="int" resultMap="BaseResultMap">

  select * from orders o where  o.person_id = #{personId}

  </select>

10.2多对一或一对一的延迟加载

ResultMap

<resultMap type="cn.itcast.model.Orders" id="lazyRM" extends="BaseResultMap">

  <association property="person" column="order_id" select="cn.itcast.model.Person.selectPersonByOrderId">

    </association>

  </resultMap>

 

查询语句

<select id="selectByPrimaryKeyForLazy" resultMap="lazyRM" parameterType="java.lang.Integer" >

    select  * from orders where order_id = #{orderId}

  </select>

延迟加载的查询语句

<select id="selectPersonByOrderId" parameterType="int" resultMap="personRM">

select p.* from person p, orders o where p.person_id = o.person_id and o.order_id = #{orderId}

</select>

11.一级缓存

12.二级缓存

一个项目中肯定会存在很多共用的查询数据,对于这一部分的数据,没必要

每一个用户访问时都去查询数据库,因此配置二级缓存将是非常必要的。  

Mybatis的二级缓存配置相当容易,要开启二级缓存:

1. 在核心配置文件中加入<setting name="cacheEnabled" value="true"/>

2. 要在你的Mapper映射文件中添加一行:  <cache /> 

3. select语句中useCache=false可以禁用当前的语句的二级缓存,即每次查询夸session 的查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

4.l 映射文件中所有的insert、update和delete语句将刷新缓存,三个语句中有flushCache="true" 属性,默认情况下为true,即同个sessionFactory中当有sql语句更新时缓存自动被刷新以保证数据的实时性,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读, 缓存将使用LRU(Least Recently Used)最近最少使用策略算法来回

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

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

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

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

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

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

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是1024

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

13.二级缓存框架

采用mybatis的二级缓存框架

第一步:引入缓存的依赖包

 

第二步:引入缓存配置文件

ehcache.xml

defaultCache配置说明:

maxElementsInMemory 内存中最大缓存对象数.当超过最大对象数的时候,ehcache会按指定的策略去清理内存
eternal 缓存对象是否永久有效,一但设置了,timeout将不起作用.
timeToIdleSeconds 设置Element在失效前的允许闲置时间.仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大.
timeToLiveSeconds:设置Element在失效前允许存活时间.最大时间介于创建时间和失效时间之间.仅当element是永久有效时使用,默认是0.,也就是element存活时间无穷大.
overflowToDisk 配置此属性,当内存中Element数量达到maxElementsInMemory,Ehcache将会Element写到磁盘中.
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
maxElementsOnDisk 磁盘中最大缓存对象数,若是0表示无穷大.
diskPersistent 是否在重启服务的时候清楚磁盘上的缓存数据.true不清除.
diskExpiryThreadIntervalSeconds 磁盘失效线程运行时间间隔.
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存.默认策略是LRU(最近最少使用).你可以设置为FIFO(先进先出)或是LFU(较少使用).

 

第三步:修改mapper文件中缓存类型

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

 

 

14基于注解的开发

使用注解的开发需要提供一个接口,即dao的接口,不需要实现类,初始化环境时要把接口注册

@Before

public void setUp() throws Exception {

String sqlMapConfig = "sqlMapConfig.xml";

//读取mybatis的核心配置文件

InputStream in = Resources.getResourceAsStream(sqlMapConfig);

//实例化会话工厂

sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

sqlSessionFactory.getConfiguration().addMapper(PersonDao.class);

}

 

1. 查询所有员工

接口方法:

@Select("select * from person1")

//@Options(useCache =true, flushCache =false, timeout =10000)

@Results(value = {

@Result(id =true, property ="personId", column ="person_id"),

@Result(property ="personName", column ="person_name"),

@Result(property ="birthday", column ="birthday"),

@Result(property ="address", column ="address"),

@Result(property ="gender", column ="gender")

})

public List<Person> queryPersonAll();

调用方法:

@Test

public void queryPersonAllTest() {

//打开会话

SqlSession session = sqlSessionFactory.openSession();

try {

PersonDao personDao = session.getMapper(PersonDao.class);

List<Person> pList = personDao.queryPersonAll();

for(Person person : pList){

System.out.println(person);

}

} catch (Exception e) {

e.printStackTrace();

}finally{

session.close();

}

}

2. 根据id查询员工

接口方法:

@Select("select * from person1 t where t.person_id = #{personId}")

@Results(value = {

@Result(id =true, property ="personId", column ="person_id"),

@Result(property ="personName", column ="person_name"),

@Result(property ="birthday", column ="birthday"),

@Result(property ="address", column ="address"),

@Result(property ="gender", column ="gender")

})

public Person getPersonById(Integer personId);

调用方法:

@Test

public void getPersonByIdTest(){

SqlSession session = sqlSessionFactory.openSession();

try {

PersonDao personDao = session.getMapper(PersonDao.class);

Person person = personDao.getPersonById(1);

System.out.println(person);

} catch (Exception e) {

e.printStackTrace();

}finally{

session.close();

}

}

3. 根据不同条件查询

接口方法:

@Select("select * from person1 t where t.person_name like '%${personName}%' and t.gender = #{gender}")

@Results(value = {

@Result(id =true, property ="personId", column ="person_id"),

@Result(property ="personName", column ="person_name"),

@Result(property ="birthday", column ="birthday"),

@Result(property ="address", column ="address"),

@Result(property ="gender", column ="gender")})

public List<Person> getPersonByParam(Map<String, Object> map);

调用方法:

@Test

public void getPersonByParamTest(){

SqlSession session = sqlSessionFactory.openSession();

try {

PersonDao personDao = session.getMapper(PersonDao.class);

Map<String, Object> map = new HashMap<String, Object>();

map.put("personName", "赵六");

map.put("gender", "0");

List<Person> pList = personDao.getPersonByParam(map);

for(Person person : pList){

System.out.println(person);

}

} catch (Exception e) {

e.printStackTrace();

}finally{

session.close();

}

}

4. 联合查询

注意:需要结合配置文件方式的resultMap

调用方法

@Select("select * from person1 p, orders o where p.PERSON_ID = o.PERSON_ID and p.PERSON_ID = #{personId}")

@ResultMap(value="cn.itcast.model.Person.personWithOrderRM")

public Person getPersonOne2Many(Integer personId);

 

配置文件中的resultMap

<resultMap type="person" id="personWithOrderRM" extends="personRM">

<collection property="orderList" ofType="cn.itcast.model.Orders">

<id column="ORDER_ID" jdbcType="INTEGER" property="orderId" />

    <result column="PERSON_ID" jdbcType="INTEGER" property="personId" />

    <result column="ORDER_NO" jdbcType="VARCHAR" property="orderNo" />

    <result column="TOTAL_SUM" jdbcType="REAL" property="totalSum" />

    <result column="ORDER_ADDR" jdbcType="VARCHAR" property="orderAddr" />

</collection>

</resultMap>

 

调用方法:

@Test

public void getPersonOne2ManyTest(){

SqlSession session = sqlSessionFactory.openSession();

try {

PersonDao personDao = session.getMapper(PersonDao.class);

Person person = personDao.getPersonOne2Many(1);

System.out.println(person);

} catch (Exception e) {

e.printStackTrace();

}finally{

session.close();

}

}

 

5. 修改

调用方法

@Update(value="update person1 t set"

+" t.person_name = #{personName} , "

+" t.birthday = #{birthday}, "

+" t.address=#{address},"

+" t.gender = #{gender}"

+" where  t.person_id = #{personId}")

public void update(Person person);

 

调用方法:

@Test

public void updateTest() throws Exception{

//打开会话

SqlSession session = sqlSessionFactory.openSession();

try{

PersonDao personDao = session.getMapper(PersonDao.class);

Person person = new Person();

person.setPersonId(1);

person.setPersonName("李武");

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

Date date = format.parse("1992-12-10");

person.setBirthday(date);

personDao.update(person);

session.commit();

}catch(Exception ex){

session.rollback();

ex.printStackTrace();

}finally{

session.close();

}

}

 

6. 插入

接口方法:

@Insert("insert into person1 (person_id, person_name, birthday, address, gender)values(#{personId},#{personName},#{birthday},#{address},#{gender})")

@SelectKey(keyProperty="personId",  before = false, resultType = Integer.class, statement = { "select last_insert_id()" })

public void save(Person person);

 

调用方法:

@Test

public void insertTest() throws Exception{

//打开会话

SqlSession session = sqlSessionFactory.openSession();

try{

PersonDao personDao = session.getMapper(PersonDao.class);

Person person = new Person();

person.setPersonName("王五");

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

Date date = format.parse("1990-12-10");

person.setAddress("beijing");

person.setBirthday(date);

person.setGender("0");

personDao.save(person);

session.commit();

}catch(Exception ex){

session.rollback();

ex.printStackTrace();

}finally{

session.close();

}

}

7. 动态条件组合查询

接口方法:

@SelectProvider(type=SQLHelp.class,method="getSql")

public List<Person> queryPersonByCondition(Map<String, Object> map);

 

获得sql的帮助类

package cn.itcast.model;

import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN;

import static org.apache.ibatis.jdbc.SqlBuilder.FROM;

import static org.apache.ibatis.jdbc.SqlBuilder.SELECT;

import static org.apache.ibatis.jdbc.SqlBuilder.SQL;

import static org.apache.ibatis.jdbc.SqlBuilder.WHERE;

 

import java.util.Date;

import java.util.Map;

 

public class SQLHelp {

 

public String getSql(Map<String, Object> parameters) {

String personName = (String) parameters.get("personName");

Date birthday = (Date) parameters.get("birthday");

String address = (String) parameters.get("address");

String gender = (String) parameters.get("gender");

BEGIN();

SELECT("*");

FROM("person1");

if(personName != null){

WHERE("person_name = #{personName}");

}

if(birthday != null){

WHERE("birthday < #{birthday}");

}

if(address != null){

WHERE("address = #{address}");

}

if(gender != null){

WHERE("gender = #{gender}");

}

return SQL();

}

}

 

调用方法:

@Test

public void queryPersonByConditionTest() throws Exception{

//打开会话

SqlSession session = sqlSessionFactory.openSession();

try{

PersonDao personDao = session.getMapper(PersonDao.class);

Map<String, Object> map = new HashMap<String, Object>();

//map.put("personName", "");

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

Date date = format.parse("1990-04-01");

map.put("birthday", date);

//map.put("address", "beijing2");

map.put("gender", "0");

List<Person> personList = personDao.queryPersonByCondition(map);

for(Person person : personList){

System.out.println(person);

}

session.commit();

}catch(Exception ex){

session.rollback();

ex.printStackTrace();

}finally{

session.close();

}

}

 ssm整合springmvc+spring+mybatis

1. 创建一个web工程

2. 导入所依赖的jar

<filter>

        <filter-name>SpringCharacterEncodingFilter</filter-name>

        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <init-param>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>SpringCharacterEncodingFilter</filter-name>

        <url-pattern>*.do</url-pattern>

    </filter-mapping>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值