一个简单的mybatis案例
1.新建数据库文件表 tb1_employee
字段 : int id, last_name varchar , email varchar, gender char
2处理java .新建工程名字 Mybatis01Helloworld 然后导入包
2.1).建立包 和类
com.smgk.mybatis.bean 存放bean 变量对应数据库的字段
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
// get set toString
}
2.2)建立 conf 文件夹 存放配置文件
建立 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">
<!--
transactionManager 事务管理器
配置数据库
dirver:数据库驱动器
url :数据库的地址
username:用户名
password: 密码
-->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 将我们配置好的sql映射文件,一定要注册到全局配置文件中, -->
<mappers>
<mapper resource="EmployeeMapping.xml"/>
</mappers>
</configuration>
然后建立 一个sql语句映射文件
eg: EmployeeMapping.xml 专门针对 employee 这个bean的映射操作
<?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">
<mapper namespace="org.mybatis.example.EmployeeMapping">
<!--
namespace:名称空间 这个可以随便根据实际情况
id: 唯一的标识符,这个名字用下使用sql语句的的标识 符
returnType:返回值 的类型,比如我们要把这个数据库的东西查找出来 然后封闭成一个对象 ,全类名
#{id}从传递过来的参数中取出id 像jdbc中的 ? 点位符
-->
<select id="selectEmp" resultType="com.smgk.mybatis.bean.Employee">
select id,last_name lastName,email,gender from tbl_employee where id = #{id}
</select>
</mapper>
然后 进入操作数据库
@Test
public void test() throws IOException {
//用mybatis操作数据库要获取一个SqlSessionFactory 然后再操作的
String resource = "mybatis-config.xml";
//主要是把配置文件读到InputStream中,然后进行操作
InputStream inputStream = Resources.getResourceAsStream(resource);
//新建SqlSessionFactory 对象获取 SqlSessionFactory,
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlSession实例,能直接执行已经映射的sql语句
SqlSession sqlSession=sqlSessionFactory.openSession();
Employee employee=sqlSession.selectOne("org.mybatis.example.EmployeeMapping.selectEmp", 1);
System.out.println(employee);
}
3. 利用 接口与配置文件进行绑定
@Test
/*
* 实现接口和配置文件绑定的方法(接口绑定和方法绑定,)
* 1 建立了接口文件 EmployeeMapping 然后建立与配置文件相对应的方法
* public Employee getEmpById(Integer id); 对应配置里面的select 这个接点的功能
* 2.把配置文件中的 nameSpace 改成接口的全类名
* 3.把配置文件中对应的sql语句节点的 id 改成 接口中方法的名字
* 然后执行下面相对应的操作
* 4.
*/
public void test2() throws IOException {
//获取sqlSession
SqlSessionFactory ssf=getSqlSessionFactory();
SqlSession ss=ssf.openSession();
try {
//通过sqlSession 获取映射 ss.getMapper 里面的参数就是接口名.class
EmployeeMapping em=ss.getMapper(EmployeeMapping.class);
//然后调用接口相对应的方法就可以了
Employee e= em.getEmpById(1);
System.out.println(e);
}finally {
ss.close();
}
}
二 mybatis 中 的增删查改
搭建环境省略,
1.建立bean与数据库
public class Student {
private Integer id;
private String lastName;
private String email;
private String gender;
private String city;
}
2.具体实现
获取SqlSessionFactory方法
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource="mybatis-config.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
增:
@Test
public void testAdd() throws IOException {
SqlSessionFactory ssf = getSqlSessionFactory();
SqlSession ss = ssf.openSession();
try {
StudentMapper sm = ss.getMapper(StudentMapper.class);
Student s=new Student(2, "小红", "xx@xx.com", "1", "guanddong");
sm.addStudent(s);
ss.commit();
}finally {
ss.close();
}
}/*
<!-- public void addStudent(Student student); -->
<insert id="addStudent" parameterType="com.smgk.mybatis.bean.Student">
insert into tbl_student_crud(id,last_name,gender,email,city)
values(#{id},#{lastName},#{gender},#{email},#{city})
</insert> */
删:
@Test
public void testDelete() throws IOException {
SqlSessionFactory ssf = getSqlSessionFactory();
SqlSession ss = ssf.openSession();
try {
StudentMapper sm = ss.getMapper(StudentMapper.class);
Integer id=2;
sm.deleteStudetn(5);
ss.commit();
}finally {
ss.close();
}
} /*
<!-- public void deleteStudetn(Integer id); -->
<delete id="deleteStudetn" parameterType="java.lang.Integer">
delete from tbl_student_crud where id=#{id}
</delete> */
查:
@Test
public void testSelect() throws IOException {
SqlSessionFactory ssf = getSqlSessionFactory();
SqlSession ss = ssf.openSession();
try {
StudentMapper sm=ss.getMapper(StudentMapper.class);
Student s=sm.getStudentById(1);
System.out.println(s);
}finally {
ss.close();
}
} /*
<!-- public Student getStudentById(Integer id); -->
<select id="getStudentById" resultType="com.smgk.mybatis.bean.Student">
select * from tbl_student_crud where id = #{id}
</select> */
改:
@Test
public void testUpdate() throws IOException {
SqlSessionFactory ssf = getSqlSessionFactory();
SqlSession ss = ssf.openSession();
try {
StudentMapper sm = ss.getMapper(StudentMapper.class);
Student s=new Student(4, "小陈", "xc@xc.com", "0", "guanddong");
sm.updateStudent(s);
ss.commit();
}finally {
ss.close();
}
} /*
<!-- public void updateStudent(Student student); -->
<update id="updateStudent" parameterType="com.smgk.mybatis.bean.Student">
update tbl_student_crud set id=#{id},last_name=#{lastName},gender=#{gender},email=#{email},city=#{city} where id=#{id}
</update> */
3. 自定义操作数据库.xml返回对象类型
<!--
自定义 resultMap 类型(自定义某个javabean的结果集映射规则)
type: 自定规则 的javabean 的类型
id: 唯一id方便使用
-->
<resultMap type="com.smgk.mybatis.bean.Student" id="MyStu">
<!-- 定义主键封闭规则
id : 定义主键列的封闭规则
result 普通 列
column:指定哪 一列 对应数据库的一列
property: 指定对应的javabean属性
-->
<id column="id" property="id"/>
<result column="email" property="email" />
<result column="gender" property="gender" />
<result column="last_name" property="lastName" />
</resultMap>
<select id="testResultMap" resultMap="MyStu">
select * from tbl_student_crud;
</select>
4.分页查询
Student 中的 d_id 跟 department 中的 id 相关联
<!-- 分步查询 -->
<!-- 使用association进行分步查询
1.先按照员工id进行分步查询
2.根据查询到的员工信息中的d_id 值 去部门表查出部门的数据
3.部门设置到员工中去
使用select 定的方法(传入column指定的这列参数的值)查出对象封闭到property里面 就是这里的dept方法
考虑到性能的问题 建议开户延时加载 (按需加载)
Employee ====> Dept
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
-->
<resultMap type="com.smgk.mybatis.bean.Student" id="MyStuByStem">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/>
<result column="city" property="city"/>
<!--使用联合 association操作级联属性值-->
<association property="dept" select="com.smgk.mybatis.dao.DepartmentMapper.getDeptById" column="d_id"></association>
</resultMap>
<select id="getStuByIdStep" resultMap="MyStuByStem">
select * from tbl_student_crud where id=#{id}
</select>
5. 通过bean 中的集合类型的get方法在获取 部门时把部门那一组的学生也返回
Collection 嵌套结果集的的方式,定义关联集合类型元素的封装规则
<!-- public Department getDeptByIdPlus(Integer id);
查找部门 通过返回部门,把部门信息和部门所在的员工信息都返回
-->
<resultMap type="com.smgk.mybatis.bean.Department" id="MyDept">
<id column="id" property="id"/>
<result column="dept_name" property="deptName"/>
<!-- onllection 定义关联集合类型的属性的封闭规则
ofType 是集合里面无线的类型
-->
<collection property="stus" ofType="com.smgk.mybatis.bean.Student">
<id column="s_id" property="id"/>
<result column="city" property="city"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<result column="last_name" property="lastName"/>
</collection>
</resultMap>
<select id="getDeptByIdPlus" resultMap="MyDept">
select * from tbl_dept d left join tbl_student_crud s on d.id=s.d_id where d.id=#{id}
</select>
三、动态 SQL【主要是把sql语句变得灵活 动态,不像以前那么固执】
主要有四种
- if 条件判断(动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分)
- choose (when, otherwise)
- trim (where, set) 字符
- foreach
3.1 if
<!-- public List<Student> getStuByDynamicIF(Student stu);
根据传入的学生对象中获取里面的属性值 进行条件查找
解释 where 这个语句的问题有两种
一个: 在where 后面直接加一个1=1,然后后面条件全部加个and
第二个
-->
<select id="getStuByDynamicIF" resultType="com.smgk.mybatis.bean.Student">
select * from tbl_student_crud
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="gender!=null">
and gender=#{gender}
</if>
<if test="email!=null">
and email=#{email}
</if>
<if test="lastName!=null && lastName!=''">
and last_name like #{lastName}
</if>
<if test="city!=null">
and city = #{city}
</if>
</where>
</select>
<!-- Student stu=new Student(null, "", null, null, null, null);
List<Student> stuList=smd.getStuByDynamicIF(stu);
for(Student stu1:stuList) {
System.out.println(stu1);
}
-->
3.2:trim 自定义字符串切割
<!-- public List<Student> getStuByDynamicTrim(Student stu);
测试 :trim 字符串切割
prefix: 前缀 给字符串加一个前缀
prefixOverrides: 前缀覆盖 去掉整个字符串前面多余的字符
suffix:后缀 给字符串加一个后缀
suffixOverrides: 后缀覆盖 去掉整个字符串后面多余的字符
-->
3.3 choose 相当于java中的条件分支yg语句
<!--public List<Student> getStuByDynamicChoose(Student stu);
测试 Choose 实现带进来的对象 哪 个属性不为空条件就是那个
注意 如果带了多个值 就会按并且 &&这个处理
-->
<select id="getStuByDynamicChoose" resultType="com.smgk.mybatis.bean.Student">
select * from tbl_student_crud
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null">
last_name like #{lastName}
</when>
<when test="gender!=null">
gender=#{gender}
</when>
<when test="email!=null">
email=#{email}
</when>
<when test="city!=null">
city=#{city}
</when>
</choose>
</where>
</select>
3.4: SET 修改用的标签
<!-- public void updateStuDynamic(Student stu);
sql 语句 update tbl_student_crud set last_name=#{lastName},
gender=#{gender},email=#{email},city=#{city}
where id=#{id}
利用set标签测试动态修改
-->
<update id="updateStuDynamic" >
update tbl_student_crud
<set>
<if test="lastName!=null">
last_name=#{lastName}
</if>
<if test="gender!=null">
gender=#{gender}
</if>
<if test="email!=null">
email=#{email}
</if>
<if test="city!=null">
city=#{city}
</if>
</set>
where id=#{id}
</update>
3.5:foreach 标签
<!-- public List<Student> testGetStuDynamicByFoEach(List list);
测试foreach标签 :
collection: 指定要遍历的集合 list类型的参数会特殊处理封装 在map中 map的key 就叫list
item: 指遍历出来 的指定到这个属性的值中 (赋值到item中 直接 ${item值})
separator: 每个元素之间的分隔符
open : 遍历出的结果 接成新的元素 然后open的内容就是这个新的值 的开始
close : 遍历出来 的结果 的一个新的结尾
index 索引 遍历list时 是索引 遍历map时是key
-->
<!-- select * from tbl_student_crud where id in(1,2,3) 下面的就是要实现这样的语句-->
<select id="testGetStuDynamicByFoEach" resultType="com.smgk.mybatis.bean.Student">
select * from tbl_student_crud where id in
<foreach collection="list" open="(" close=")" item="item_id" separator=",">
#{item_id}
</foreach>
</select>
3.6 bind 绑定标签 把一个字符串进行封装再传出来 用法很简单 比如要将这个获取 到的一个变量再加上一个%在
模糊查询中用,'%'#{lastName}'%'
<bind name="_转换后在名字" value=''%'#{lastName}'%''>
#{_转换后在名字} 这样取出;
四、缓存
1)一级缓存 :(sg)本地缓存 :sqlSession同级别的缓存【一定要是同级的session】。一级缓存是一直开启的,
只有是发送相同的数据库语句查找相同的内容才会生效
1.1)要是相同的sqlSession
1.2)要是相同的查询条件
1.3)要想使用缓存 ,两条相同语句中间不能使用增删改操作的语句
1.4)清空一级缓存 sqlSession.clearCache();
2)二级缓存(全局缓存)
基于namespace 命名空间就是相当于一个xml文件下的缓存 ,一个namespace对应一个缓存
工作机制
2.1)一个会话查询 到一条数据,这个数据 会被 放到当前会话的一级缓存中去
2.2)如果会话关闭,一级缓存中的数据会被 保存到二级缓存 中去,新的会话查询信息
注意: 二级缓存 要等你第一次会话的关闭了以后就会把一级缓存 转换到二级缓存
实现
1.开启二级缓存配置<setting name="cacheEnabled" value="true">
2.在对应的mapper.xml中开启 <cache></cache>
3. 对应的bean类中要实现 Serializable(可串化的)
四 、逆向工程 根据表返回出 bean beanMapper, beanMapper.xml
http://www.mybatis.org/generator/(官网手册)
直接建立 了个xml文件,配置好要转换的信息然后运行一个tk程序 直接逆向生成
1.导入包:
2.建立xml文件
2.1)指定一个转换对象的环境器
<context id="DB2Tables" targetRuntime="MyBatis3Simple">
2.2).配置数据源,指定怎样链接数据库【driver,url,username,password】
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis"
userId="root"
password="123456">
</jdbcConnection>
2.3)设置java类型转换器
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
2.4)指定javabean生成策略
targetPackage //目标包 targetProject//目标工程 .\表示当前目录下的文件夹
<javaModelGenerator
targetPackage="com.smgk.mybatis.bean" targetProject=".\src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
2.5 sqm映射生成策略 这个是映射 xml文件,就是映射 sql语句
<sqlMapGenerator
targetPackage="com.smgk.mybatis.dao" targetProject=".\conf">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
2.6 生成接口文件 指定 把接口生成在哪个包下 -
<javaClientGenerator
type="XMLMAPPER" targetPackage="com.smgk.mybatis.dao" targetProject=".\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
2.7)指定要逆向分析的表,即分析要逆向生成bean 和xml的表
domainObjectName:对应的bean类名
<table tableName="tbl_dept" domainObjectName="Department"></table>
<table tableName="tbl_employee" domainObjectName="Employee"></table>
3 实现逆向工程:http://www.mybatis.org/generator/running/running.html
3.1)直接在myeclipse中生成
@Test
public void testmbg() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("mbg.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
配置文件要这样来配置Mapper.xml文档的位置
其它不变可以像往常一样测试
五、分页,利用pageHelper.jar包 这个插件是分页的插件
1.加入jar包
2.在配置文件中配置分页插件(注意顺序)
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3. 在方法中实现
@Test
public void test1() throws IOException {
SqlSessionFactory ssf = getSqlSessionFactory();
SqlSession ss = ssf.openSession();
try {
StudentMapper sm = ss.getMapper(StudentMapper.class);
PageHelper.startPage(3, 3);
List<Student> listStus = sm.getAllStus();
PageInfo<Student> info=new PageInfo<>(listStus);//传这个对象过去是为了可以获取详细的分布数据
for(Student stu:listStus) {
System.out.println(stu);
}
System.out.println("记录数 :"+info.getTotal());
System.out.println("当前面最后一行的行是"+info.getEndRow());
System.out.println("上一页:"+info.getPrePage());
System.out.println("当前页:"+info.getPageNum());
System.out.println("下一页:"+info.getNextPage());
System.out.println("总页数:"+info.getPages());
System.out.println("一页显示记录数:"+info.getPageSize());
ss.commit();
}finally {
ss.commit();
}
}