Mybatis初步

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

1.准备开发环境

1、创建测试项目,普通java项目或者是JavaWeb项目均可,如下图所示:
这里写图片描述
添加相应的jar包:
mybatis-3.4.4.jar
mysql-connector-java-5.1.30-bin.jar
jsbc.prop[mysql数据库信息配置文件]:

#dbConfig
#Mon Jul 31 07:54:49 CST 2017
url=jdbc:mysql://localhost:3306/t_market
password=root
driver=com.mysql.jdbc.Driver
username=root

mybatis-config.xml[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>

  <!-- properties属性,properties和java的.properties的配置文件有关;
  配置properties的resource指定.properties的路径;
  然后再在properties标签下配置property的name和value,
  则可以替换.properties文件中相应属性值。 -->
  <properties resource="jsbc.prop" />

  <!--typeAliases 必须在properties之后声明 -->
  <!-- typeAliases类型别名,类型别名是Java 类型的简称;它仅仅只是关联到XML 配置,简写冗长的JAVA 类名; -->
  <typeAliases>
    <!-- 定义别名User为javaBean类com.my.market.model.User -->
    <typeAlias alias="User" type="com.my.market.model.User"/>
  </typeAliases>

<!-- environments环境,MyBatis 可以配置多个环境。这可以帮助你SQL 映射对应多种数据库等; -->
  <environments default="development">
    <!-- 默认开发环境 -->
    <environment id="development">
      <!-- 事务管理器 -->
      <transactionManager type="JDBC"/>
      <!-- 数据源 -->
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>

  <!-- 将model中类对应的mapper文件加入配置中-->
  <!-- mappers映射器,这里是告诉MyBatis 去哪寻找映射SQL 的语句;可以使用类路径中的资源引用,或者使用字符,输入确切的URL引用; -->
  <mappers>
    <mapper resource="com/my/market/model/User.xml"/>
  </mappers>

</configuration>  

2.定义表所对应的实体类,如下图所示:

这里写图片描述
User.java[实体类User]:

package com.my.market.model;

public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;
    private int type;
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public int getId() {
        return id;
    }
    public String getUsername() {
        return username;
    }
    public User(int id, String username, String password, String nickname, int type) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
        this.type = type;
    }
    public User() {
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
                + ", type=" + type + "]";
    }
}

User.xml[User类对应的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">

<!-- com.my.market.model.User实体类对应的mapper文件,namespace限定名字空间避免重复 -->
<mapper namespace="com.my.market.model.User">
    <!-- 通过[namespace.id 即 com.my.market.model.User.add]进行add的插入方法的调用 -->
    <insert id="add" parameterType="User">
        insert into t_user(username, password, nickname, type) 
        values(#{username},#{password},#{nickname},#{type})
    </insert>
    <update id="update" parameterType="User">
        update t_user set password=#{password},nickname=#{nickname},type=#{type} where id=#{id}
    </update>
    <delete id="delete" parameterType="int">
        delete from t_user where id=#{id}
    </delete>
    <select id="select" parameterType="int" resultType="User">
        select * from t_user where id=#{id}
    </select>
    <!-- 使用User别名 -->
    <select id="list" resultType="User">
        select * from t_user
    </select>
</mapper>

3.Junit测试类

MyBatisUtil.java[Mybatis工具类用来获取session]:

package com.my.market.util;

import java.io.Closeable;
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 class MyBatisUtil {
    private static final String RESOURCE = "mybatis-config.xml";
    private static SqlSessionFactory factory;
    static {
        try {
            //1.创建配置文件(mybatis-config.xml)的输入流
            InputStream iStream=Resources.getResourceAsStream(RESOURCE);
            //2.创建SqlSessionFactory
            factory=new SqlSessionFactoryBuilder().build(iStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private MyBatisUtil() {
    }
    public static SqlSession getSession() {
        //3.创建SqlSession
        return factory.openSession();
    }
    public static void close(SqlSession session) {
        if(null!=session) {
            session.close();
        }
    }
}

TestMyBatisJunit.java[MyBatis Junit测试类]:

package com.my.market.test;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.jws.soap.SOAPBinding.Use;

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 org.junit.Test;

import com.my.market.model.User;
import com.my.market.util.MyBatisUtil;

public class TestMyBatisJunit {
    private static final String RESOURCE = "mybatis-config.xml";

    @Test
    public void testDelete() {
        InputStream is=null;
        try {
            is = Resources.getResourceAsStream(RESOURCE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
        SqlSession session=factory.openSession();
        System.out.println(User.class.getName());
        session.delete(User.class.getName()+".delete", 9);
        session.commit();
        session.close();
    }

    @Test
    public void testLoad() {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            User user=(User)session.selectOne(User.class.getName()+".select", 1);
            System.out.println(user);
        }finally {
            MyBatisUtil.close(session);
        }
    }
    @Test
    public void testAdd() {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            User user=new User(0, "tangseng1", "123", "唐僧1", 0);
            session.insert(User.class.getName()+".add", user);
            session.commit();
        }catch(Exception e) {
            session.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
    }
    @Test
    public void testList() {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            List<User> userList=session.selectList(User.class.getName()+".list");
            for(User u: userList) {
                System.out.println(u);
            }
        }finally {
            MyBatisUtil.close(session);
        }
    }
}

4.工具,基础类

1.BaseDao.java[所有dao的基本父类]:

package com.my.market.dao;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.my.market.model.Address;
import com.my.market.model.Page;
import com.my.market.model.SystemContext;
import com.my.market.model.User;
import com.my.market.util.DBUtil;
import com.my.market.util.DaoUtil;
import com.my.market.util.LogUtil;
import com.my.market.util.MyBatisUtil;

public class BaseDao<T> {
    public BaseDao() {
//      //依赖注入,对于子类需要set的对象,例如setUserDao
//      Method[] methods=this.getClass().getDeclaredMethods();
//      //error:unknow function
//      //this.setUserDao(null);
//      System.out.println(Arrays.toString(methods));
//      for(Method m: methods) {
//          String methodName =m.getName();
//          if(methodName.startsWith("set")) {
//              LogUtil.printLog(m);
//              String name=methodName.substring(3);
//              LogUtil.printLog(methodName+":  "+name);
//              Object obj=DaoUtil.createDaoFactory().getDao(name);
//              try {
//                  m.invoke(this, obj);
//              } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
//                  e.printStackTrace();
//              }
//          }
//      }
        DaoUtil.diDao(this);
    }
    public void add(T obj) {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            session.insert(obj.getClass().getName()+".add", obj);
            session.commit();
        }catch(Exception e) {
            session.rollback();
            e.printStackTrace();
        }finally {
            MyBatisUtil.close(session);
        }
    }
    public <Type> void add(String sqlId, Type obj) {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            session.insert(sqlId, obj);
            session.commit();
        }catch(Exception e) {
            session.rollback();
            e.printStackTrace();
        }finally {
            MyBatisUtil.close(session);
        }
    }
    public void update(T obj) {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            session.update(obj.getClass().getName()+".update", obj);
            session.commit();
        }catch(Exception e) {
            session.rollback();
            e.printStackTrace();
        }finally {
            MyBatisUtil.close(session);
        }
    }
    public void delete(Class<T> clz, int id) {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            session.delete(clz.getName()+".delete", id);
            session.commit();
        }catch(Exception e){
            session.rollback();
            e.printStackTrace();
        }finally {
            MyBatisUtil.close(session);
        }
    }
    public void delete(String sqlId, Map<String, Object> params) {
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            session.delete(sqlId, params);
            session.commit();
        }catch(Exception e){
            session.rollback();
            e.printStackTrace();
        }finally {
            MyBatisUtil.close(session);
        }
    }
    public T load(Class<T> clz, int id) {
        SqlSession session=null;
        T obj=null;
        try {
            session=MyBatisUtil.getSession();
            obj= session.selectOne(clz.getName()+".load", id);
        }finally {
            MyBatisUtil.close(session);
        }
        return obj;
    }
    public T loadBySqlId(String sqlId, Map<String, Object> params) {
        SqlSession session=null;
        T obj=null;
        try {
            session=MyBatisUtil.getSession();
            obj= session.selectOne(sqlId, params);
        }finally {
            MyBatisUtil.close(session);
        }
        return obj;
    }
    public T loadBySqlId(String sqlId, Object param) {
        SqlSession session=null;
        T obj=null;
        try {
            session=MyBatisUtil.getSession();
            obj= session.selectOne(sqlId, param);
        }finally {
            MyBatisUtil.close(session);
        }
        return obj;
    }
    public Page<T> find(Class<T> clz, Map<String, Object> params){
        int pageSize =SystemContext.getMaxPageItems();
        int pagerOffset=SystemContext.getPagerOffset();
        String order=SystemContext.getOrder();
        String condition=SystemContext.getCondition();
        Page<T> page = null;
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            if(null==params) {
                params=new HashMap<>();
            }
            params.put("pageSize", pageSize);
            params.put("pagerOffset", pagerOffset);
            params.put("order", order);
            params.put("condition", condition);
            List<T> objList=session.selectList(clz.getName()+".find", params);
            int totalRecord=session.selectOne(clz.getName()+".find_count", params);
            page=new Page<T>(pagerOffset/pageSize+1, totalRecord, pageSize,
                    totalRecord/pageSize+(totalRecord%pageSize==0? 0:1), objList);
        }finally {
            MyBatisUtil.close(session);
        }
        return page;
    }
    public Page<T> find(String sqlId, Map<String, Object> params){
        int pageSize =SystemContext.getMaxPageItems();
        int pagerOffset=SystemContext.getPagerOffset();
        String order=SystemContext.getOrder();
        String condition=SystemContext.getCondition();
        Page<T> page = null;
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            if(null==params) {
                params=new HashMap<>();
            }
            params.put("pageSize", pageSize);
            params.put("pagerOffset", pagerOffset);
            params.put("order", order);
            params.put("condition", condition);
            List<T> objList=session.selectList(sqlId, params);
            LogUtil.printLog(sqlId);
            LogUtil.printLog(sqlId+"_count");
            int totalRecord=session.selectOne(sqlId+"_count", params);
            page=new Page<T>(pagerOffset/pageSize+1, totalRecord, pageSize,
                    totalRecord/pageSize+(totalRecord%pageSize==0? 0:1), objList);
        }finally {
            MyBatisUtil.close(session);
        }
        return page;
    }
    public List<T> listBySqlId(String sqlId, Map<String, Object> params){
        List<T> objList= null;
        SqlSession session=null;
        try {
            session=MyBatisUtil.getSession();
            if(null==params) {
                params=new HashMap<>();
            }
            objList=session.selectList(sqlId, params);
        }finally {
            MyBatisUtil.close(session);
        }
        return objList;
    }
}

2.DaoUtil.java[工厂模式的获取,依赖注入]:

package com.my.market.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

import com.my.market.dao.IFactoryDao;
import com.my.market.model.MarketDi;

public class DaoUtil {
    public static void main(String[] args) {
        createDaoFactory();
    }
    public static IFactoryDao createDaoFactory() {
        Properties properties= PropertiesUtil.getDaoProp();
        String factoryName=properties.getProperty("factory");
        LogUtil.printLog(factoryName);
        IFactoryDao daoFactory=null;
        try {
            Class<?> clz=Class.forName(factoryName);
            String methodName="getInstance";
            Method method=clz.getMethod(methodName);
            daoFactory =(IFactoryDao)method.invoke(clz);
        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException |
                IllegalArgumentException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        LogUtil.printLog(daoFactory);
        return daoFactory;
    }

    public static void diDao(Object obj) {
        //get the class from the object which will set value into it
        Class<?> clz=obj.getClass();
        //get declared methods from the class
        Method[] methods=clz.getDeclaredMethods();
        for(Method m: methods) {
            //if the Method has 'MarketDi' annotation, it show the Method want to get a object
            if(m.isAnnotationPresent(MarketDi.class)) {
                MarketDi aDi=m.getAnnotation(MarketDi.class);
                String objName=aDi.value();
                if(null==objName || "".equals(objName)) {
                    String methodName=m.getName();
                    LogUtil.printLog(methodName+": "+objName);
                    if(methodName.startsWith("set")) {
                        LogUtil.printLog(m);
                        objName=methodName.substring(3);
                    }
                }
                //get className from properties file, invoke the Method, set the object into it
                try {
                    Properties properties=PropertiesUtil.getDaoProp();
                    String className=properties.getProperty(objName);
                    LogUtil.printLog(objName+": "+className);
                    Object object=Class.forName(className).newInstance();
                    m.invoke(obj, object);
                } catch (InstantiationException | IllegalAccessException | ClassNotFoundException |
                        IllegalArgumentException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.PropertiesUtil.java[属性读取工具]:

package com.my.market.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

import sun.security.jca.GetInstance;

public class PropertiesUtil {
    private static Properties dBProperties=null;
    private static Properties daoProperties=null;
    private static final String CONFIG_FILE="dbConfi.prop";
    private static final String DAO_FILE="dao.prop";
    private PropertiesUtil() {
    }
    public static Properties getInstance() {
        if(null==dBProperties) {
            synchronized (PropertiesUtil.class) {
                if(null==dBProperties) {
                    dBProperties=new Properties();
//                  try(
//                      FileInputStream fin=new FileInputStream("/"+CONFIG_FILE);
//                  ){
                    try{
                        File f1=new File("test.txt");
                        LogUtil.printLog(f1.getAbsolutePath());
                        LogUtil.printLog(PropertiesUtil.class.getResource(CONFIG_FILE));
                        dBProperties.load(PropertiesUtil.class.getResourceAsStream(CONFIG_FILE));
                    }catch (Exception e) {
                        e.printStackTrace();
                        System.exit(-1);
                    }
                }
            }
        }
        return dBProperties;
    }
    public static Properties getDaoProp() {
        try {
            if(null==daoProperties) {
                synchronized(PropertiesUtil.class) {
                    if(null==daoProperties) {
                        daoProperties=new Properties();
                        daoProperties.load(PropertiesUtil.class.getClassLoader().getResourceAsStream(DAO_FILE));
                    }
                }
            }
        }catch(IOException e) {
            e.printStackTrace();
        }
        return daoProperties;
    }
}

DaoFactoryByProperties.java[通过properties获取Dao工厂]:

package com.my.market.dao;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.my.market.util.LogUtil;
import com.my.market.util.PropertiesUtil;

public class DaoFactoryByProperties implements IFactoryDao {
    private static DaoFactoryByProperties factory=new DaoFactoryByProperties();
    private static Map<String, Object> daoMap=new HashMap<>();
    private DaoFactoryByProperties() {
    }
    public static IFactoryDao getInstance() {
        return factory;
    }
    @Override
    public Object getDao(String name) {
        Object object=null;
        Properties properties=PropertiesUtil.getDaoProp();
        String daoClassName=properties.getProperty(name);
        LogUtil.printLog(daoClassName);
        if(daoMap.containsKey(daoClassName)) {
            return daoMap.get(daoClassName);
        }
        try {
            object=Class.forName(daoClassName).newInstance();
            daoMap.put(daoClassName, object);
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return object;
    }

}

5.mybatis使用步骤

操作步骤
1、将jar导入到项目
2、创建Config.xml文件用来指定相应的数据库连接信息
这里写图片描述
这里写图片描述
3、创建mapp.xml文件
这里写图片描述
4、创建SqlSessionFactory
这里写图片描述
5、根据factory获取session
这里写图片描述
6、直接根据session来执行相应的操作
这里写图片描述

6.map文件中的insert,update,delete,select

insert标签表示添加相应的对象信息,paramterType表示添加的对象类型
这里写图片描述
update表示更新操作,delete表示删除操作
这里写图片描述
select表示查询操作,可以查询列表或者单个对象
这里写图片描述
相应的调用方式
这里写图片描述

7.mapp.xml中两种引用

1、#{xxx}这种方式会自动将这个值替换为PreparedStatment中?来使用,如果是字符串会自动加上引号,对于排序而言就无法操作
2、${xx}这种方式叫做完全替换,直接将字符串完整的替换到这个位置,完全替换的方式可能会出现SQL注入的安全隐患。建议在参数中不要使用这种方式。但是如果使用在排序中没有任何影响
这里写图片描述

8.动态SQL语句

在mapp.xml文件中可能会根据一些参数值的不同而动态的产生相应的SQL语句,此时就需要进行动态SQL语句的设定
这里写图片描述

9.Resultmap的使用

使用ResultMap可以完成相应的结果集自定义输出
这里写图片描述
ResultMap还可以完成一些外键对对象的映射
这里写图片描述
使用以上映射方式有一个致命的缺点:所谓的N+1问题
使用关联查询来解决N+1问题
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值