mybatis配置文件解析

mybatis配置文件解析

在这里插入图片描述

//StudentDao.java
package com.bjpowernode.Dao;

import com.bjpowernode.domain.Student;
import com.bjpowernode.vo.StudentAndClassroomVo;

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

public interface StudentDao {
    List<Student> getAll() ;

    public Student getById(String id);
    public void save(Student s);

    public Student selete1(String a0001);

    List<Student> selete2(int i);

    List<Student> selete3(String cxk, int i);

    List<Student> selete4();

    List<Student> selete5(Map<String, Object> map);

    Student selete6(String a0002);

    List<Student> selete7(String z);

    List<Student> selete8(String z);

    List<Student> selete9(String s);

    String selete10(String a0002);

    List<String> selete11();

    int selete12();

    List<Map<String, Object>> select14();

    List<Student> selete15();

    List<Student> selete16();

    List<Student> selete17();

    List<Student> selete18(String[] strArr);

    Student selete19(String a0002);

    List<Map<String, Object>> selete20();

    List<StudentAndClassroomVo> selete21();

    List<StudentAndClassroomVo> selete22(String name);
}

// studentDao.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">
<!--namespace:命名空间
               不同的mapper文件用namespace区分
               不同的mapper映射文件所适用的namespace的命名不允许出现重复
    使用命名空间.sqlId的形式来找到我们想要的执行的sql语句
    parameterType:sql语句传递的参数类型
-->
<mapper namespace="com.bjpowernode.Dao.StudentDao">
    <select id="getAll" resultType="Student">
        select * from tbl_student
    </select>
    <select id="getById" parameterType="java.lang.String" resultType="com.bjpowernode.domain.Student">
        select * from tbl_student where id=#{id}
    </select>
    <insert id="save">
        insert into tbl_student(id,name,age) values(#{id},#{name},#{age})
    </insert>
    <!--parameter:java.lang.String,String,string都可以写-->
    <select id="selete1" parameterType="String" resultType="Student">
        select * from tbl_student where id=#{id}
    </select>
    <!--使用简单类型(8大基本类型)为参数
    在#{}里的参数随意写-->
    <select id="selete2" parameterType="int" resultType="Student">
        select * from tbl_student where age=#{age123343}
    </select>
    <!--绝对不可以为sql语句传递多个参数,我们想要传递多个参数时,我们应该将多个参数封装到domain中或者是打包到map集合中-->
    <!--<select id="selete3" parameterType="" resultType="Student">
        select * from tbl_student where age=#{age},name=#{name}
    </select>-->
    <!--如果我们为参数传递的是个Domain类型,我们的#{}中必须传递的是属性名-->
    <select id="selete4" parameterType="Student" resultType="Student">
        select * from tbl_student where name=#{name} and age=#{age}
    </select>
    <!--如果我们为sql语句传递一个map类型,那么#{}中必须是key-->
    <select id="selete5" parameterType="Student" resultType="Student">
        select * from tbl_student where name=#{name} and age=#{age}
    </select>
    <!--
    #{}:表示占位符,可以有效地方式sql注入,使用#{}设置参数无需考虑参数的类型。preparedStatement
    ${}:表示拼接符,不能方式sql注入,使用${}设置参数必须考虑参数类型,statement
    有时候需要动态拼接表名
    Select * from ${tablename}
    String tbl="tbl_student";
    String sql="select * from"+sql;
    动态拼接排序字段
    select * from tablename order by ${username} desc
    -->
    <select id="selete6" resultType="Student">
        select * from tbl_student where id='${value}';
    </select>
    <!--like模糊查询 使用${}执行like模糊查询
                    使用#{}执行like模糊查询-->
    <select id="selete7" resultType="Student">
        select * from tbl_student where name like '%${value}%'
    </select>
    <!--在mysql中空格相当于+,必须加,不能省略-->
    <select id="selete8" resultType="Student">
        select * from tbl_student where name like '%' #{name} '%'
    </select>
    <select id="selete10" resultType="String">
        select name from tbl_student where id=#{id}
    </select>
    <select id="selete11" resultType="String">
        select name from tbl_student
    </select>
    <select id="selete12" resultType="int">
        select count(*) from tbl_student
    </select>
    <select id="select14" resultType="map">
        select * from tbl_student
    </select>
    <!--起别名的方式-->
    <select id="selete15" resultType="Student">
        select id,
        fullname as name ,
        age from tbl_student
    </select>
    <!--
    id:resultMap标签对的唯一标识
    将来在使用resulrMap标签的时候,使用id来找到这组标签
    type:指定一个类型,与数据库一一对应,建立表字段和类属性的名字一一匹配的关系
    -->
    <resultMap id="stuMap" type="Student">
    <!--
    id标签:用来配置主键的对应关系的
    result标签:用来配置普通字段对应关系的
    对于tbl_student,表结果时一个id,两个普通的字段
    我们需要一个id标签,两个result标签
    property属性:配置的是类中的属性名
    column:配置都是表中的字段名

    -->
        <id property="id" column="id"/>
        <result property="name" column="fullname"/>
        <result property="age" column="age"/>
    </resultMap>
    <select id="selete16" resultMap="stuMap">
        select * from tbl_student;
    </select>
    <select id="selete17" parameterType="Student" resultType="Student">
        select * from tbl_student
        /*
        where标签在使用的时候必须要搭配if标签来使用
        通过if标签的判断,如果有查询条件,则展现where关键字如果没有查询条件则不展现where关键字
        where标签会屏蔽掉第一个连接符and/or
        */
        <where>
            <if test="name!=null and name!=''">
                name like '%' #{name} '%'
            </if>
            <if test="address!=null and address!=''">
                and address like '%' #{address} '%'
            </if>
        </where>
    </select>
    <select id="selete18" resultType="Student">
        select * from tbl_student
        where id in
        /*
        foreach标签:用来遍历传递来的数组参数
        collection:标识传递参数类型
                        array:数组
                        list:集合
        item:每次遍历出来的元素,在使用该元素的时候需要套用在#{}中
        open:拼接循环的开始符号
        close:拼接循环的结束符号
        separator:元素与元素之间的分隔符

        */
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>
    <!--使用sql标签制作sql片段
    sql片段的作用是代替sql语句中代码
    如果你的mapper映射文件中的sql语句某些代码出现了大量的重复,我们可以使用sql片段来代替他们
    id:sql片段的唯一标识,将来找到sql片段使用id来进行定位
    一般情况下没有必要使用sql片段的必要
    大量使用sql片段会大大降低sql语句可读性
    -->
    <sql id="sql1">
        select * from tbl_student
    </sql>
    <select id="selete19" resultType="Student">
        <include refid="sql1"/> where id=#{id}
    </select>
    <!--c.name和s.name不能一样所以只能起别名-->
    <select id="selete20" resultType="map">
        select s.name as sname,
               c.name as cname
        from tbl_student s
        join tbl_classroom c
        on s.classroomId=c.id

    </select>
    <select id="selete21" resultType="com.bjpowernode.vo.StudentAndClassroomVo">
        select
        s.id as sid,
        s.name as sname,
        s.age sage,
        s.address saddress,
        c.id cid,
        c.name cname
        from tbl_student s
        join tbl_classroom c
        on s.classroomId=c.id
    </select>
    <select id="selete22" resultType="com.bjpowernode.vo.StudentAndClassroomVo">
        select
        s.id as sid,
        s.name as sname,
        s.age sage,
        s.address saddress,
        c.id cid,
        c.name cname
        from tbl_student s
        join tbl_classroom c
        on s.classroomId=c.id
        where s.name like '%' #{sname} '%'

    </select>
</mapper>
// An highlighted block
package com.bjpowernode.domain;

public class Student {
    private String id;
    private String name;
    private Integer age;//Integer可以表现空值
    private String address;

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


}

//StudentServiceImpl.java
package com.bjpowernode.service.Impl;

import com.bjpowernode.Dao.StudentDao;

import com.bjpowernode.domain.Student;
import com.bjpowernode.service.StudentService;
import com.bjpowernode.util.SqlSessionUtil;

import java.util.List;

public class StudentServiceImpl implements StudentService {
    //什么是多态,将来可以将后面的接口改成更好的形态
    private StudentDao studentDao= SqlSessionUtil.getSession().getMapper(StudentDao.class);
    @Override
    public Student getById(String id) {
        Student s=studentDao.getById(id);
        return s;
    }

    @Override
    public void save(Student s) {
        studentDao.save(s);
    }

    @Override
    public List<Student> getAll() {
        List<Student> slist=studentDao.getAll();
        return slist;
    }

}

// StudentService.java
package com.bjpowernode.service;

import com.bjpowernode.domain.Student;

import java.util.List;

public interface StudentService {
    public Student getById(String id);
    public void save(Student s);

    List<Student> getAll();

}

// test1.java
package com.bjpowernode.test;


import com.bjpowernode.domain.Student;
import com.bjpowernode.service.Impl.StudentServiceImpl;
import com.bjpowernode.service.StudentService;
import com.bjpowernode.util.ServiceFactory;

import java.util.List;


public class test1 {
    public static void main(String[] args) {
        //StudentService ss=new StudentServiceImpl();
        StudentService ss= (StudentService) ServiceFactory.getService(new StudentServiceImpl());
        Student s=new Student();
        s.setAge(25);
        s.setId("A0005");
        s.setName("cxl");
        ss.save(s);
        //测试根据id查单条
      Student s1=ss.getById("A0002");
        System.out.println(s1);
        List<Student> s11=ss.getAll();
        for (Student sss:s11){
            System.out.println(sss);
        }
    }
}

//test2.java
package com.bjpowernode.test;


import com.bjpowernode.Dao.StudentDao;
import com.bjpowernode.domain.Student;

import com.bjpowernode.util.SqlSessionUtil;
import com.bjpowernode.vo.StudentAndClassroomVo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class test2 {
    public static void main(String[] args) {
        StudentDao studentDao=SqlSessionUtil.getSession().getMapper(StudentDao.class);
        /*Student s=studentDao.selete1("A0002");
        System.out.println(s);*/
        /*List<Student> students=studentDao.selete2(25);
        for (Student ss:students){
            System.out.println(ss);
        }*/
        /*查询姓名为cxk,年龄为25岁*/
       /* List<Student> students=studentDao.selete3("cxk",30);
        for (Student student:students){
            System.out.println(student);
        }*/
        /*使用domain参数查询姓名为cxf,年龄为23岁的学员信息*/
        /*Student student=new Student();
        student.setName("cxk");
        student.setAge(23);
        List<Student> students=studentDao.selete4();
        for (Student student1:students){
            System.out.println(student1);
        }*/
        /*map为参数
        * 查询cxk,23
        * */
       /* Map<String,Object> map=new HashMap<String,Object>();
        map.put("name","wxf");
        map.put("age",23);
        List<Student> students1=studentDao.selete5(map);
        for (Student student11:students1){
            System.out.println(student11);
        }*/
        /*使用map或者是domain都可以为sql语句同时传递多个参数
        * 当domain传递不符合需求的情况下我们需要使用map
        * 查询cxk,年级为一年一班的学员的详细信息
        * select * from tbl_student s
        * join tbl_classroom c on s.classroomId=c.id
        * where s.name=#{name} and c.name=#{name}
        *
        *在实际项目开发中一定要使用为sql传值的这几种方式,但是对于在select中parameter一般都是省略不写的
        *
        * */
        /*
        * 根据id查单条,sql使用${}接收
        *
        * */
       /* Student s=studentDao.selete6("A0002");
        System.out.println(s);*/

        //like模糊查询使用${}
       /*List<Student>slist= studentDao.selete7("z");
       for (Student student:slist){
           System.out.println(student);
       }*/
     /*了解一下
        List<Student>slist= studentDao.selete8("%z%");
        for (Student student:slist){
            System.out.println(student);
        }*/
     /*   List<Student>slist= studentDao.selete8("z");
        for (Student student:slist){
            System.out.println(student);
        }*/
        /*测试resultType返回String类型
        * 查询出编号为A0001的学员的姓名
        * */
        /*String name=studentDao.selete10("A0002");
        System.out.println(name);*/
        /*查询出所有学生的姓名*/
       /* List<String> name=studentDao.selete11();
        for (String s:name)
        System.out.println(s);*/
        /*测试返回Int类型,查询表中有多少条信息*/
        /*int count=studentDao.selete12();
        System.out.println(count);*/
        /*返回map类型
        *
        * */
        /*
        * 当执行了sql语句之后,通过查询得到的结果id,name,age
        * 根据返回值类型,会自动为我们创建出来一个该类型的对象,由该对象将查询的结果封装起来
        * Student s=new Student();
        * s.setId("A0001");
        * s.setAge(23);
        * s.setName("cxk");
        * ------------------------------
        * Student s=new Student();
        * s.setId("A0001");
        * s.setAge(23);
        * s.setName("cxk");
        * 多条记录封装为了多个Student对象
        * 系统会自动为我们创建出来一个List结合来保存对象
        *
        *
        * 对于sql我们可以使用domain多方便啊,为什么使用map?
        * 因为对于查询结果,很多情况使用domain不能封装,我们会使用map封装
        * 需求:根据姓名分组,查询出来每一个姓名对应得数量
        * 叫wyf的有多少人
        * 叫lh有多少人
        * 使用domain能封装查询结果值吗?
        *
        * 不能因为domain有name属性但是没有count属性
        * 使用返回值map一定可以保存查询得到的结果
        *
        * */
       /* List<Map<String,Object>> maps=studentDao.select14();
        for (Map<String,Object> map:maps){
            Set<String> set=map.keySet();
            for (String key:set){
                System.out.println("key:"+key);
                System.out.println("value:"+map.get(key));
            }
            System.out.println("----------");
        }*/
        /*
        * 当数据库中属性与Domain类属性不一致时的处理
        * */
      /*  List<Student> slist=studentDao.selete15();
        for (Student student:slist){
            System.out.println(student);
        }*/
    /*    List<Student> slist=studentDao.selete16();
        for (Student student:slist){
            System.out.println(student);
        }*/
        /*
        * 动态sql查询:
        * 在实际项目中我们对于查询需求必须将sql写成动态的形式,sql的核心思想是
        * 有哪个查询条件就动态在where关键字后面挂在哪个查询条件
        * */
     /*   Student s=new Student();
        s.setName("y");
        s.setAddress("a");
        List<Student> list=studentDao.selete17();
        for (Student student1:list){
            System.out.println(student1);
        }*/
        /*
        * 测试动态sql语句  foreach标签
        *
        * */
       /* String strArr[]={"A0002","A0003"};
        List<Student> list=studentDao.selete18(strArr);
        for (Student student1:list){
            System.out.println(student1);
        }*/
        //测试sql片段
       /* Student s=studentDao.selete19("A0002");
        System.out.println(s);*/
        /*多表查询*/
     /*   List<Map<String,Object>> mapList=studentDao.selete20();
        for (Map<String,Object> map:mapList){
            Set<String> set=map.keySet();
            for (String key:set){
                System.out.println("key:"+key);
                System.out.println("value:"+map.get(key));
            }
            System.out.println("_________________");
        }*/
        /*
        * pojo--domain
        * vo----value object
        * 查询对象加vo
        * 在实际项目开发中如果需要为前端展现数据,使用一个domain类型不足以表现
        * 出来这些数据
        * 这是我们可以考虑两种技术来实现
        * 分别为使用map以及使用vo
        * 例如我们现在的需求查询的结果使用学生的domain和班级的domain不能封装这些结果
        * 所以我们可以使用map来封装这些信息
        * 我们也可以使用map去保存这些信息
        * 同时我们可以使用vo类去保存这些信息
        * vo指的是创建出来一个类,这个类的属性是完全由我们自己去定义
        * 属性会保留所有需要展现的信息
        * 我们可以用vo封装所有的学生和班级
        *
        * */
    /*    List<StudentAndClassroomVo> voList=studentDao.selete21();
        for (StudentAndClassroomVo slist:voList){
            System.out.println(slist);
        }*/
        List<StudentAndClassroomVo> voList=studentDao.selete22("z");
        for (StudentAndClassroomVo slist:voList){
            System.out.println(slist);
        }
        /*
        * 在实际项目开发中应该使用Map还是vo
        * 如果前端的需求的重复率不高就使用map就可以了
        *
        * */
    }
}

// ServiceFactory.java
package com.bjpowernode.util;

public class ServiceFactory {
    //传递zs,得到李四的过程
    public static Object getService(Object service){
        return new TransactionInvocationHandler(service).getProxy();
    }
}

// SqlSessionUtil.java
package com.bjpowernode.util;

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 java.io.IOException;
import java.io.InputStream;

public class SqlSessionUtil {
    private static SqlSessionFactory sqlSessionFactory;
    /*目的是为了不能使用创建对象的方式创建SqlSessionUtil*/
    private SqlSessionUtil(){}
    static {
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);
    }
    /*作为一个存取的对象,基于当前线程的存取机制*/
    private static ThreadLocal<SqlSession> t = new ThreadLocal<>();

    //取得SqlSession对象
    public static SqlSession getSession() {
        SqlSession session = t.get();
        if (session == null) {
            session = sqlSessionFactory.openSession();
            t.set(session);
        }
        return session;
    }

    //关闭SqlSession对象
    public static void MyClose(SqlSession session) {
        if (session != null) {
            session.close();
            /*其实线程没有真的消除掉,线程回带线程池中,必须remove*/
            t.remove();
        }
    }

}

// TransactionInvocationHandler.java
package com.bjpowernode.util;

import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*动态代理处理类*/
public class TransactionInvocationHandler implements InvocationHandler {
    //target zs
    private Object target;
    public TransactionInvocationHandler(Object target){
        this.target=target;
    }
    //代理类的业务方法,李四的表白方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        SqlSession session=null;
        Object obj=null;
        try {
            session = SqlSessionUtil.getSession();
            /*如果没有返回值则返回一个null*/
           /*处理业务逻辑*/
            //zs的表白方法
            obj=method.invoke(target,args);
            session.commit();
        }catch (Exception e){
            //如果处理业务逻辑出错则执行回调函数
            session.rollback();
            e.printStackTrace();
        }finally {
            SqlSessionUtil.MyClose(session);
        }
        return obj;

    }
    //取得李四代理对象
        public Object getProxy(){
        //类加载器加载lisi的处理对象

            return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
}

//StudentAndClassroomVo.java
package com.bjpowernode.vo;

public class StudentAndClassroomVo {
    private String sid;
    private String sname;
    private Integer sage;//Integer可以表现空值
    private String saddress;
    private String cid;
    private String cname;

    @Override
    public String toString() {
        return "StudentAndClassroomVo{" +
                "sid='" + sid + '\'' +
                ", sname='" + sname + '\'' +
                ", sage=" + sage +
                ", saddress='" + saddress + '\'' +
                ", cid='" + cid + '\'' +
                ", cname='" + cname + '\'' +
                '}';
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Integer getSage() {
        return sage;
    }

    public void setSage(Integer sage) {
        this.sage = sage;
    }

    public String getSaddress() {
        return saddress;
    }

    public void setSaddress(String saddress) {
        this.saddress = saddress;
    }

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }
}

//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" />
    <!--设置与数据库交互的环境
    配置二级缓存,配置查询延迟策略
    配置的目的是为了更加有效的查询表中的记录
    在实际项目中setting基本没用,因为settings对于查询的优化基本上没有效果
    如何提高查询效率
    基础操作
        对于常用的查询条件的字段,设置索引
    高级操作
        使用nosql数据库,redis
    专业操作
        Elasticsearch>Solr
        针对于电商行业

    -->
    <!--<settings>
        <setting name="" value=""/>
    </settings>-->
    <!--mapper中映射文件为domain起别名-->
    <typeAliases>
        <!--
            方式一:为指定的类分别起别名
            type:要为哪个domain起别名,填写包名,类名
            alias:别名名字
            方式二:使用package标签批量起别名
            别名是Mybatis替我们起好的,命名不是由我们自己决定的,别名为类名(类名的名字不区分大小写)
            name指定一个包结构
        -->
        <package name="com.bjpowernode.domain"/>
      <!--  <typeAlias type="com.bjpowernode.domain.Student" alias="stu"></typeAlias>-->
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--

    -->
    <mappers>
        <!--方式一:resource是找到全路径-->
        <!--<mapper resource="com\bjpowernode\Dao\StudentDao.xml"/>-->
        <!--方式二:
        使用class属性,找到dao层接口的全路径-->
       <!-- <mapper class="com.bjpowernode.Dao.StudentDao"></mapper>-->
        <!--方式三
        批量注册
        name:指向dao层的包,表示在该包下所有的mapper映射文件自动注册-->
        <package name="com.bjpowernode.Dao"/>
    </mappers>
</configuration>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值