MyBatis_02 日志、全局配置、CRUD

一、配置日志(LOG4J)

使用日志可以监控SQL的执行情况,目前日志框架也非常成熟,如log4j。

1、加入依赖

<!--log4j-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2、加入配置文件,名称必须为:log4j.properties。(可以去网上拷贝一个

模板)

log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p - %m%n
log4j.logger.org.apache=INFO

3、效果

在这里插入图片描述

二、全局配置(mybatis-config.xml)

1、配置文件头(固定写法,建议不要手写,从官网拷贝,或自己保存为一个模板,其中dtd为标签约束文 件,当电脑联网会自动下载,否则没有提示)

<?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">

2、configuration

<configuration>
<!-- configuration:配置,所有的配置必须在该标签中  -->
</configuration>

3、configuration标签下子标签的顺序

properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers
如果不按这个顺序编写会出现以下报错
在这里插入图片描述

3、properties:配置全局参数

<!-- 配置全局参数 -->
    <properties resource="h2jdbc.properties"/>

4、settings:设置选项

<settings>
	<!-- 是否开启驼峰命名 -->
	<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

其它设置参考官网文档
mybatis的setting
settings 的配置项很多,但是真正用到的不会太多,我们把常用的配置项研究清楚就可以了,比如关于缓存的 cacheEnabled,关于级联的lazyLoadingEnabled 和 aggressiveLazy Loading,关于自动映射的autoMappingBehavior和mapUnderscoreToCamelCase,关于执行器类型的defaultExecutorType 等。

5、typeAliases:别名设置

<!--别名设置-->
<typeAliases>
    <!-- 设置单个别名 -->
     <typeAlias type="org.example.entity.Student" alias="Student"/>
    <!-- 设置批量别名 -->
    <!--<package name="org.example.entity"/>-->
</typeAliases>
注意:
  • 不管是通过 typeAlias 标签配置,还是通过package 标签配置的别名,在mapper.xml文件中使用的时候,是可以忽略大小写的。
  • 如果不手动设置别名,默认是类名的小写。
  • 如果配置了注解别名,注解别名会覆盖上面的所有配置。
@Alias("stu")
public class Student {
 ...
}

6、environments

环境列表,表示在该标签下,可以配置多个environment标签,default可以指定一个默认环境。 使用场景:例如配置两个environment,一个为开发环境,一个为上线环境,开发时使用mysql,上线时使 用oracle。这样不用改变明细代码,而只用改变default就可以随意切换,非常方便。

<environments default="dev">
	<environment id="dev">
		<!--事务管理器配置-->
		<transactionManager type="JDBC"/>
		<!--数据源的配置-->
		<dataSource type="POOLED">
			<property name="driver" value="${h2jdbc.driver}"/>
			<property name="url" value="${h2jdbc.url}"/>
			<property name="username" value="${h2jdbc.username}"/>
			<property name="password" value="${h2jdbc.password}"/>
		</dataSource>
	</environment>
</environments>
  • <environment id="development">
    环境配置标签,id为该环境的唯一标识符
  • <transactionManager type="JDBC" />
    事务管理器配置,type="JDBC"表示使用JDBC自带的事务管理器,“JDBC”表示事务管理器的一个实 例,这里使用默认值即可。
  • <dataSource type="POOLED">
    数据源的配置,这里可以配置三种选项:
    • UNPOOLED:不使用连接池技术
    • POOLED:使用连接池技术
    • JNDI:使用JNDI的方式

7、mappers:映射器

1、概念
  • 映射器是MyBatis最复杂、最核心的组件。
  • 映射器提供DAO层接口到mapper.xml文件的映射,我们只需要调用DAO层的方法,就可以以执行对应的SQL语句,这里用到的是java的动态代理特性。
  • mappers:配置mapper列表,专门放置我们写好的xxxMapper.xml配置文件。
  • mapper:resource指定xxxMapper.xml配置文件的所在路径。
2、配置映射器
<!-- 配置mappers -->
<mappers>
    <!-- 配置单个mapper,指定文件路径
    resource:指定类路径下的映射文件路径
    -->
    <!--<mapper resource="StudentMapper.xml" />-->

    <!-- 使用类名注册
    1、指定xxxMapper映射接口的类路径
    2、xxxMapper.xml文件要和映射接口在同一目录,且名称要保持一致。
    3、没有sql映射文件,所有sql通过注解写在接口中。
    -->
    <!-- <mapper class="org.example.mapper.StudentMapper"/> -->

    <!-- 批量注册:指定包名,全包扫描,但xml映射文件要和映射接口放在同一包下 -->
    <package name="org.example.mapper"/>
</mappers>
3、使用注解配置(不需要sql映射文件)
public interface StudentMapper {
	//根据id查询学生
	@Select("select * from student where id=#{id}")
	Student findById(Integer id);
}
注意:
  • 注解虽然使用方便,但并不推荐,毕竟SQL写在代码中,产生了高耦合,维护起来不方便。
  • 实际开发中,也可以混合使用,重要的复杂的写在xml中,不重要的简单的可以使用注解。
4、批量注册

批量注册:指定包名,全包扫描,但xml映射文件要和映射接口放在同一包下

<package name="org.example.mapper"/>

在这里插入图片描述
我们通常可以在资源包下,创建一个和映射接口一模一样的文件。

三、增删改查

增删改查的接口定义方法和映射配置如下:

1、CRUD
1、insert --映射插入语句

接口(StudentMapper.java):

//新增学生
int insert(Student stu);

xml(StudentMapper.xml)

<!--新增学生-->
<insert id="insert" parameterType="Student">
    insert into student values(null,#{name},#{age},#{email})
</insert>
2、delete – 映射删除语句

接口(StudentMapper.java):

//删除学生
Boolean delete(Integer id);

xml(StudentMapper.xml)

<!--删除学生-->
<delete id="delete" parameterType="Integer">
    delete from student where id=#{id}
</delete>
3、update --映射更新语句

接口(StudentMapper.java):

//更新学生
Boolean update(Student stu);

xml(StudentMapper.xml)

<!--更新学生-->
<update id="update" parameterType="Student">
    update student set name=#{name},age=#{age},email=#{email} where id=#{id}
</update>
4、select – 映射查询语句

接口(StudentMapper.java):

//根据id查询学生
Student getStuById(Integer id);

xml(StudentMapper.xml)

<!--根据id查询学生-->
<select id="getStuById" resultType="Student">
     select id,name,age,email from student where id  = #{id}
 </select>
2、注意事项

1)parameterType(参数类型)可以省略,resultType(返回类型)不能省略。
2)mybatis允许增删改直接定义以下类型返回值

  • 只需要在接口上设置返回值类型,mybatis就可以自动为我们返回相应类型的执行结果。
  • Integer、Long、Boolean、void包装类和基本类型都。

3)事务提交

  • SqlSession默认是手动提交事务,如需自动提交,在参数中设置true。
  • sqlSessionFactory().openSession()—>手动提交事务
  • sqlSessionFactory().openSession(true)—>自动提交事务

4)获取添加操作后的主键值
在映射配置中增加:

  • useGeneratedKeys=“true”:使用自增主键获取主键策略
  • keyProperty=“id”:指定对应的主键属性,也就是mybatis获取到主键值后,将这个值放到JavaBean的
    哪个属性中。

例如:

<!--新增学生。添加后返回记录的id需配置useGeneratedKeys="true" keyProperty="id"-->
<insert id="insert" parameterType="Student" useGeneratedKeys="true" keyProperty="id">
    insert into student values(null,#{name},#{age},#{email})
</insert>

四、注解

在Mapper接口中,可以使用Annotation完成SQL映射

1、@Select

相当于<select>元素

@Select("select * from student")
List<Student> list();
2、@Insert

相当于<insert>元素

@Insert("insert into student values(#{id},#{name},#{age},#{email})")
int insert2(Student stu);

如果要获取主键id,可以使用@Option注解

@Insert("insert into student values(#{id},#{name},#{age},#{email})")
@Options(useGeneratedKeys = true,keyColumn = "id",keyProperty = "id")
int insert2(Student stu);
3、@Delete

相当于<delete>元素

//删除学生2
@Delete("delete from student where id = #{id}")
boolean delete2(Integer id);
4、@Update

相当于<update>元素

@Update("update student set name=#{name},age=#{age},email=#{email} where id=#{id}")
int update2(Student stu);
5、什么时候用注解?

通常情况下,如果比较简单的SQL,可以使用注解,如果比较复杂,还是建议写到配置文件中。在开发的时候,也可以使用注解+配置文件的混合方式。

五、映射配置

1、单个参数

mybatis不会做任何处理,使用#{参数名}的方式即可,且参数名没有要求。 也就是#{}中的参数既可以写id,也可以写其它名称。

<select id="getStuById" resultType="Student">
    select id,name,age,email from student where id  = #{id}
</select>
2、多个参数

1)有多个参数的时候,用上述方法就会抛出异常:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]

2)当有多个参数的时候,mybatis会做特殊处理,把参数封装到一个Map中,key为param+下标的方式:param1,param2,…,#{param1},#{param2}

<select id="findByMap" resultType="Student">
  select id,name,age,email
    from student
    where id=#{param1} and name=#{param2}
</select>

3)使用注解
当参数很多,上述处理容易写错,也不方便,我们希望和接口中定义的方法参数名保持一致,可以在接口参数前使用注解:@param

Student findByIdAndName(@Param("id") Integer id, @Param("name") String name);

在映射配置中和注解的名称对应起来:

<select id="findByMap" resultType="Student">
    select id,name,age,email
    from student
    where id=#{id} and name=#{name}
</select>
3、对象参数

如果多个参数正好和我们的实体类对应,我们就可以直接传入对象。
#{属性名}:取出传入pojo的属性值

4、Map参数

如果多个参数和我们的实体类不对应,为了方便,我们也可以传入Map类型。
#{key}:取出map中对应的值
接口:

Student findByMap(Map<String, Object> map);

映射配置:

<select id="findByMap" resultType="Student">
    select id,name,age,email
    from student
    where id=#{id} and name=#{name}
</select>

测试:

/**
 * 测试findByMap
 */
@Test
public void testFindByMap(){
    SqlSession session = sqlSessionFactory.openSession();
    try{
        //获取Mapper对象
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        //调用对象的方法
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", "8");
        map.put("name", "老狗");
        Student stu = mapper.findByMap(map);
        //打印
        System.out.println(stu);
    }finally{
        session.close();
    }
}
5、Collection作为参数

如果参数类型是集合,例如List、Set、数组(Array),也会进行特殊处理,mybatis会对List进行Map封 装,需要使用key来获取,此处可以使用三种key:

  • #{arg0[index]}
  • #{collection[index]}
  • #{list[index]}

如果是数组:#{array[index]}

6、#{}和${}的区别
  • #{}:以预编译的形式,将参数设置到sql语句中,相当于PreparedStatment,防止SQL注入
  • ${}:取出的值直接拼接在sql语句中,相当于Statment,会有安全问题

通常情况下,我们会使用#{}居多,不过在SQL中需要拼接时,就会用到${}的方式。

例如:我们以下列代码为例,id使用${}的方式获取,name使用#{}的方式获取

<select id="findByIdAndName" resultType="Student">
    select id,name,age,email
    from student
    where id=${id} and name=#{name}
</select>

运行测试类,我们看控制台的输出结果:
在这里插入图片描述

六、返回类型的处理

1、查询返回List

注意:在映射配置中,返回类型依然是集合中对象的类型,而非List

<!--模糊查询List<Student> findByLike(String str);-->
<select id="findByLike" resultType="com.turing.entity.Student">
	select id,name,age,email
	from student
	where name like #{str}
</select>
2、查询返回Map

注意:在映射配置中,返回类型如果是Map,类型写map即可。

<!--根据id查询学生对象,返回Map
Map<String, Object> findById2(int id);
-->
<select id="findByLike2" resultType="map">
    select id,name,age,email
    from student
    where name like #{str}
</select>
3、多条记录封装成一个Map

例如:Map<Integer,Student>:key是记录中的主键,value是学生对象。
接口:

@MapKey("id")把id作为返回值map的key
Map<String, Student> findByLike3(String str);

映射文件:

<select id="findByLike3" resultType="Student">
    select id,name,age,email
    from student
    where name like #{str}
</select>

测试类:

@Test
public void testFindByLike3(){
    SqlSession session = sqlSessionFactory.openSession();
    try{
        //获取Mapper对象
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        //调用对象的方法
        Map<String, Student> map = mapper.findByLike3("%老%");
        //打印
        System.out.println(map);
    }finally{
        session.close();
    }
}

完整代码

代码已托管在gitee上面,点击直达

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值