MyBatis--初级

2017.2.1-2017.2.2

MyBatis能干什么?

它是一个持久层框架(就是将数据保存到数据库中),更加便携的操作数据库,比如将数据库返回的内容进行List或实体类的封装,将执行操作的SQL语句配置到xml文件中,这样有利于代码的后期维护,使代码的分层更加明确,它还具有优化查询效率的缓存等功能。

为什么要使用MyBatis?

举个简单的例子,在使用传统的jdbc代码时,需要写上DAO层代码,在DAO层代码中将数据表中的数据封装到自定义的实体类中。这样给代码维护带来了问题。但MyBatis和hibernate解决了这样的问题,使用它们做查询时,可以自动地将数据表中的数据记录封装到实体或Map中,在将它们放入List返回

使用MyBatis Generator工具逆向

http://blog.csdn.net/zcwforali/article/details/54809088

第一个项目

  1. 前期资源准备

    • mybatis.jar
    • mysql-connector-java-5.1.12-bin.jar
  2. 新建项目

  3. 编写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>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql:///mybatis" />
                    <property name="username" value="root" />
                    <property name="password" value="951029" />
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="orm/UserinfoMapper.xml"/>
        </mappers>
    
    </configuration>
    
  4. 用mybatis 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 >
      <classPathEntry location="F:\java\mybatis\WebRoot\WEB-INF\lib\mysql-connector-java-5.1.12-bin.jar" />
      <context id="context1" >
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql:///mybatis?characterEncoding=utf-8" userId="root" password="951029" />
        <javaModelGenerator targetPackage="orm" targetProject="mybatis/src" />
        <sqlMapGenerator targetPackage="orm" targetProject="mybatis/src" />
        <javaClientGenerator targetPackage="orm" targetProject="mybatis/src/" type="XMLMAPPER" />
        <table schema="dbo" tableName="userinfo" >
            <generatedKey column="id" sqlStatement="jdbc" identity="true"/>
        </table>
      </context>
    
    </generatorConfiguration>
    

    5.写servlet代码执行数据操作

    package controller;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    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 orm.Userinfo;
    
    public class test extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            System.out.println("hello");
            try{
                Userinfo userinfo=new Userinfo();
    
                userinfo.setUsername("zcw");
                userinfo.setPassword("123");
    
                String resource="mybatis-config.xml";
                InputStream inputStream=Resources.getResourceAsStream(resource);
                SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession=sqlSessionFactory.openSession();
                sqlSession.insert("insert",userinfo);
                sqlSession.commit();
                sqlSession.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    
    }
    

    6.浏览器访问servlet

SqlSession对象获取封装类

package Common;

import java.io.IOException;
import java.io.InputStream;

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 abstract class GetSqlSession {
    public static SqlSession getSqlSession() throws IOException{
        String resource="mybatis-config.xml";
        InputStream inputStream=Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        return sqlSession;
    }
}

对MySQL进行CRUD

前面已经执行了插入操作,就不再演示了,后面的代码只更改test类的代码。

查询(R)操作

Userinfo userinfo=new Userinfo();       
String resource="mybatis-config.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
userinfo=sqlSession.selectOne("selectByPrimaryKey",1);  //获得主键为1的userinfo对象,"selectByPrimaryKey"是从UserinfoMapper.xml得知的
System.out.println(userinfo.getUsername());
sqlSession.commit();
sqlSession.close();

更新(U)操作

userinfo=sqlSession.selectOne("selectByPrimaryKey",1);  //获得要更改的数据
userinfo.setPassword("666");    //更改他的字段
sqlSession.update("updateByPrimaryKeySelective",userinfo);  //执行

删除(D)操作

sqlSession.delete("deleteByPrimaryKey",5);

MyBatis核心对象的生命周期与封装

  1. SqlSessionFactoryBuilder可以被JVM虚拟机所实例化、使用或销毁。一旦使用SqlSessionFactoryBuilder创建SQLSessionFactory后,SqlSessionFactoryBuilder类就不需要存在了。因此SqlSessionFactoryBuilder对象的最佳使用范围是在方法内。
  2. SqlSessionFactory对象由SqlSessionFactoryBuilder对象创建。一旦创建SqlSessionFactory对象,该实例应该在应用执行期间都存在。所以应用它的最佳方式是写一个单例模式,或使用Spring框架来实现单例模式。
  3. SqlSession对象由SqlSessionFactory类创建,每一个线程都应该有自己的SqlSession实例。SqlSession的实例不能共享,它也是线程不安全的,所以千万不要在Servlet中声明一个该对象的实例变量。关闭SqlSession很重要,应该确保使用finally块来关闭它。

    public class insertUserinfo extends HttpServlet{
        public void doGet(...)throws ServletException,IOException{
            SqlSession sqlSession=GetSqlSession.getSqlSession();
            try{
                //sqlSession curd code
                sqlSession.commit();
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                sqlSession.close();
            }
        }
    }
    

创建GetSqlSessionFactory.java类

package db;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/*
 * 使用单例模式来获取SqlSessionFactory对象
 */
public class GetSqlSessionFactory {

    private static SqlSessionFactory sqlSessionFactory;

    private GetSqlSessionFactory() {
    }

    synchronized public static SqlSessionFactory getSqlSessionFactory() {
        try {
            if (sqlSessionFactory == null) {
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources
                        .getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder()
                        .build(inputStream);
            } else {
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSessionFactory;

    }
}

创建GetSQLSession.java类

package db;

import org.apache.ibatis.session.SqlSession;

public class GetSqlSession {
    private static ThreadLocal<SqlSession> tl=new ThreadLocal<SqlSession>();

    public static SqlSession getSession(){
        SqlSession sqlSession=tl.get();
        if(sqlSession==null){
            sqlSession=GetSqlSessionFactory.getSqlSessionFactory().openSession();
            tl.set(sqlSession);
        }
        else{

        }
        System.out.println("获得sqlSession对象的hashCode:"+sqlSession.hashCode());
        return sqlSession;
    }

    public static  void commit(){
        if(tl.get()!=null){
            tl.get().commit();
            tl.get().close();
            tl.set(null);
            System.out.println("提交了!");
        }
    }

    public static void rollback(){
        if(tl.get()!=null){
            tl.get().rollback();
            tl.get().close();
            tl.set(null);
            System.out.println("回滚了!");
        }
    }

}

创建DBOperate.java类

package db;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class DBOperate {
    public int insert(String sql,Map valueMap){
        SqlSession sqlSession=GetSqlSession.getSession();
        return sqlSession.insert(sql,valueMap);
    }

    public int delete(String sql,Map valueMap){
        SqlSession sqlSession=GetSqlSession.getSession();
        return sqlSession.delete(sql,valueMap);
    }

    public int update(String sql,Map valueMap){
        SqlSession sqlSession=GetSqlSession.getSession();
        return sqlSession.update(sql,valueMap);
    }

    public List<Map> select(String sql,Map valueMap){
        SqlSession sqlSession=GetSqlSession.getSession();
        return sqlSession.selectList(sql,valueMap);
    }
}

MyBatis3常用技能

  • 使用Properties对象连接数据库
  • 动态SQL中要使用的标签
  • 动态SQL中对null值的处理
  • 对超大字符串及分页的处理

连接DB数据库的参数来自于Properties对象

  1. 在src目录下创建”XX.properties”文件(如db.properties),将要配置的内容以键值对的形式写入文件:

    drivername=com.mysql.jdbc.Driver
    url=jdbc:mysql:///mybatis
    username=root
    password=951029
    
  2. 修改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="db.properties"/>  <--!加上配置路径-->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">          
                    <property name="url" value="${url}" />
                    <property name="driver" value="${drivername}" />
                    <property name="username" value="${username}" />
                    <property name="password" value="${password}" />
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="orm/UserinfoMapper.xml"/>
        </mappers>
    
    </configuration>
    

<resultMap>标签

如果数据表中的字段名称和java实体类中属性名称不一致时可使用<resultMap>,我试了一下查询时好用,但插入时就出问题了
更改UserinfoMapper.xml中<result>中property和column不一样,实体类中也得相应更改

    <result column="password" property="passwordhy" jdbcType="VARCHAR" />

<sql>标签

目的:解决sql语句重复使用

<mapper namespace="orm.UserinfoMapper">
    <sql id="userinfoField">id,name,password</sql>
    <select id="getUserinfoAll" resultType="map">
        select 
        <include refid="userinfoField"/>
        form 
        userinfo
    </select>
</mapper>

将SQL语句作为字符串变量传入

在userinfoMapper.xml文件中

<select id="">
    select 
    id,username,password
    from
    userinfo where id=#{id} order 
    by  ${orderSql}
</select> 

java类

HashMap mapParam=new HashMap();
mapParam.put("id",5);
mapParam.put("orderSql","id desc");
......//创建sqlSession
List <Map>listuserInfo=sqlSession.selectList('getUserinfo",mapParam);   //传递mapParam参数
for(......) {
    //遍历操作
}

插入null值的处理办法(2种方法)

jdbcType(第1种)

在映射配置文件userinfoMapping.xml文件中

<insert ......>
    insert into userinfo(id,username,password)
    values(#{id,jdbcType=INTEGER},#{username,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR)
</insert>

这里在#{}格式中加入了数据类型声明,这样可以明确地告诉MyBatis框架如果遇到null值该如何处理。

<if>(第2种)

在映射配置文件userinfoMapping.xml文件中

<insert ......>
    <if test="password!=null">
        insert into userinfo(id,username,password)
        values(#id{id},#{username},#{password})
    </if>
    <if test="password==null">
        insert into userinfo(id,username)
        values(#{id},#{username})
</insert>

<choose>标签

<choose>标签的作用是在众多的条件中选择一个条件,类似于switch标签,在配置映射文件中使用

<select .....>
    select * from where 1=1
    <choose>
        <when test="username!=null"> and username like '%'||#{username}||'%'</when>
        <when>......</when>
        <otherwise>and password=123</otherwise>
    </choose>
</select>

<set>标签

<set>标签可以用在update语句中,用于动态指定要更新的列,在配置文件中使用

<update ......>
    update userinfo
    <set>
        <if test="username!=null">username=#{username},</if>
        <if .....>......</if>
        <if test="password!=null">password=#{password},</if>
    </set>

<foreach>标签

foreach标签有循环功能,可以用来生成有规律的SQL语句。
foreach标签主要的属性有item、index、collection、open、separator和close。
item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中的位置,open表示语句以什么开始,separator表示在每次迭代之间以什么符号作为分隔符,close表示该语句以什么结束。

<select ......>
    <foreach collection="criteria.criteria" item="criterion" open="(" close=")" separator="," > 
        #{criterion}
    </foreach>
</select>

分页

SqlSession sqlSession=GetSqlSession.getSession();
//RowBounds(a,b),a代表从第a个记录开始(0为第一个),往后移动b个位置
List<Userinfo> listMap=sqlSession.selectList("selectByExample",null,new RowBounds(2,4));
for (int i = 0; i < listMap.size(); i++) {
    Userinfo e=listMap.get(i);
    System.out.println(e.getId());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值