提示:这里可以添加本文要记录的大概内容:
一、MyBatis是什么?
持久层(Dao层)框架,优点 1、简单易学灵活 2、sql和代码的分离,提高了可维护性。 3、提供映射标签,支持对象与数据库的orm字段关系映射提供对象关系映射标签,支持对象关系组建维护 4、提供xml标签,支持编写动态sql
二、使用步骤
新建Mavean项目
1.创建数据库文件
CREATE DATABASE `mybatis` ;
use mybatis;
CREATE TABLE `user` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
2.导入依赖
pom.xml文件中
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--junit依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--解决资源无法生效或无法导出-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
3.编写mybatis核心配置文件
在resource文件夹下新建mybatis-config.xml文件,写入
<?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"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jbdc:mysql://localhost:3306/mybatis?useSSL=false&
useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/veterlemon/dao/UserMapper.xml"/>
</mappers>
</configuration>
4.编写mybatis工具类
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
5.编写代码
1、建立pojo的实体类
public class User {
private int id;
private String name;
private String pwd;
public User() { }
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPwd() { return pwd; }
public void setPwd(String pwd) { this.pwd = pwd; }
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
2、在Dao层创建对应Mapper类 (实际上是讲原本的接口类(Dao类)转变成Mapper类)
public interface UserMapper {
List<User> getUserList();
}
3、为Dao类创建Mapper.xml文件,并进行配置 (实际上是将原本的接口实现类(DapImpl)转变成Mapper配置文件)
<?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接口-->
<mapper namespace="com.veterlemon.dao.UserMapper">
<!--select查询语句;id对应Dao内的方法名;resultType/resultMap表示sql语句执行后返回的一个/多个结果集-->
<select id="getUserList" resultType="com.veterlemon.pojo.User">
<!--sql语句-->
select * from mybatis.user
</select>
</mapper>
6.测试
使用junit进行测试,建议test下的java包与main下的java包保持一致
public class UserDaoTest {
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e){
e.printStackTrace();
} finally {
sqlSession.close();
}
}
}
三、MyBatis的CRUD
在mybatis环境下添加查询方法,步骤: 先在Mapper类中新增方法,再去对应的Mapper.xml文件中绑定新增方法并编写sql
1.操作Dao层的UserMapper类
在Dao包下的UserMapper类中添加新的查询方法
public interface UserMapper {
List<User> getUserList();
User getUserById(int id);
int insertUser(User user);
int updateUser(User user);
int deleteUser(int id);
List<User> getUserLike(String name);
}
2.操作对应Dao层的Mapper.xml文件
<!--parameterType="com.veterlemon.pojo.User",可以直接取到类中对象的属性-->
<?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.veterlemon.dao.UserMapper">
<select id="getUserList" resultType="com.veterlemon.pojo.User">
select * from mybatis.user
</select>
<select id="getUserById" parameterType="int" resultType="com.veterlemon.pojo.User">
select * from mybatis.user where id = #{id};
</select>
<insert id="insertUser" parameterType="com.veterlemon.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
</insert>
<update id="updateUser" parameterType="com.veterlemon.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id}
</delete>
<select id="getUserLike" resultType="com.veterlemon.pojo.User">
select * from mybatis.user where name like "%"#{name}"%";
</select>
</mapper>
3.进行测试
增删改操作需要提交事务
public class UserDaoTest {
@Test
public void getUserList_Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
try {
UserMapper userDao = sqlSession.getMapper(UserMapper.class);
List<User> userList = userDao.getUserList();
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e){
e.printStackTrace();
} finally {
sqlSession.close();
}
}
@Test
public void getUserById_Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void insertUser_Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int result = mapper.insertUser(new User(4, "张三", "1555"));
if (result > 0){
System.out.println("用户添加成功");
}else {
System.out.println("用户添加失败");
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser_Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int result = mapper.updateUser(new User(4, "李白", "123"));
if (result > 0){
System.out.println("用户修改成功");
}else {
System.out.println("用户修改失败");
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser_Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int result = mapper.deleteUser(4);
if (result > 0){
System.out.println("用户删除成功");
}else {
System.out.println("用户删除失败");
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void getUserLike(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserLike("李");
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
4.用Map改良Mapper(注解更佳)
当实体类或数据库的表中参数或字段过多时,应该考虑用Map来优化,以便减少不必要的操作 优化Mapper
int insertUserMap(Map<String, Object> map);
<!--属于优化Map操作的语句,传递过来的是map的key,所以可以自定义-->
<insert id="insertUserMap" parameterType="map">
insert into mybatis.user (id, name, pwd) values (#{user_id},#{username},#{password});
</insert>
@Test
public void insertUserMap_Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("user_id", 6);
map.put("username", "李逵");
map.put("password", "321");
int result = mapper.insertUserMap(map);
if (result > 0){
System.out.println("Map优化之用户添加成功");
}else {
System.out.println("Map优化之用户添加失败");
}
sqlSession.commit();
sqlSession.close();
}
四、MyBatis的配置解析
mybatis-config.xml内的
1.环境、事务管理器、数据源
<environments default="development">
<!--可以有多个environment,由最外层的default选中-->
<environment id="development">
<!--事务管理器,有JDBC和MANAGED两种-->
<transactionManager type="JDBC"/>
<!--数据源,有unpooled、pooled、judi三种-->
<dataSource type="POOLED">
<!--属性,通过property的属性实现引用配置文件-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
2.属性
properties,作用:引入外部配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=UTF-8
username=root
password=123456
<?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>
<!--引入外部配置文件-->
<properties resource="db.properties">
<!--也可以将dp.properties的属性写到这-->
<!--使用顺序:先使用properties内部的,然后去读外部文件,若外部文件有重复的属性,则覆盖内部的-->
<property name="password" value="1111"/>
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--为每一个Mapper配置文件注册-->
<mappers>
<mapper resource="com/veterlemon/dao/UserMapper.xml"/>
</mappers>
</configuration>
3.类型别名
typeAliases,减少类名完全限定名的冗余 (当实体类多时,建议使用形式二或注解)
//mybatis-config.xml文件中
<typeAliases>
<typeAlias type="com.veterlemon.pojo.User" alias="User"/>
<package name="com.veterlemon.pojo"/>
</typeAliases>
//对应的UserMapper.xml文件中
<select id="getUserList" resultType="User">
select * from mybatis.user
</select>
<select id="getUserById" parameterType="int" resultType="user">
select * from mybatis.user where id = #{id};
</select>
4.★★设置★★
settings,非常重要
mapUnderscoreToCamelCase,是否开启自动驼峰命名规则映射
loglmpl,指定MyBatis所用日志的具体实现,未指定时将自动查找
5.映射器
mappers,作用:为每个Mapper类绑定注册
<mappers>
<mapper resource="com/veterlemon/dao/UserMapper.xml"/>
<mapper class="com.veterlemon.dao.UserMapper"/>
<package name="com.veterlemon.dao"/>
</mappers>
五、生命周期和作用域
错误的使用会导致严重的【并发问题】
1.SqlSessionFactoryBuilder
一旦创建了SqlSessionFactory就不需要SqlSessionFactoryBuilder了,故应设为局部变量
2.SqlSessionFactory
可以理解为数据库连接池,一旦创建就一直存在,不需要重复创建,应该设为全局变量
3.SqlSession
一个连接数据库连接池的请求,线程不安全所以用完之后必须要关闭
六、解决属性名与字段名不一致问题
当数据库【表中的字段】与【实体类中定义的变量名】不一致时,可能会导致该不一致的属性无法被获取,如下: 表字段 实体类
解决1:起别名
通过类型处理器,在对应的Mapper.xml中修改sql
<select id="getUserById" resultType="User">
select id,name,pwd from mybatis.user where id= #{id}
</select>
解决2:使用resultMap
简单的使用,当表存在一对多、多对多等关系时,需要使用resultMap的高级技巧
<resultMap id="UserMap" type="User">
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserById" resultMap="UserMap">
select * from mybatis.user where id= #{id}
</select>
七、日志
1.LOG4J
在mybatis-config.xml中开启日志
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
在pom.xml中导包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
再resource包下新建log4j.properties文件,写入
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=./log/veterlemon.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
简单使用
public class UserDaoTest {
static Logger logger = Logger.getLogger(UserDaoTest.class);
@Test
public void getUserList_Test() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
logger.info("测试,成功进入getUserList_Test()方法");
UserMapper userDao = sqlSession.getMapper(UserMapper.class);
User user = userDao.getUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void Log4j_Test(){
logger.info("info:进入了log4j_test");
logger.debug("debug:进入了log4j_test");
logger.error("error:进入了log4j_test");
}
}
2.STDOUT_LOGGING
在mybatis-config.xml中开启日志
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
|