中文官网:https://mybatis.org/mybatis-3/zh/index.html
MyBatis是属于持久层(DAO层)的框架
封装了JDBC的很多操作细节,让开发者大大简化了DAO层的代码
在2010年从iBatis改名为Mybatis
一、创建核心配置文件(一般叫mybatis-config.xml),配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--是否开启驼峰命名自动映射,默认false,created_time -> createdTime 如果不开启在mapper里面也可以设置 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--打印Sql日志log-->
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
</settings>
<!--别名-->
<typeAliases>
<!--一旦设置了别名,不区分大小写-->
<!-- <typeAlias type="com.mj.bean.Skill" alias="skill"/>-->
<!-- <typeAlias type="com.mj.bean.Experience" alias="experience"/>-->
<!--这个包下的所有类,都会有一个别名:短类名也就是全类名的最后一个单词-->
<package name="com.mj.bean"/>
</typeAliases>
<environments default="dev">
<environment id="dev">
<!--采用JDBC的事物管理方法-->
<transactionManager type="JDBC"/>
<!--POOLED代表采用连接池的方式管理链接 更改成阿里巴巴的连接池-->
<dataSource type="com.mj.common.DruidDataSourceFactory">
<!--数据库驱动-->
<!--阿里巴巴连接池这个名字是driverClassName-->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/crm"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
<environment id="pro">
<!--采用JDBC的事物管理方法-->
<transactionManager type="JDBC"/>
<!--POOLED代表采用连接池的方式管理链接-->
<dataSource type="POOLED">
<!--数据库驱动-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/crm"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--映射文件-->
<mapper resource="mappers/skill.xml" />
<mapper resource="mappers/experience.xml" />
</mappers>
</configuration>
二、创建数据库映射mapper文件如下:
- 单表查询如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="skill"> <select id="list" resultType="com.mj.bean.Skill"> SELECT * FROM skill </select> <select id="get" resultType="com.mj.bean.Skill"> SELECT * FROM skill WHERE id = #{id} </select> <select id="list2" resultType="com.mj.bean.Skill"> <!--不要用${id} 美元符代表的是直接替换,会有SQL注入的风险--> SELECT * FROM skill WHERE id > #{id} OR level > #{level} OR name LIKE #{name} </select> <!-- 手动开启属性和数据库字段的映射 --> <!-- <resultMap id="rm" type="com.mj.bean.Skill">--> <!-- <id property="id" column="id"/>--> <!-- <result property="createdTime" column="created_time"/>--> <!-- <result property="name" column="name"/>--> <!-- <result property="level" column="level"/>--> <!-- </resultMap>--> <!-- <select id="list" resultMap="rm">--> <!-- SELECT * FROM skill--> <!-- </select>--> </mapper>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="skill"> <!-- 手动开启属性和数据库字段的映射 --> <resultMap id="rm" type="com.mj.bean.Skill"> <!-- 主键一般用id --> <id property="id" column="id"/> <result property="createdTime" column="created_time"/> <result property="name" column="name"/> <result property="level" column="level"/> </resultMap> <select id="list" resultMap="rm"> SELECT * FROM skill </select> </mapper>
- 联表查询如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="experience"> <!-- 第一种方式 --> <select id="list" resultType="com.mj.bean.Experience"> SELECT t1.*, t2.id `company.id`, t2.name `company.name`, t2.intro `company.intro` FROM experience t1 JOIN company t2 ON t1.company_id = t2.id </select> <!-- 第二种方式 --> <!-- <resultMap id="rmExperience" type="com.mj.bean.Experience">--> <!-- <result property="company.name" column="t2_name"/>--> <!-- <result property="company.id" column="t2_id"/>--> <!-- <result property="company.intro" column="t2_intro"/>--> <!-- </resultMap>--> <!-- <select id="list" resultMap="rmExperience">--> <!-- SELECT--> <!-- t1.*,--> <!-- t2.id t2_id,--> <!-- t2.name t2_name,--> <!-- t2.intro t2_intro--> <!-- FROM--> <!-- experience t1--> <!-- JOIN--> <!-- company t2--> <!-- ON t1.company_id = t2.id--> <!-- </select>--> </mapper>
三、test类中访问数据库
@Test
public void select() throws Exception{
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 创建一个工厂构建器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 创建一个工厂
SqlSessionFactory factory = builder.build(reader);
// 创建一个session
SqlSession session = factory.openSession();
List<Skill> skills = session.selectList("skill.list");
for (Skill skill : skills) {
System.out.println(skill);
}
}
封装工具类:
public class MyBatises {
private static SqlSessionFactory factory;
static {
try ( Reader reader = Resources.getResourceAsReader("mybatis-config.xml")) {
// 创建一个工厂.factory 保留一份
factory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSession openSession() {
return factory.openSession();
}
}
访问数据库带参数如下:
@Test
public void select2() throws Exception{
try ( SqlSession session = MyBatises.openSession()){
Skill skill = session.selectOne("skill.get",2);
System.out.println(skill);
}
}
@Test
public void select3() throws Exception{
try ( SqlSession session = MyBatises.openSession()){
// 以下两种方式都可以
// HashMap map = new HashMap();
// map.put("id",2);
// map.put("level", 30);
Skill skill = new Skill();
skill.setId(2);
skill.setLevel(30);
skill.setName("%三%");
List<Skill> skills = session.selectList("skill.list2",skill);
for (Skill skill1 : skills) {
System.out.println(skill1);
}
}
}
更改阿里巴巴连接池:
<!--阿里巴巴的连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.11</version> </dependency>
mybatis配置文件:
<environment id="dev"> <!--采用JDBC的事物管理方法--> <transactionManager type="JDBC"/> <!--POOLED代表采用连接池的方式管理链接 更改成阿里巴巴的连接池--> <dataSource type="com.mj.common.DruidDataSourceFactory"> <!--数据库驱动--> <!--阿里巴巴连接池这个名字是driverClassName--> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/crm"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment>
相关类的设置:
package com.mj.common; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory; public class DruidDataSourceFactory extends PooledDataSourceFactory { public DruidDataSourceFactory() { this.dataSource = new DruidDataSource(); } }
汇总增删改查如下:
测试类如下:
public class SkillTest { @Test public void select() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); // 创建一个工厂构建器 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); // 创建一个工厂 SqlSessionFactory factory = builder.build(reader); // 创建一个session SqlSession session = factory.openSession(); List<Skill> skills = session.selectList("skill.list"); for (Skill skill : skills) { System.out.println(skill); } } @Test public void select2() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ Skill skill = session.selectOne("skill.get",2); System.out.println(skill); } } @Test public void select3() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ // 以下两种方式都可以 // HashMap map = new HashMap(); // map.put("id",2); // map.put("level", 30); Skill skill = new Skill(); skill.setId(2); skill.setLevel(30); skill.setName("%三%"); List<Skill> skills = session.selectList("skill.list2",skill); for (Skill skill1 : skills) { System.out.println(skill1); } } } @Test public void select4() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ String string = "%三%"; List<Skill> skills = session.selectList("skill.list3",string); for (Skill skill1 : skills) { System.out.println(skill1); } } } @Test public void insert() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ Skill skill = new Skill("我是张三",1234); session.insert("skill.insert2",skill); System.out.println(skill.getId()); // mybatis默认不会自动提交事物,需要手动管理 session.commit(); } } @Test public void update() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ Skill skill = new Skill("我是张三",1234); skill.setId(1); session.update("skill.update",skill); System.out.println(skill.getId()); // mybatis默认不会自动提交事物,需要手动管理 session.commit(); } } @Test public void delete() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ Skill skill = new Skill(); skill.setId(1); session.delete("skill.delete",skill); System.out.println(skill.getId()); // mybatis默认不会自动提交事物,需要手动管理 session.commit(); } } @Test public void dynamicSQL() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ // id name level 三个条件 Skill skill = new Skill(); skill.setId(5); skill.setName("我是张三"); skill.setLevel(12); List<Skill> skills = session.selectList("skill.dynamicSQL1",skill); for (Skill skill1 : skills) { System.out.println(skill1); } } } // 批量插入 @Test public void batchInsert() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ List<Skill> skills = new ArrayList<>(); skills.add(new Skill("天王1",34)); skills.add(new Skill("天王2",35)); skills.add(new Skill("天王3",36)); session.insert("skill.batchInsert",skills); session.commit(); } } // 批量删除 @Test public void batchDelete() throws Exception{ try ( SqlSession session = MyBatises.openSession()){ List<Integer> ids = new ArrayList<>(); ids.add(14); ids.add(16); ids.add(17); session.insert("skill.batchDelete",ids); session.commit(); } } }
mapper中skill.xml文件如下
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="skill"> <!--查询所有数据--> <select id="list" resultType="skill"> SELECT * FROM skill </select> <!--根据id查询数据--> <select id="get" parameterType="int" resultType="com.mj.bean.Skill"> SELECT * FROM skill WHERE id = #{id} </select> <!--根据条件查找数据--> <select id="list2" parameterType="com.mj.bean.Skill" resultType="com.mj.bean.Skill"> <!--不要用${id} 美元符代表的是直接替换,会有SQL注入的风险--> SELECT * FROM skill WHERE id > #{id} OR level > #{level} OR name LIKE #{name} </select> <!--根据条件查找数据--> <select id="list3" parameterType="String" resultType="com.mj.bean.Skill"> <!--不要用${id} 美元符代表的是直接替换,会有SQL注入的风险--> SELECT * FROM skill WHERE name LIKE #{name} </select> <!-- 动态SQL --> <select id="dynamicSQL" parameterType="com.mj.bean.Skill" resultType="com.mj.bean.Skill"> SELECT * FROM skill WHERE 1 = 1 <if test="id != null"> AND id > #{id} </if> <if test="name != null"> AND name like #{name} </if> <if test="level != null"> AND level > #{level} </if> </select> <select id="dynamicSQL1" parameterType="com.mj.bean.Skill" resultType="com.mj.bean.Skill"> SELECT * FROM skill <where> <if test="id != null"> AND id > #{id} </if> <if test="name != null"> AND name like #{name} </if> <if test="level != null"> AND level > #{level} </if> </where> </select> <!-- 手动开启属性和数据库字段的映射 --> <!-- <resultMap id="rm" type="com.mj.bean.Skill">--> <!-- <id property="id" column="id"/>--> <!-- <result property="createdTime" column="created_time"/>--> <!-- <result property="name" column="name"/>--> <!-- <result property="level" column="level"/>--> <!-- </resultMap>--> <!-- <select id="list" resultMap="rm">--> <!-- SELECT * FROM skill--> <!-- </select>--> <!--插入数据--> <insert id="insert" parameterType="com.mj.bean.Skill"> INSERT INTO skill(name,level) VALUES (#{name},#{level}) </insert> <!--插入数据后立刻返回ID--> <insert id="insert2" parameterType="com.mj.bean.Skill"> INSERT INTO skill(name,level) VALUES (#{name},#{level}) <!--插入之后就能拿到id--> <selectKey resultType="int" keyProperty="id" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> </insert> <!--更新某条数据--> <update id="update" parameterType="com.mj.bean.Skill"> UPDATE skill SET name = #{name}, level = #{level} WHERE id = #{id} </update> <!--删除数据--> <delete id="delete" parameterType="int"> DELETE FROM skill WHERE id = #{id} </delete> <!--插入多条,批量添加, 能获取主键--> <insert id="batchInsert" useGeneratedKeys="true" keyProperty="id" parameterType="List" > INSERT INTO skill(name, level) VALUES <foreach collection="list" item="skill" separator=","> (#{skill.name}, #{skill.level}) </foreach> </insert> <!--删除多条,批量删除--> <delete id="batchDelete" parameterType="List" > DELETE FROM skill WHERE id IN <foreach collection="list" item="id" open="(" close=")" separator=","> #{id} </foreach> </delete> </mapper>
注:批量添加比单个多次添加效率高,批量操作生成的SQL语句可能会比较长,有可能会超过数据库的限制
mybatis配置文件写SQL语句的某些字符需要转义:
<
< > > <> <> & & ' ' " "
工程结构如下: