mybatis配置文件解析

it2025-03-28  12

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)