思路流程:搭建环境–>导入Mybatis—>编写代码—>测试
1.搭建实验数据库mybatis,新建一张usr表
2.在pom.xml导入依赖
<dependencies> <!--mybatis相关--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version> </dependency> <!--mysql相关--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> </dependencies> <!--配置Maven静态资源过滤问题--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>2.写对应数据库的实体类com.tong.pojo包下的User
@Data public class User { private int id; //id private String name; //姓名 private String pwd; //密码 }3.创建包com.tong.dao中写UserMapper的接口
public interface UserMapper { //查询所有 public List<User> selectUser(); }4.在com.tong.dao下写对应的UserMapper.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"> <mapper namespace="com.tong.dao.UserMapper"> <select id="selectUser" resultType="com.tong.pojo.User"> select * from user </select> </mapper>5.在resources目录下新建mybatis-config.xml配置文件,编写mybatis的配置
<?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> <!--自定义别名,这样在mapper.xml中的这样写resultType="Student 如果没有自定义别名,在mapper.xml 中要写完包名 resultType="com.kuang.pojo.Student --> <typeAliases> <package name="com.tong.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://127.0.0.1:3306/mybatis?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--注册映射文件 1--> <!-- <mappers> <mapper class="com.tong.dao.UserMapper"/> </mappers>--> <!--注册映射文件 2--> <mappers> <mapper resource="com/tong/dao/UserMapper.xml"/> </mappers> </configuration>6.写一个测试类
@Test public void test() throws IOException { //读取mybaits的配置文件 String resource = "mybatis-config.xml"; InputStream in =Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //获得SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); //获得对应的类 StudentMapper mapper = sqlSession.getMapper(UserMapper.class); //执行的方法 List<User> users = mapper.selectUser(); users.forEach(System.out::println); }执行流程:idea要打断点通过debug方式启动才看得到
1.Resources加载mybaits.xml的配置文件------>
2.实例化SqlSessionFactoryBuilder().build()------>
3.XMLConfigBuilder 解析mybatis.xml里面的配置 ------>
4.把配置信息存放到Configuration中------>
5.实例化SqlSessionFactory------>
6.由TransactionFactory创建一个Transaction事务对象------>
7.创建执行器Excutor------>
8.创建SqlSession接口------>
9.实现CRUD,如果执行成功就提交事务,失败就回滚到Transaction------>关闭
1.导入log4j的依赖
<!--日志--> <dependency> <groupId>slog4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>2.在resources目录中创建log4j.properties,并添加内容
##通过配置只查看com.kuang的namespace下的sql语句的日子 log4j.logger.com.kuang.dao=debug,console #控制台附加器 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern= [%-5p][%d{yyyy-MM-dd HH:mm:ss}]%m%n3.在mybatis-config.xml中添加属性,要注意按顺序
<!--要注意按顺序--> <settings > <setting name="logImpl" value="LOG4J" /> </settings>MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
二级缓存需要手动开启和配置,他是基于namespace级别的缓存
一级缓存只存在一个SqlSession里面,并且只有查询的时候才生效,session.close()的时候失效
一级缓存失效的四种情况
一级缓存是SqlSession级别的缓存,是一直开启的,我们关闭不了它增删改都会是刷新缓存注意:如果要使用二级缓存,实体类要序列号,不然会报错
用户-------->二级缓存-------->一级缓存-------->数据库
在字段比较多的时候用map非常方便
接口中
//万能的map int addUser(Map<String, Object> map);xml中
<!--用map类型,对象的属性可以直接取出来,传递map的key, values后面可自定义名字,无需完全匹配数据库,对应参数中map的key --> <insert id="addUser" parameterType="map"> insert into mybatis.user (id,name,password) values (#{id},#{username},#{password}); </insert> 测试 //添加 @Test public void addUser1() { SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); Map<String, Object> map = new HashMap<String, Object>(); map.put("id", 1); map.put("username", "马云"); map.put("password", "666666"); mapper.addUser(map); sqlSession.commit();//提交事务 sqlSession.close();//关闭连接 }可以使用list,也可以使用map:
方式一:使用list
方式二:使用map
接口中 //方式一:list //批量添加 int insertUser_piliang(List<Map<String,Object>> list); //方式二:map //批量添加 int insertUser_piliang2(Map map); mapper.xml中 <!-- 方式一:list --> <insert id="insertUser_piliang" parameterType="java.util.List"> insert into user(name,pwd) values <foreach collection="list" index="index" item="item" separator=","> (#{item.name},#{item.pwd}) </foreach> </insert> <!-- 方式二:map --> <insert id="insertUser_piliang2" parameterType="map"> insert into user(name,pwd) values <!-- collection:指定输入对象中的集合属性 item:每次遍历生成的对象 open:开始遍历时的拼接字符串 close:结束时拼接的字符串 separator:遍历对象之间需要拼接的字符串 --> <foreach collection="list" index="index" item="item" separator=","> (#{item.name},#{item.pwd}) </foreach> </insert> 测试 //方式一:list @Test public void insertUser_piliang(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); ArrayList<Map<String,Object>> list = new ArrayList<>(); HashMap<String, Object> map = new HashMap<>(); for (int i = 0; i < 10; i++) { map.put("name", "邓紫棋"); map.put("pwd", "666666"); list.add(map); } mapper.insertUser_piliang(list); sqlSession.commit(); sqlSession.close(); } //方式二:map @Test public void insertUser_piliang2(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<>(); List<User> list = new ArrayList<>(); User user = new User(); //用for循环遍历添加100个User for (int i = 0; i < 100; i++) { user.setName("马云"); user.setPwd("888888"); list.add(user); } map.put("list", list); mapper.insertUser_piliang2(map); sqlSession.commit();//手动提交事务 sqlSession.close(); }需求:根据用户名和密码查询,如果用户名为空,就根据密码查询,反之,密码为空,则根据用户名查询
接口 List<User> queryUserIf(Map map); xml <select id="queryUserIf" parameterType="map" resultType="User"> select * from user <where> <if test="name != null"> name=#{name} </if> <if test="pwd != null"> and pwd=#{pwd} </if> </where> </select>这个 标签会知道如果它包含的标签中有返回值的话,它就插入一个 。此外,如果标签返 回的内容是以AND 或OR 开头的,则它会剔除掉。就是当name 的值为空时,会剔除掉and,有些案例直接用1=1
替换掉 ,但这是不安全的,存在sql注入问题。
测试 //if查询 @Test public void queryUser(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); HashMap<String, Object> map = new HashMap<>(); map.put("name", "李四"); map.put("pwd", "888888"); List<User> users = mapper.queryUserIf(map); users.forEach(System.out::println); }有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句
接口 //choose List<User> queryUserChoose(Map map); xml <select id="queryUserChoose" resultType="User" parameterType="map"> select * from user <where> <choose> <when test="name != null"> name=#{name} </when> <when test="pwd != null"> and pwd=#{pwd} </when> <otherwise> and id=#{id} </otherwise> </choose> </where> </select> 测试 测试结果:如果map中都没有值时,以id为主,如果name中有值,就以name为主查询,不关pwd的事 //choose查询 @Test public void queryUserChoose(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); HashMap<String, Object> map = new HashMap<>(); map.put("name", "张三"); map.put("pwd", "888888"); map.put("id",2); //这是固定的,一定要有这个值 List<User> users = mapper.queryUserChoose(map); users.forEach(System.out::println); }转载csdn:https://blog.csdn.net/Crystalqy/article/details/79419244
常用的模糊查询有三种方法:**
直接使用 % 拼接字符串,如 '%'#{name}'%' 或 "%"#{name}"%",单引号或双引号都可以。使用concat(str1,str2)函数拼接使用mybatis的bind标签 <!-- ******************** 模糊查询的常用的3种方式:********************* --> <select id="getUsersByFuzzyQuery" parameterType="User" resultType="User"> select * from users <where> <!-- 方法一: 直接使用 % 拼接字符串 注意:此处不能写成 "%#{name}%" ,#{name}就成了字符串的一部分, 会发生这样一个异常: The error occurred while setting parameters, 应该写成: "%"#{name}"%",即#{name}是一个整体,前后加上% --> <if test="name != null"> name like "%"#{name}"%" </if> <!--方法二: 使用concat(str1,str2)函数将两个参数连接 --> <if test="phone != null"> and phone like concat(concat('%',#{phone}),'%') </if> <!--方法三: 使用 bind 标签,对字符串进行绑定,然后对绑定后的字符串使用 like 关键字进行模糊查询 --> <if test="email != null"> <bind name="pattern" value="'%'+email+'%'"/> and email like #{pattern} </if> </where> </select>需求:查询学生的名字以及对应的老师的名字
多对一的理解:
多个学生对应一个老师需求:获取指定老师,及老师下的所有学生
一对多的理解:
一个老师拥有多个学生使用mybatis时,增删改查都需要提交事务,否则运行成功并没有添加到数据库
可以手动提交事务,也可以在openSession()是设置为true,此时不用每次都手动提交了
这是在自定义的MybatisUtil工具包中
//获取SqlSession连接 public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(true);//设置为true }