目录
3、编写Mybatis核心配置文件 mybatis-config.xml
4、编写SQL映射文件:SQL语句代码UserMapper.xml

pom 就是 project object moudle 项目对象模型
配置完pom.xml文件之后,相对应的jar包就会出现在项目中,不需要再手动导包,而实际在maven中有一个本地仓库,仓库中存放有相对应的jar包,它只是通过本地仓库将jar包导入项目。

由于中央仓库是由maven团队维护,由于仓库位置在国外,在国内访问速度较慢,所以一般公司会搭建自己的私服,将中央仓库的jar包同步下来,通过访问私服速度更快,中央仓库中存放的都是开源的jar包,带版权的jar只能在私服中

仓库工作流程:
项目1中需要某个jar包,向本地仓库申请,本地仓库中没有再向中央仓库中申请,并将相对应的jar包保存在本地仓库,然后导入项目1中,这时项目2需要用到该jar包时直接向本地仓库申请后导入。但如果架设了私服,本地仓库会先向私服请求,私服没有才会向中央仓库请求,然后将jar包下载到私服,再保存到本地仓库。




maven通过核心配置文件直接导包,不需要再下载后右键导包。

在setting文件中指定本地仓库
<localRepository>D:\2ProgramTool\Intellij idea\apache\maven cangkulocalRepository>

compile编译,将代码编译成 字节码文件,生成目标文件target文件
clean清理,将目标文件删除
test测试,执行test文件夹下的测试代码,输出测试结果
package打包,将该maven项目打包成jar文件
install安装,将该maven项目的jar包下载进本地仓库
使用Maven可以将项目打包!!

Maven对项目构建的生命周期分为3套 :clean、default、site






-
-
- <dependencies>
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
-
- <version>5.1.34version>
- dependency>
-
- <dependency>
-
-
- <groupId>com.alibabagroupId>
- <artifactId>druidartifactId>
- <version>1.1.12version>
- dependency>
-
- dependencies>

运行环境不存在说明这个依赖不会存在打包好的jar包中。

与数据库进行操作的代码称为持久层。三层框架:表现层,业务层,持久层 -> 前端、后端、数据库

将数据库连接和数据库操作都写在依赖中


- CREATE DATABASE mybatis;
- USE mybatis;
-
- DROP TABLE IF EXISTS tb_user;
-
- CREATE TABLE tb_user(
- id INT PRIMARY KEY AUTO_INCREMENT,
- username VARCHAR(10),
- password VARCHAR(10),
- gender CHAR(1),
- addr VARCHAR(30)
- );
-
- INSERT INTO tb_user(username,password,gender,addr)
- VALUES
- ('张三','12345','男','安徽'),
- ('李四','14335','男','芜湖'),
- ('王五','16745','女','南京');

-
-
- 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?useSSL=false"/>
- <property name="username" value="root"/>
- <property name="password" value="12345"/>
- dataSource>
- environment>
- environments>
- <mappers>
-
- <mapper resource="UserMapper.xml"/>
- mappers>
- configuration>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
- <mapper namespace="test">
-
- <select id="selectAll" resultType="com.itheima.pojo.User">
- select * from tb_user;
- select>
-
- mapper>
- public class User {
- private Integer id;
- private String username;
- private String password;
- private String gender;
- private String addr;
- public class MybatisDemo {
- public static void main(String[] args) throws Exception {
- //1、加载Mybatis核心配置文件,获取SqlSessionFactory
- String resource = "mybatis-config.xml";
- //Mybatis提供了资源加载类Resource,通过静态方法getResourceAsStream将字符串返回成一个字节输入流
- InputStream inputStream = Resources.getResourceAsStream(resource);
- //再通过SqlSessionFactoryBuilder对象的build方法获取字节输入流创建一个sqlSessionFactory
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
-
- //2、用sqlSessionFactory获取对应sqlSession对象
- SqlSession sqlSession = sqlSessionFactory.openSession();
-
- //3、执行sql
- //传入SQL语句的唯一标识需要跟上名称空间
- List
users = sqlSession.selectList("test.selectAll"); -
- System.out.println(users);
-
- //4、释放资源
- sqlSession.close();
- }
- }
点击右侧DataBase点击加号,创建一个数据库连接,再点击🖊进行SQL语法编写,代码会自动补全

由于入门案例中的Mybatis简化后仍然存在硬编码问题,代码不灵活,所以使用Mapper代理方式进一步解决硬编码问题


右键单击resources新建文件,文件格式与Mapper接口的包名一致,中间用 / 做分隔符

文件创建成功后,将Mapper映射文件拖入文件夹中

编译Maven项目查看class文件,Mapper接口与映射文件在同一文件夹下

- 包名.类名
- <mapper namespace="com.itheima.mapper.UserMapper">
-
- <select id="selectAll" resultType="com.itheima.pojo.User">
- select * from tb_user;
- select>
-
- mapper>
- public interface UserMapper {
- //定义一个与SQL映射文件id同名的方法
- //返回SQL映射文件中对应的返回值类型,还要根据SQL语义判断具体返回值类型
- List
selectAll(); - }
注意:由于Mapper映射文件位置已经更改,所以在Mybatis核心配置文件中修改映射文件的位置
- <mappers>
-
- <mapper resource="com/itheima/mapper/UserMapper.xml"/>
- mappers>
- //3、执行sql
- //获取UserMapper接口的代理对象
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- List
userList = mapper.selectAll(); -
- System.out.println(userList);

-
- configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
-
-
- <typeAliases>
- <package name="com.itheima.pojo"/>
- typeAliases>
-
-
- <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?useSSL=false"/>
- <property name="username" value="root"/>
- <property name="password" value="12345"/>
- dataSource>
- environment>
- environments>
- <mappers>
-
- <mapper resource="com/itheima/mapper/UserMapper.xml"/>
- mappers>
- configuration>

发现问题:在查询数据并对数据进行输出时发现,从数据库中查找的数据不能很好的封装成User类存储的值是null。

由于数据库中列名为user_name,而User实体类中对应的用户名为userName,两者名称不同对应不上无法自动的封装数据。
三种修改方式:
- <!--
- <!--第一种起别名 缺点:每次查询都要定义一次别名-->
- select
- id, user_name as userName, password, gender, addr
- from tb_user;
- </select>
- <sql id="user_column">
- id, user_name as userName, password, gender, addr
- sql>
-
- <select id="selectAll" resultType="User">
- select
- <include refid="user_column">include>
- from tb_user;
- select>
- <resultMap id="userResultMap" type="user">
-
-
- <result column="user_name" property="username">result>
- resultMap>
-
- <select id="selectAll" resultMap="userResultMap">
-
- select
- *
- from tb_user;
- select>
数据成功封装


- <select id="selectById" resultMap="userResultMap">
- select *
- from tb_user where id = #{id};
- select>
- public interface UserMapper {
- //1、查询所有
- List
selectAll(); -
- //2、查看详情,根据id查询
- User selectById(int id);



多条件查询,传入多个参数有三种传参方式 :
- public interface UserMapper {
- //1、查询所有
- List
selectAll(); -
- //2、查看详情,根据id查询
- User selectById(int id);
-
- //3、多条件查询
- //三种方式的参数接收
- //1、散装参数,存在多个参数使用@Param("占位符名称")注解
- List
selectByFields(@Param("username") String username,@Param("gender") String gender,@Param("addr") String addr);
- <select id="selectByFields" resultMap="userResultMap">
- select
- *
- from tb_user
- where
- user_name = #{username}
- and gender = #{gender}
- and addr like #{addr};
- select>
- //接收参数
- String username = "张三";
- String gender = "男";
- String addr = "徽";
- //处理参数 模糊查询
- addr = "%" + addr;
-
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- List
user = usermapper.selectByFields(username,gender,addr); - System.out.println(user);
- //接口
- // 2、对象参数:传入一个对象,对象的属性名称要与参数占位符名称一致
- List
selectByFields(User user);
- //接收参数
- String username = "张三";
- String gender = "男";
- String addr = "徽";
- //处理参数
- addr = "%" + addr;
-
- //封装对象
- User user = new User();
- user.setUsername(username);
- user.setGender(gender);
- user.setAddr(addr);
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- List
users = usermapper.selectByFields(user);
- //接口
- //3、传入Map集合
- List
selectByFields(Map map);
- //接收参数
- String username = "张三";
- String gender = "男";
- String addr = "徽";
- //处理参数
- addr = "%" + addr;
-
- //添加Map集合
- Map map = new HashMap();
- //键:xml中的占位符名称,值:传入的参数
- map.put("username",username);
- map.put("gender",gender);
- map.put("addr",addr);
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- List
users = usermapper.selectByFields(map);
多条件查询当前存在的弊端:如果用户只输入其中一个数据就进行查询结果会查不到任何数据,所以需要采用动态查询方式

使用if实现动态查询
- <select id="selectByFields" resultMap="userResultMap">
- select
- *
- from tb_user
- where
- /*test中判断的值是传入的占位符的值,判断占位符是否为空字符串或者空字符,不能使用表名*/
- /*多条件的and不能丢*/
- <if test="username != null and username != ''">
- user_name = #{username}
- if>
-
- <if test="gender != null and gender != ''">
- and gender = #{gender}
- if>
-
- <if test="addr != null and addr != ''">
- and addr like #{addr};
- if>
-
- select>
- //接收参数
- String username = "张三";
- String gender = "男";
- String addr = "徽";
- //处理参数
- addr = "%" + addr;
-
- //添加Map集合
- // 只输入两个数据
- Map map = new HashMap();
- //键:xml中的占位符名称,值:传入的参数
- map.put("username",username);
- map.put("gender",gender);
-
- //map.put("addr",addr);
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- List
users = usermapper.selectByFields(map);
当前问题:仅仅使用if语句会有bug,如果多条件查询中,用户没有输入第一个条件,而选择了后面的条件,此时第二条语句就会变成第一条语句使得SQL语句变成了
select * from tb_user where and gender=?解决问题:在where后面加上恒等式1=1,并在每条语句前都加上and就可以解决问题
<select id="selectByFields" resultMap="userResultMap"> select * from tb_user where 1 = 1 /*test中判断的值是传入的占位符的值,判断占位符是否为空字符串或者空字符,不能使用表名*/ /*多条件的and不能丢*/ <if test="username != null and username != ''"> and user_name = #{username} if> <if test="gender != null and gender != ''"> and gender = #{gender} if> <if test="addr != null and addr != ''"> and addr like #{addr}; if> select>
也可以使用Mybatis提供的
标签来代替where语句,满足其中的条件就能执行
<select id="selectByFields" resultMap="userResultMap"> select * from tb_user <where> <if test="username != null and username != ''"> and user_name = #{username} if> <if test="gender != null and gender != ''"> and gender = #{gender} if> <if test="addr != null and addr != ''"> and addr like #{addr}; if> where> select>

使用choose实现单条件动态查询
choose就相当于switch when某个条件成立 执行代码 otherwise相当于default 恒等式
- <select id="selectByFild" resultMap="userResultMap">
- select
- *
- from tb_user
-
- where
- <choose>
-
- <when test="username != null and username != ''">
- user_name = #{username}
- when>
-
- <when test="gender != null and gender != ''">
- gender = #{gender}
- when>
-
- <when test="addr != null and addr != ''">
- addr like #{addr}
- when>
-
- <otherwise>
- 1 = 1
- otherwise>
- choose>
- select>
使用
标签代替where语句,可以省略1=1
- <select id="selectByField" resultMap="userResultMap">
- select
- *
- from tb_user
- <where>
- <choose>
- <when test="username != null and username != ''">
- user_name = #{username}
- when>
-
- <when test="gender != null and gender != ''">
- gender = #{gender}
- when>
-
- <when test="addr != null and addr != ''">
- addr like #{addr}
- when>
-
- choose>
- where>
- select>

- <insert id="add">
- insert
- into tb_user(user_name,password,gender,addr)
- values
- (#{username},#{password},#{gender},#{addr});
- insert>
- //测试类
- //接收参数
- String username = "赵六";
- String password = "123789";
- String gender = "男";
- String addr = "滁州";
-
- User user = new User(username,password,gender,addr);
-
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- usermapper.add(user);
发现问题:代码运行正常,但是数据库中却没有显示添加的数据

解决问题:执行完后需要手动提交事务
//提交事务 sqlSession.commit();可以在建立SqlSession对象时设置自动提交事务
//1、加载mybatis核心配置文件获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2、获取SqlSession对象 //设置参数 true 自动提交事务,默认手动提交 SqlSession sqlSession = sqlSessionFactory.openSession(true);
使用此方式添加数据的缺点: 数据添加后无法通过封装的数据访问到数据库中的id值


只需要对SQL语句设置两个属性就能获取到对应的id值
在Mybatis中useGeneratedKeys属性只针对insert语句生效,默认为false,当设置为true时,表示插入的表以自增列为主键,则允许JDBC自动生成主键(对主键字段对应的实体类属性进行赋值)并可将此主键值返回,前提是主键必须自增。
keyProperty属性中必须填写的是主键字段对应的实体类属性名称,以确保实体类对象通过Mybatis增加到数据库之后得到的id增长值会被设置在实体类对应的属性值上。
- public class User {
- //实体类属性值
- private Integer id;
- private String username;
- private String password;
- private String gender;
- private String addr;
- <insert id="add" useGeneratedKeys="true" keyProperty="id">
- insert
- into tb_user(user_name,password,gender,addr)
- values
- (#{username},#{password},#{gender},#{addr});
- insert>

- <update id="updateAll" >
- update tb_user
- set user_name = #{username},
- password = #{password},
- gender = #{gender},
- addr = #{addr}
- where id = #{id};
- update>
- //接收参数
- String username = "张明杨";
- String password = "124589";
- String gender = "女";
- String addr = "广西";
- Integer id = 7;
-
- //封装新的对象
- User user = new User(id,username,password,gender,addr);
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- int count = usermapper.updateAll(user);
使用Mybatis提供的
只修改部分字段

- <update id="updatePart">
- update tb_user
- <set>
- <if test="username != null and username != ''">
- user_name = #{username},
- if>
-
- <if test="password != null and password != ''">
- password = #{password},
- if>
-
- <if test="gender != null and gender != ''">
- gender = #{gender},
- if>
-
- <if test="addr != null and addr != ''">
- addr = #{addr},
- if>
-
- set>
- where id = #{id};
- update>
- //接收参数
- String username = "张明杨";
- String password = "124589";
- String gender = "女";
- String addr = "广西";
- Integer id = 8;
-
- //封装新的对象
- User user = new User();
- user.setUsername(username);
- //user.setPassword(password);
- //user.setGender(gender);
- user.setId(id);
- user.setAddr(addr);
-
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- int count = usermapper.updatePart(user);
- System.out.println(count);


- //9、批量删除
- //使用@Param注解将这个ids数组命名,传到sql语句中
- int deleteByIds(@Param("ids") int[] ids);
- <delete id="deleteByIds">
- delete from tb_user where id
- in
-
-
- <foreach collection="ids" item="id" separator="," open="(" close=");">
- #{id}
- foreach>
-
- delete>
- //3、获取Mapper接口的代理对象
- UserMapper usermapper = sqlSession.getMapper(UserMapper.class);
-
- //接收参数
- int[] ids = {6};
-
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- int count = usermapper.deleteByIds(ids);
- System.out.println(count);
定义接口时使用注解,注解中写入sql语句

- //注解开发简单SQL语句
- //注解添加数据
- @Insert("insert into tb_user(user_name,password,gender,addr) values (#{username},#{password},#{gender},#{addr})")
- int addAll2(User user);
- //接收参数
- String username = "张三";
- String password = "1221421";
- String gender = "男";
- String addr = "徽";
-
-
- User user = new User(username,password,gender,addr);
- //4、执行接口方法(执行SQL语句) 通过接口方法执行SQL语句
- int count = usermapper.addAll2(user);
-
- sqlSession.commit();
- System.out.println(count);