1.Mybatis 基于java的持久层框架,它的内部封装了JDBC,让开发人员只需要关注SQL语句本身,不需要花费精力在驱动的加载、连接的创建、Statement的创建等复杂的过程。
2.Mybatis 通过 XML 或注解的方式将要执行的各种的 statement 配置起来,并通过 java 对象和 statement 中的 sql 的动态参数进行映射生成最终执行的SQL 语句,最后 由mybatis框架执行SQL,并将结果直接映射为java对象 。
3.采用了 ORM思想 解决了实体类和数据库表映射的问题。对 JDBC进行了封装 ,屏蔽了 JDBCAPI 底层的访问细节,避免我们与 jdbc 的 api 打交道,就能完成对数据的持久化操作。
Mybatis解决的问题
1、数据库连接的创建、释放连接的频繁操作造成资源的浪费从而影响系统的性能。
2、SQL语句编写在代码中,硬编码造成代码不容易维护,实际应用中SQL语句变化的可能性比较大,一旦变动就需要改变java类。
3、使用preparedStatement的时候传递参数使用占位符,也存在硬编码,因为SQL语句变化,必须修改源码。
4、对结果集的解析中也存在硬编码。
动态sql标签: if where (choose when otherwise) set foreach sql
处理特殊字符: <![CDATA[sql]]> 转义符
模糊查询: concat('',#{},'') ${}
目录
1创建maven工程导入
1.1新建工程
1.2pom.xml导入
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--范围test-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
1.3创建实体和Mapper接口
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int userId;
private String username;
private String realname;
public User(String username, String realname) {
this.username = username;
this.realname = realname;
}
}
public interface UserDao {
/**
* 查询
*/
public List<User> findAll();
/**
* 添加
*/
public int addUser(User user);
/**
* 根据账号和密码查询用户信息
* @param username 账号
* @param realname 密码
* 使用@Param为参数起名 那么在映射文件中就可以使用该名称
*/
public User findByUsernameAndPwd(@Param("username") String username, @Param("realname") String realname);
}
1.4创建mybatis的主配置文件
将映射文件注册到mybatis的配置文件中
<mappers>
<mapper resource="mapper/UserMapper.xml" />
</mappers>
<?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" />
<!--数据源的配置:name的值固定 value的值要根据客户自己修改-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!--注册映射文件-->
<mappers>
<!--resource:引用资源文中的映射文件 url:网络上的映射文件-->
<mapper resource="mapper/UserMapper.xml" />
</mappers>
</configuration>
1.5创建映射配置文件
<?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">
<!--namespace:命名空间
必须和dao相同
-->
<mapper namespace="com.dao.UserDao">
<select id="findAll" resultType="com.ykq.entity.User">
select * from tb_user
</select>
<select id="findByUsernameAndPwd" resultType="com.entity.User">
select * from tb_user where username=#{username} and realname=#{realname}
</select>
<!--添加用户
useGeneratedKeys:设置使用生成的主键
keyProperty: 赋值给哪个属性
-->
<insert id="addUser" parameterType="com.entity.User"
useGeneratedKeys="true" keyProperty="userId">
insert into tb_user values(null,#{username},#{realname})
</insert>
</mapper>
根据账号和密码查询用户信息
mybatis默认会把多个参数封装成param1 param2 .......
这种方式名称不见名知意
如果想自己起名称使用@Param
1.6测试
@Test
public void testFindAll() throws Exception{
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsReader);
SqlSession session=factory.openSession();
UserDao userDao=session.getMapper(UserDao.class);//获取接口的映射类
List<User> list = userDao.findAll();
System.out.println(list);
session.commit();
session.close();
}
为实体类起别名
<typeAliases>
<!--单独为某个实体类起别名 -->
<typeAlias type="com.entity.User" alias="u"/>
<!--为指定包下的实体类起别名该别名就是实体类名-->
<package name="com.entity"/>
</typeAliases>
输入映射(传参到sql):
parameterType只能接收一个参数
接收的是基本类型(Integer/String..)的话是可以省略parameterType该属性、若是实体类对象,那么sql中占位符位置必须是实体类中属性。
使用下标方式#{arg0}或#{param1}
public List<User> findByCondition(@Param("name") String name, @Param("email") String email) ;
2.动态sql
set标签
<update id="update">
update account
<set>
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="money!=null">
money=#{money},
</if>
<if test="isdeleted!=null">
isdeleted=#{isdeleted},
</if>
<if test="created!=null">
created=#{created},
</if>
<if test="updated!=null">
updated=#{updated},
</if>
</set>
where id=#{id}
</update>
foreach标签
使用的为数组array 如果你使用的为集合 那么就用list
collection:类型
item:数组中每个元素赋值的变量名
open: 以谁开始
close:以谁结束
separator:分割符
<select id="findByIds" resultType="com.ykq.entity.Account">
select * from account where id in
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
if 语句
<select id="queryUser" parameterType="map" resultType="user">
select * from usr where 1=1
<if test="id != null" >
and id =#{id}
</if>
<if test="username != null" >
and username = #{username}
</if>
</select>
where语句
<select id="queryUser" parameterType="map" resultType="user">
select * from usr
<where>
<if test="id != null" >
id =#{id}
</if>
<if test="username != null" >
and username = #{username}
</if>
</where>
</select>
choose,when,otherwise
<select id="queryUser" parameterType="map" resultType="user">
select * from usr
<where>
<choose>
<when test="id != null" >
id =#{id}
</when>
<when test="username != null" >
and username = #{username}
</when>
<otherwise>
and id= 4
</otherwise>
</choose>
</where>
</select>
删除
<delete id="batchDelete">
<foreach collection="array" item="id" open="delete from account where id in(" close=")" separator=",">
#{id}
</foreach>
</delete>
添加
<insert id="saveBatch">
insert into account(name,isdeleted) values
<foreach collection="list" item="acc" separator=",">
(#{acc.name},#{acc.isdeleted})
</foreach>
</insert>
3. 配置日志文件
添加jar依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
添加日志配置文件
log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
详细日志
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=D:/qy151/log/qy151.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
4.模糊查询
select * from 表名 where 列名 like '%a%'
(1)使用字符串函数 完成拼接 concat
<select id="findByLike" resultType="u">
select * from user where name like concat('%',#{name},'%')
</select>
(2)使用${}
#{} 和 ${}的区别:
#{} : 表示一个占位符,通知Mybatis 使用实际的参数值代替。
并使用 PrepareStatement 对象执行 sql 语句 , #{…} 代替 sql 语句的 “?” 。这个是 Mybatis 中的首选做法,安全迅速
${} : 表示字符串原样替换 ,通知 Mybatis 使用 $ 包含的 “ 字符串 ” 替换所在位置。
使用 Statement 或者 PreparedStatement 把 sql 语句和 ${} 的内容连接起来。 一般用在替换表名,
列名,不同列排序等操作 。
<select id="findByLike" resultType="u">
select * from User where name like '%${name}%'
</select>