1.创建一个干净的maven项目,删除src
目录,新建模块,导入依赖
2.在resource
目录下编写mybatis-config.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/jdbcStudy?userSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 每一个Mapper.xml文件都需要在此处被注册-->
<mappers>
<mapper resource="com/lewis/dao/ShopMapper.xml" />
</mappers>
</configuration>
3.新建dao,pojo,utils
目录,在utils
目录下建立MybatisUtils
工具类,获取mybatis-config.xml
资源,建立sqlSessionFactory
工厂对象,并用openSession方法
建立sqlSession对象
//MybatisUtils.java
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//使用MyBatis第一步,获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//调用sqlSessionFactory对象的openSession方法获取sqlSession对象,使用sqlSession对象操作数据库
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
4.在pojo目录
下编写实体类,与数据表建立ORM映射
5.在dao目录
下建立表名Mapper
接口,指定对这张表的操作声明,如声明getList方法
6.在dao目录
下建立表名Mapper.xml
文件,实现sql
操作。其中mapper
标签中的namespace
的值为接口位置,指定要操作的表;select
标签中的id
值为要实现的接口中的方法,resultType
值为表名对应的pojo实体类
7.在mybatis-config.xml
文件中注册Mapper
8.注意在pom.xml
文件中建立build
标签,使java目录下的xml文件能够生效
9.在test
目录下编写测试文件测试。
在配置好之后,CURD只需要在dao层下的的Mapper接口类
里面加方法,在Mapper.xml
文件里加标签,在测试类里加方法即可。
//ShopMapper.java
public interface ShopMapper {
//得到商品列表
List<Shop> getShopList();
//根据id查询
Shop getShopById(int i);
//增
int addShop(Shop shop);
//改
int updateShop(Shop shop);
//删
int deleteShop(int id);
}
//ShopMapper.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">
<!--绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.lewis.dao.ShopMapper">
<!--获得整个列表-->
<select id="getShopList" resultType="com.lewis.pojo.Shop">
select * from jdbcstudy.shop;
</select>
<!--根据id查询-->
<select id="getShopById" resultType="com.lewis.pojo.Shop" parameterType="int">
select * from jdbcstudy.shop where id=#{id};
</select>
<!--插入-->
<insert id="addShop" parameterType="com.lewis.pojo.Shop">
insert into jdbcstudy.shop values (#{id},#{name},#{money});
</insert>
<!--更新-->
<update id="updateShop" parameterType="com.lewis.pojo.Shop">
update jdbcstudy.shop set name = #{name},money = #{money} where id=#{id};
</update>
<!-- 删除-->
<delete id="deleteShop" parameterType="int">
delete from jdbcstudy.shop where id = #{id};
</delete>
</mapper>
//ShopDaoTest.java
public class ShopDaoTest {
public static void selectList(){
//第一步,获得sqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//第二步,执行sql,getMapper
ShopMapper shopDao = sqlSession.getMapper(ShopMapper.class);
List<Shop> shopList = shopDao.getShopList();
//展示查询结果
for (Shop shop : shopList) {
System.out.println(shop);
}
//第三步,关闭sqlSession
sqlSession.close();
}
//根据id查
public static void getListById(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
ShopMapper mapper = sqlSession.getMapper(ShopMapper.class);
Shop shopById = mapper.getShopById(1);
System.out.println(shopById);
sqlSession.close();
}
//
public static void addShop(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
ShopMapper mapper = sqlSession.getMapper(ShopMapper.class);
int res = mapper.addShop(new Shop(3,"liwen",1000));//增删改只有这一句不同
//mapper.updateShop(new Shop(3,"liwen",2000)); 更新
//mapper.deleteShop(3);删除
if(res>0)
sqlSession.commit();//增删改操作需提交事务。
sqlSession.close();
}
在resources
目录下新建db.properties
,里面放数据库连接信息。
//db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcStudy?userSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
然后在mybatis-config.xml
里面可以使用properties标签
引入,使用${name}
使用
//mybatis-config.xml
<properties resource="db.properties">
<property name="password" value="123456"/>
</properties>
<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>
//mybaits-config.xml
<typeAliases>
<typeAlias type="com.lewis.pojo.Shop" alias="Shop" />//直接给实体类起别名
<package name="com.lewis.pojo"/>
</typeAliases>
在这个包下的所有实体类,别名默认为这个类的类名首字母小写,但也可以使用注解改。适用于包下实体类比较多的情况
每一个Mapper.xml文件都需要在此处被注册
//mybatis-config.xml
<mappers>
<mapper resource="com/lewis/dao/ShopMapper.xml"/>
<mapper class="com.lewis.dao.ShopMapper"/>//推荐使用class方式注册
</mappers>
sqlSessionFactoryBuilder
,sqlSessionFactory
, sqlSession
, mapper
关系1.sqlSessionFactoryBuilder
:这个类可以被实例化和丢弃,一旦创建了sqlSessionFactory,就不在需要它了。
2.sqlSessionFactory
:一旦被创建在整个程序的运行期间都存在,可以想象为一个数据库连接池,有且只能有一个,可用单例模式来实现。
3.sqlSession
:可以想象为一个数据库连接池中的一个连接,不是线程安全的,因此不能被共享,最佳作用域是放在方法被,用完之后需手动关闭,否则会占用资源。
4.mapper
:相当于一个具体的业务,执行增删改查
简单的语句不需要结果集映射,复杂语句只需描述他们之间的关系即可
//ShopMapper.xml
<resultMap id="ShopMap" type="Shop">
<result column="id" property="shopId"/>//前者是数据表字段,后者是实体类属性,建立映射
<result column="name" property="username"/>
<result column="pwd" property="password"/>
<association property="..."/>//一对多,多对一关系
<collection property="..."/>
</resultMap>
1 STDOUT_LOGIN(标准日志输出):在mybatis-config.xml
中设置,可以直接使用
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
2 log4j
导入包,新增依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
在mybatis-config.xml设置,值为LOG4J
在resources目录下新建log4j.properties文件,百度log4j配置,复制粘贴
在要使用日志输出的类中,导入log4j包;获取日志对象,参数为当前类名
sql 语句分页:select * from tableName limit startIndex,pageSize
mybatis分页:
1.接口 List getUserByLimit(Map
2.Mapper.xml: select * from mybatis.user limit #{startIndex},#{pageSize}
3.测试:
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("startIndex",0);
map.put("pageSize",2);
List<User> userList = mapper.getUserByLimit(map);
注解适合比较简单的sql语句,复杂的业务还是要用Mapper.xml文件完成语句执行
@Select("select * from user")
List<User> getUsers();
@Update("update user set name=#{},password=#{} where id=#{}")
int updateUser(User user);
@Insert("insert into user(id,name,password) values(#{id},#{name},#{password})")
int addUser(User user);
@Delete("delte from user where id=#{}")
int deleteUser(@Param(id)int id);
关于@Param()
然后在mybatis-config.xml
中注册
在实体类上加注解,可以不用写get/set,toString,有参、无参构造
等方法
1.在IDEA中安装插件
2.导入jar包(依赖)
3.在实体类上加注解
缺点:对新手不友好,降低代码可阅读性,其他的项目也必须安装这个插件才能运行
有两张表,student
表有id,name,tid
字段;teacher
表有id,name
字段,tid
为外键
//接口类
List<Student> getStudent();
//实体类
private int id;
private String name;
Private Teacher teacher;
//Mapper.xml
//方法一:按照结果嵌套,推荐使用
<select id="getStudent" resultMap="StudentTeacher">
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where s.id=t.id
</select>
<resultMap id="StudentTeacher" type="Student>
<result property="id" column="sid"/>//property表示属性;colnum表示数据库字段,别名优先
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">//对象用association,嵌套
<result property="name" column="tname"/>
</association>
</resultMap>
//方法二:子查询:查询所有的学生信息,根据查询出来的学生的tid,寻找对应的老师信息
<select id="getStudent" resultMap="StudentTeacher">//返回结果为一个Map
select * from student;
</select>
<resultMap id="StudentTeacher" resultType="Student">//返回结果为一个Student对象
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">//返回结果为一个Teacher对象
select * from teacher where id=#{id}
</select>
association
标签展开;如果返回结果为一个集合,用collection
标签展开ofType
获取//接口类
List<Teacher> getTeacher();
//实体类
private int id;
private String name;
private List<Student> student;
<select id="getStudent" resultMap="StudentTeacher">
select s.id sid,s.name sname,t.name tname,t.id tname
from student s,teacher t
where s.id=t.id and tid=#{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>//property表示属性;colnum表示数据库字段,别名优先
<result property="name" column="tname"/>
<collection property="students" ofType="Student">//集合中的泛型信息,使用ofType获取
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection >
</resultMap>
根据不同条件生成不同的SQL语句,本质是在SQL层面去执行一些逻辑代码
不输入条件,查询所有;输入参数条件,将满足条件的if标签
下的sql语句
追加到初始sql
语句末尾
<select id="queryBolgIF" parameterType="map" resultType="blog">
select * from mybatis.blog where 1=1
<if test="title! = null">
title = #{title}
</if>
<if test="author! = null">
and author= #{author}
</if>
</select>
将上面的where 1=1
换成了where标签
。有if
取值为真,才会去插where
子句,且若语句的开头为OR或AND
,会将其自动去除
<select id="queryBolgIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<if test="title! = null">
title = #{title}
</if>
<if test="author! = null">
and author= #{author}
</if>
</where>
</select>
在choose标签
里面选择一个执行,优先级与顺序有关,类似于 if-if-else
语句
<select id="queryBolgIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<choose>
<when test="title!=null">
title = #{title}
</when>
<when test="author!=null">
and author= #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
注意在if标签里加逗号,如果有多余的逗号,标签会自动删除
<update id="queryBolgUpdate" parameterType="map">
update mybatis.blog
<set>
<if test="title! = null">
title = #{title},//注意加逗号
</if>
<if test="author! = null">
and author= #{author}
</if>
</set>
where id = #{id}
</update>
使用 sql标签
抽取一些公共信息,然后使用include标签
引用即可。
注意:1.最好基于单表来定义片段;2.不要存在where标签
,因为会自动去除一些东西
//抽取
<sql id = "A">
公共部分
</sql>
//引用
<include refid="A"/>
open
的值代表开头,close
的值e代表结尾,separato的值r代表用来分隔的符号,一般为,
,or
这些。
需求:查询id值为1,2,3的用户信息
<select id="queryBolgForeach" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="id" open="and(" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
拼接后的sql语句为:select * from mybatis.blog where 1=1 and (id=1 or id=2 or id=3)
Mybatis默认开启,只在一次sqlSession中有效,也就是拿到连接到关闭连接这个区间。增删改操作会改变数据,会使缓存失效。
Mybatis默认关闭,需要手动开启,一个命名空间对应一个二级缓存。
开启二级缓存:在Mapper.xml
文件中加入
即可