一 MyBatis框架
1 框架介绍
框架:对基础代码进行封装并提供相应的API,调用API可省去一些代码的编写,从而提高效率。一个好的框架一定是经过测试,自身的功能已经实现,可以完成特定的功能。
2 MyBatis 框架
MyBatis 框架是一款持久层框架,他集成了绝大部分的JDBC代码与手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的domain对象,支持自定义sql,存储过程与高级映射
Mybatis的功能架构分为三层:
API接口层:提供给外部使用的接口API,通过这些本地API可操纵数据库。接口层接收到调用请求就会调用数据处理层完成具体的数据处理。
数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
基础支撑层:负责最基础的功能支撑,即连接管理、事务管理、配置加载和缓存处理,将这些共用的东西抽取出来作为最基础的组件。为上层提供最基础的支撑(数据处理层)
3 使用流程
① 编写 mybatis-config.xml 文件:配置连接数据的四要素(数据源),以及项目需要依赖的通用配置
② 编写 XxxMapper.xml文件:映射文件,编写SQL语句和类型映射
③ MyBatis 加载配置文件,创建SqlSessionFactory 对象(类似连接池)
④ 通过SqlSessionFactory来生产SqlSesson 对象 SqlSesson(类似 Connection连接对象)
⑤ 使用SqlSession即可执行CRUD操作
⑤ mybatis底层会进行数据处理,SQL执行以及结果集的处理
4 准备环境与测试
① 添加项目需要的 jar 包,或者导入对应的依赖
Lombok,可自动生成getter/setter/toString等方法
mysql-connector-java-5.1.36-bin.jar,Java语言连接MySQL数据库的驱动包,它提供了一系列的类和方法,可以用来执行创建和查询数据库、插入和更新数据、管理用户和权限等任务
mybatis-3.4.6.jar,MyBatis框架的核心包,它提供了一系列的类和方法,用于对数据库进行操作。MyBatis框架是一个持久层框架,它可以通过配置文件和映射文件来将SQL语句映射到Java对象,从而简化了数据库的操作。
② 数据库表
CREATE TABLE `t_employee` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`eid` varchar(10) NOT NULL,`ename` varchar(6) NOT NULL,`job` varchar(10) DEFAULT NULL,`salary` int(10) DEFAULT NULL,`password` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `eid` (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
③ 实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {private Long id;private String eid;private String ename;private String password;private String job;private Integer salary;
}
④ resources下编写主配置文件:mybatis-config.xml,拷贝xml约束,添加环境配置(事物管理器,连接池,映射文件),在此还需要关联映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--配置日志--><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><!--配置数据库连接信息--><environments default="dev"><environment id="dev"><!--配置事务管理模式--><transactionManager type="JDBC"></transactionManager><!--配置数据源信息--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///web_crud"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!--加载映射文件--><mappers><mapper resource="mappers/EmployeeMapper.xml"></mapper><!--扫描映射文件所在的包路径:mapper映射文件和mapper接口的路径需要保持一致,mapper路径需通过/分隔--></mappers>
</configuration>
⑤ 于mapper目录中,编写对应的mapper文件,拷贝约束信息,编写SQL语句,一个项目可以操作多张表,每张表都需要一个mapper配置文件来编写SQL语句每条SQL语句都需要有一个唯一的标识,这个唯一的标识由 namespace+sqlid 组成
使用namespace+sqlid就得到了保存用户信息的唯一标识,如:cn.tj.mybatis.mapper.EmployeeMapper.insert 之后可以通过标识找到这条SQL语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace用来区别项目下的多个文件的标识-->
<mapper namespace="employee"><!--增加用户:id当前文件中sql标签的唯一标识--><insert id="insertEmployee">insert into t_employee(eid,ename,job,salary,password) values(#{eid},#{ename},#{job},#{salary},#{password})</insert>
</mapper>
⑥ 接口
public interface EmployeeDao {//增加员工void insertEmployee(Employee employee);
}
⑦ 实现类
public class EmployeeDaoImpl implements EmployeeDao {@Overridepublic void insertEmployee(Employee employee) {try {//1.加载配置文件信息InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rs);//2.创建sqlSession//openSession()默认的时候是需要手动提交事务,如果设置自动提交事务需要参数设置为trueSqlSession sqlSession = factory.openSession(true);//3.执行增加操作sqlSession.insert("employee.insertEmployee",employee);//手动提交事务//sqlSession.commit();//4.关闭对象sqlSession.close();} catch (IOException e) {e.printStackTrace();}}
}
⑧ 测试类
public class EmployeeTest {/*增加用户测试*/@Testpublic void employee_insert(){EmployeeDao employeeDao=new EmployeeDaoImpl();Employee employee = new Employee(null, "tj012", "大黄", "123", "BA", 18000);employeeDao.insertEmployee(employee);System.out.println("增加用户成功");}
}
二 代码重构
通过代码实现对员工表的基础增删改查
1 实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {private Long id;private String eid;private String ename;private String password;private String job;private Integer salary;
}
2 mybatis-config.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--加载外部配置文件--><properties resource="db.properties"></properties><!--类型别名--><typeAliases><!--一个实体类对应一个别名,映射文件中的resultType属性可以将路径缩写--><!--<typeAlias type="cn.tj.mybatis.domain.Employee" alias="employee"></typeAlias>--><!--扫描实体类所在的包路径将实体类全部起别名:别名默认是实体类名称 不区分大小写--><package name="cn.tj.mybatis.domain"/></typeAliases><!--配置数据库连接信息--><environments default="dev"><environment id="dev"><!--配置事务管理模式--><transactionManager type="JDBC"></transactionManager><!--配置数据源信息--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.user}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--加载映射文件--><mappers><mapper resource="mappers/EmployeeMapper.xml"></mapper></mappers>
</configuration>
3 mapper映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace用来区别项目下的多个文件的标识-->
<mapper namespace="cn.tj.mybatis.mapper.EmployeeMapper"><!--增加员工:id当前文件中sql标签的唯一标识--><insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">insert into t_employee(eid,ename,password,job,salary) values(#{eid},#{ename},#{password},#{job},#{salary})</insert><!--修改员工--><update id="updateEmployee">update t_employee set eid=#{eid} ,ename=#{ename} ,password=#{password} ,job=#{job},salary=#{salary} WHERE id=#{id}</update><!--删除员工--><delete id="deleteEmployee">DELETE from t_employee WHERE id=#{id}</delete><!--根据id查询员工:查询必须设置返回类型参数resultType--><select id="selectOne" resultType="employee">SELECT * from t_employee WHERE id=#{id}</select><!--查询所有员工--><select id="selectAll" resultType="employee">SELECT * from t_employee</select><!--模糊查询--><select id="selectByName" resultType="employee">SELECT * from t_employee WHERE ename like "%"#{ename}"%"</select>
</mapper>
3 db.properties文件(连接数据所需信息)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///web_crud
jdbc.user=root
jdbc.password=root
4 log4j.properties日志文件,可监控mybatis运行(每一条SQL)(需导入log4j jar包)
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.cn.tj.mybatis.mapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
5 数据库表
CREATE TABLE `t_employee` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`eid` varchar(10) NOT NULL,`ename` varchar(6) NOT NULL,`job` varchar(10) DEFAULT NULL,`salary` int(10) DEFAULT NULL,`password` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `eid` (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
6 接口
public interface EmployeeDao {//增加用户public void insertEmployee(Employee user);//根据id修改用户public void updateEmployee(Employee user);//根据id删除用户public void deleteEmployee(Long id);//根据id查询用户public Employee selectOne(Long id);//查询所有用户public List<Employee> selectAll();//模糊查询public List<Employee> selectByName(String name);
}
7 实现类
public class EmpoyeeDaoImpl implements EmployeeDao {@Overridepublic void insertEmployee(Employee employee) {try {//1.加载配置文件信息InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rs);//2.创建sqlSession//openSession()默认的时候是需要手动提交事务,如果设置自动提交事务需要参数设置为trueSqlSession sqlSession = factory.openSession(true);//3.执行增加操作sqlSession.insert("cn.tj.mybatis.mapper.EmployeeMapper.insertEmployee",employee);//手动提交事务
// sqlSession.commit();//4.关闭对象sqlSession.close();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void updateEmployee(Employee employee) {try {InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rs);SqlSession sqlSession = factory.openSession(true);sqlSession.update("cn.tj.mybatis.mapper.EmployeeMapper.updateEmployee",employee);sqlSession.close();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void deleteEmployee(Long id) {try {InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rs);SqlSession sqlSession = factory.openSession(true);sqlSession.delete("cn.tj.mybatis.mapper.EmployeeMapper.deleteEmployee",id);sqlSession.close();} catch (IOException e) {e.printStackTrace();}}@Overridepublic Employee selectOne(Long id) {try {SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession = factory.openSession(true);Employee employee = sqlSession.selectOne("cn.tj.mybatis.mapper.EmployeeMapper.selectOne", id);return employee;} catch (IOException e) {e.printStackTrace();}return null;}@Overridepublic List<Employee> selectAll() {try {SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession = factory.openSession(true);List<Employee> employeeList = sqlSession.selectList("cn.tj.mybatis.mapper.EmployeeMapper.selectAll");return employeeList;} catch (IOException e) {e.printStackTrace();}return null;}@Overridepublic List<Employee> selectByName(String name) {SqlSession sqlSession = MybatisUtil.getSqlSession();return sqlSession.selectList("cn.tj.mybatis.mapper.EmployeeMapper.selectByName", name);}
}
8 工具类
public class MybatisUtil {private static SqlSessionFactory factory=null;/*加载配置文件创建工厂对象,只需要加载一次即可*/static {try {InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");factory = new SqlSessionFactoryBuilder().build(rs);} catch (IOException e) {e.printStackTrace();}}/*加载配置文件创建factory对象*/public static SqlSession getSqlSession(){return factory.openSession(true);}// 关闭对象public static void close(SqlSession sqlSession){if (sqlSession!=null){sqlSession.commit();sqlSession.close();}}
}
9 测试类
public class EmployeeTest {private EmployeeDao employeeDao=new EmpoyeeDaoImpl();/*增加用户测试*/@Testpublic void employee_insert(){Employee employee=new Employee(null,"tj0118","大黄","123","CTO",18000);employeeDao.insertEmployee(employee);System.out.println("用户的id:"+employee.getId());System.out.println("增加用户成功");}/*修改用户*/@Testpublic void employee_update() {employeeDao.updateEmployee(new Employee(2L,"tj018","大黄","123","CEO",18000));}/*删除用户*/@Testpublic void user_delete() {employeeDao.deleteEmployee(8l);}/*根据id查询*/@Testpublic void employee_selectOne() {Employee employee = employeeDao.selectOne(1l);System.out.println(employee);}/*查询所有*/@Testpublic void employee_selectAll() {List<Employee> employeeList = employeeDao.selectAll();for (Employee employee : employeeList) {System.out.println(employee);}}/*模糊查询*/@Testpublic void employee_selectByname() {List<Employee> userList =employeeDao.selectByName("大");for (Employee employee : userList) {System.out.println(employee);}}
}