特意说明,这里使用模块儿而不是整个项目是为了方便学习。每个模块儿的pom.xml都在父级项目当中进行了声明,这样不用频繁进行jar包的导入。
在src/main/resouces目录下面创建一个xml文件,建议使用`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://localhost:3306/mybatis?userSSL=true&userUnicode=ture&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration>目的是为了将MyBatis配置文件加载,其他内容进行一次封装。
public class MyBatisUtil { // 加载配置文件获取工厂 private static SqlSessionFactory sqlSessionFactory = null; static { String resource = "mybatis-config.xml"; InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } finally { if(inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(); } }这里的user属性 和 数据库mybits.user中的字段是一样(先保持名字一致)。
public class User { private int id; private String name; private String pwd; // 省略构造 + getter/setter }一旦创建了SqlSessionFactory就不再需要了,因此其最佳使用位置是局部方法位置。不应该让其一直存在,以保证所有的XML解析资源可以被释放给重要的事情。
被创建就应该一直存在,没有必要抛弃它后重新创建。其最佳作用域是应用的作用区域。很多方法可以做到,比如单例模式,静态单例模式,或者用静态代码块儿进行初始化。
SqlSession是线程不安全,放在局部作用区域使用,确保其在单线程中。应该让每次收到一个请求,打开一个SqlSession,返回响应,然后关闭。
可以配置多个环境变量对应于不同的数据库,但是项目只能使用一个数据一个环境。记住2点:MyBatis默认使用的事物管理器就是JDBC,链接池是POOLED。
可以用来引入外部的配置文件, 或者将配置字段值当作子标签值。
引入外部配置: 在mybatis-config.xml直接设置配置:类型别名是为Java类设置的一个短的名字。只和XML配置有关,存在的意义仅仅是为了减少类完全限定名的冗余。例如:
此配置选项实在太多了,需要对照对照官网使用 ,但是先记住如下几个的使用:
官网地址:settings设置
<!-- 设置 --> <settings> <!-- 开启二级缓存,虽然默认是开启的,但是再开启一遍。 --> <setting name="cacheEnabled" value="true"/> <!-- 设置日志 --> <setting name="logImpl" value="LOG4J"/> </settings>注册绑定我们的mapper文件。
mapper.xml 可以放置在任何位置,资源路径写对了即可。
<mappers> <mapper resources="dao/UserMapper.xml"/> </mappers>接口名称必须和xml文件名一致,且放在同一个目录下。
<!-- dao 目录下 : UserMapper.java UserMapper.xml --> <mappers> <mapper class="dao.UserMapper"/> </mappers>可以将一个包下面的所有mapper直接进行注册,条件和方式二一致。
<mappers> <mapper name="dao"/> </mappers>为了解决了数据库记录 向 POJO的映射过程中,由于名称不一致导致的查询为null的情况,可以使用如下的解决方案:
利用Sql的取别名即可了, 将查询出来的字段设置为
了解一些,主要使用的还是配置文件的方式进行开发。在注解开发当中可以不用使用mapper.xml文件了, 且mybatis-config.xml文件映射mapper的方式为导class属性的方式。
使用注解映射简单语句比较简便,但是对于负责,需要配置结果集映射的情况,就力不从心了。
其本质是反射机制,底层使用的动态代理。
#{}是带有预编译, 很大程度上能防止SQL注入的问题,而使用${}是不安全的。
表示多对一当中的那个多的POJO当中的表示一的那个对象,比如Student类中设置了一个Teacher成员。
查询所有学生的信息以及对应的老师的信息:
类似子查询方式 : <mapper namespace="dao.StudentMapper"> <!-- 配置多对一关系映射 --> <resultMap id="StudentTeacher" type="pojo.Student"> <!-- property : POJO的属性。 column : 外键字段。 javaType : POJO的属性的类型。 --> <association property="teacher" column="tid" javaType="pojo.Teacher" select="getTeacher"/> </resultMap> <!-- 查询所有学生 --> <select id="getAllStudent" resultMap="StudentTeacher" resultType="pojo.Student"> select * from student </select> <select id="getTeacher" resultType="pojo.Teacher"> select * from teacher where id=#{id} </select> </mapper> 联接查询方式 : <resultMap id="StudentTeacherInnerJoin" type="pojo.Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <!-- property : POJO的属性。 javaType : POJO的属性的类型。 --> <association property="teacher" javaType="pojo.Teacher"> <result property="name" column="tname"/> </association> </resultMap> <select id="getAllStudentUserInnerJoin" resultMap="StudentTeacherInnerJoin" resultType="pojo.Student"> select s.id sid, s.name sname, t.name tname from student as s, teacher as t where s.tid=t.id; </select>表示多对一当中的那个一的POJO当中的表示多那个对象,比如Teacher类中设置了一个Student的集合成员。
需求:查询指定老师和其所有的学生。
类似查询方式: <mapper namespace="dao.TeacherMapper"> <select id="getTeacherById" resultType="pojo.Teacher" resultMap="TeacherStudent"> select * from teacher where id=#{id} </select> <resultMap id="TeacherStudent" type="pojo.Teacher"> <!-- property : POJO的属性 javaType : POJO属性的类型 ofType : 集合的泛型 select : 使用的子查询。 --> <collection property="students" javaType="ArrayList" ofType="pojo.Student" select="getStudentByTeacherId" column="id"/> </resultMap> <select id="getStudentByTeacherId" resultType="pojo.Student"> select * from student where tid=#{tid} </select> </mapper> 联接查询方式: <mapper namespace="dao.TeacherMapper"> <resultMap id="TeacherStudent" type="pojo.Teacher"> <result property="name" column="tname"/> <!-- property : POJO的属性。 ofType : 集合的泛型的类型。 --> <collection property="students" ofType="pojo.Student"> <result property="name" column="sname"/> </collection> </resultMap> <select id="getTeacherById" parameterType="int" resultMap="TeacherStudent" resultType="pojo.Teacher"> select t.name tname, s.name sname from teacher as t, student as s where t.id=#{id} and t.id=s.tid </select> </mapper>动态SQL就是方法传入的参数不同条件生成不同的SQL语句。其目的是为了简化SQL语句拼接的问题
这里直接看文档就行了
一次查询的结果,暂时存放到一个地方,当还要查询的时候,直接去缓存里面查询。(经常使用且不经常改变的数据)。
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存的。
默认情况下的,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)二级缓存需要手动开启,namespace(一个Mapper)级别的缓存。还提供自定义方式,实现二级缓存。在SqlSession 和 其close之间使用。
只需要在mapper.xml中添加如下一个标签:
<cache eviction = "FIFO" // 缓存策略 flushInterval="60000" // 刷新缓存的时间 size="512" // 缓存的大小 readOnly="true" // 只读 />