1、实现mybatis
官方文档:https://mybatis.org/mybatis-3/zh/getting-started.html
MyBatis 是一款优秀的持久层框架,免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和实体类为数据库中的记录。
创建数据库
CREATE DATABASE `mybatis`;
USE `mybatis`;
CREATE TABLE `user` (
`id` INT(20) NOT NULL AUTO_INCREMENT COMMENT '用户编号', --非空,自增,注释
`name` VARCHAR(30) NOT NULL COMMENT '用户名称',
`pwd` VARCHAR(30) NOT NULL COMMENT '用户密码',
PRIMARY KEY (`id`) --设置主键
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `user`(`name`,`pwd`) VALUE ('a','123'),('b','123')
项目架构如图:
1.1、导入依赖
pom.xml
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
1.2、编写实体类
@Data //使用lombok插件可见不写有参无参构造和get,set方法
public class User {
private int id;
private String name;
private String pwd;
}
1.3、编写核心配置文件
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>
<!--识别JavaBean,如果没有这个,mapper.xml中的传参和返回参数类型要写完整实体类路径-->
<typeAliases>
<package name="pojo"/>
</typeAliases>
<!--配置环境-->
<environments default="development">
<environment id="development">
<!--事务管理-->
<transactionManager type="JDBC"/>
<!--数据库属性,一般另外写一个properties文件存放-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--绑定接口-->
<mappers>
<mapper resource="dao/UserMapper.xml"/>
</mappers>
</configuration>
1.4、编写接口
public interface UserMapper {
List<User> select();
User getUserById(int id);
int insert(User user);
int delete(int id);
int update(User user);
}
1.5、编写xml
Mapper.xml
#{}和${}的区别:#{}可以防止SQL注入
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--绑定对应的mapper接口,命名空间必须是完整路径-->
<mapper namespace="dao.UserMapper">
<!--id 绑定对应接口方法名称,resultType 写对应返回类型-->
<!--如果mybatis-config.cml没有配置<typeAliases>,resultType 写完整路径-->
<select id="select" resultType="User">
select * from user;
</select>
<!--parameterType 写传参类型-->
<select id="getUserById" parameterType="int" resultType="User">
<!--#{}内的字段要和接口参数相同-->
select * from mybatis.user where id=#{id};
</select>
<insert id="insert" parameterType="User">
insert into `user`(`name`,`pwd`) value (#{name},#{pwd})
</insert>
<delete id="delete" parameterType="int">
delete from `user` where `id`=#{id}
</delete>
<update id="update" parameterType="User">
update `user` set `name`=#{name} where `id`=#{id}
</update>
</mapper>
1.6、包装工具类
public class MybatisUtils {
//获取sqlSession对象
public static SqlSession getSqlSession() throws IOException {
//添加mybatis配置文件
String resource = "mybatis-config.xml";
//创建字符输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSession工厂获得sqlSession对象
return sqlSessionFactory.openSession(true);
}
}
1.7、测试
public class MyTest {
@Test
public void test() throws IOException{
//获取session
SqlSession sqlSession = MybatisUtils.getSqlSession();
//获取mapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询
List<User> userList = mapper.select();
for (User u : userList) {
System.out.println(u);
}
//根据ID查询
User user = mapper.getUserById(1);
System.out.println(user);
//openSession()不为true需要事务提交
//sqlSession.commit();
//关闭资源
sqlSession.close();
}
}
注:如运行不通过考虑maven静态资源过滤问题,在pom.xml添加
<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>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
2、Map
parameterType 传参类型可以是map,有很多字段但只需要传少量参数的时候使用。
2.1、编写接口
public interface UserMapper {
//import java.util.Map;
int addUser(Map map);
}
2.2、编写xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--绑定对应的mapper接口-->
<mapper namespace="com.lin.dao.UserMapper">
<insert id="addUser" parameterType="Map">
insert into mybatis.user(name, pwd) value (#{username},#{password})
</insert>
</mapper>
2.3、测试
public class MyTest {
@Test
public void test(){
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("username","hhh");
map.put("password","123456");
mapper.addUser(map);
} catch (IOException e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
}
3、模糊查找
<select id="getUserByName" resultType="User">
select * from mybatis.user where name like "%"#{name}"%";
</select>
4、优化
注意:mybatis-config的属性配置有规定顺序
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
4.1、属性优化
1、db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=true
username=root
password=123456
2、mybatis-config.xml
<!--这句写在最上面-->
<properties resource="db.properties"/>
<dataSource type="POOLED">
<!--改变的地方-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
4.2、别名优化
<typeAliases>
<!--绑定别名-->
<typeAlias type="pojo.User" alias="User"/>
<!--
扫描包,识别到的类型是类名开头小写(也可以是大写)
<package name="pojo"/>
-->
</typeAliases>
4.3、设置优化
<settings>
<!--缓存-->
<setting name="cacheEnabled" value="true"/>
<!--懒加载-->
<setting name="lazyLoadingEnabled" value="false"/>
<!--驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!--日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
4.4、映射器
1、通过xml注册mapper
<mappers>
<mapper resource="com/lin/dao/UserMapper.xml"/>
</mappers>
2、通过类注册
<mappers>
<mapper class="com.lin.dao.UserMapper"/>
</mappers>
3、扫描包
<mappers>
<package name="com.lin.dao"/>
</mappers>
方式2和3需注意:
1、接口和Mapper配置文件必须同名。
2、接口和Mapper配置文件必须在同一包下
5、ResultMap
结果集映射,解决表的字段与实体类的属性名不一致问题,在mapper.xml中的返回类型使用resultMap。
//实体类
public class User {
private int id;
private String name;
private String password;
}
--表
CREATE TABLE `user` (
`id` INT(20) NOT NULL AUTO_INCREMENT COMMENT '用户编号', --非空,自增,注释
`name` VARCHAR(30) NOT NULL COMMENT '用户名称',
`pwd` VARCHAR(30) NOT NULL COMMENT '用户密码',
PRIMARY KEY (`id`) --设置主键
) ENGINE=INNODB DEFAULT CHARSET=utf8
<!--mapper.xml-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lin.dao.UserMapper">
<resultMap id="UserMap" type="User">
<!--column对应表的字段名 property对应实体类的属性名-->
<!--可以只映射不相同的部分-->
<!--<result column="id" property="id"/>
<result column="name" property="name"/>-->
<result column="pwd" property="password"/>
</resultMap>
<select id="select" resultMap="UserMap">
select * from user;
</select>
</mapper>
一般建议名称相同或使用驼峰命名。
6、日志
6.1、标准日志输出
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
6.2、LOG4J
可以控制输出的位置如:控制台,日志文件等
1、导包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2、配置mybatis-config.xml
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
2、配置log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
3、测试
private static Logger logger = Logger.getLogger(Test.class);
@Test
public void Test2() {
// System.out.println("This is println message.");
// 记录debug级别的信息
logger.debug("This is debug message.");
// 记录info级别的信息
logger.info("This is info message.");
// 记录error级别的信息
logger.error("This is error message.");
}
7、分页
7.1、分页的使用
1、接口
public interface UserMapper {
List<User> queryAllUser(Map<String,Integer> map);
}
2、xml
<select id="queryAllUser" resultType="User">
select * from mybatis.user limit #{si},#{ps}
</select>
3、测试
public void Test1() throws IOException {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Integer> map=new HashMap<>();
map.put("si",0);
map.put("ps",10);
List<User> userList = mapper.queryAllUser(map);
for (User u : userList) {
System.out.println(u);
}
}
7.2、RowBounds
@Test
public void Test1() throws IOException {
RowBounds rowBounds = new RowBounds(0, 10);
SqlSession sqlSession = MybatisUtils.getSqlSession();
List<User> list = sqlSession.selectList("dao.UserMapper.queryAllUser",null,rowBounds);
for (User user:list
) {
System.out.println(user);
}
sqlSession.close();
}
8、注解开发
1、编写接口
public interface UserMapper {
@Select("select * from user")
List<User> queryAllUser();
@Select("select * from user where id=#{id}")
User queryUserById(@Param("id") int uid);
@Insert("insert into user(name,pwd) value (#{name},#{pwd})")
int addUser(User user);
@Update("update user set name=#{name} where id=#{id}")
int updateUser(User user);
@Delete("delete from user where id=#{id}")
int deleteUser(@Param("id") int id);
}
2、绑定接口
<mappers>
<mapper class="dao.UserMapper"/>
</mappers>
3、测试
@Test
public void Test() throws IOException {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.queryAllUser();
for (User user:list) {System.out.println(user);}
System.out.println(mapper.queryUserById(1));
mapper.addUser(new User(125,"asd","123456"));
mapper.updateUser(new User(1,"asd","123456"));
mapper.deleteUser(50);
sqlSession.close();
}