全局配置文件mybatis-config.xml
properties
<·configuration>
①.properties引用外部配置文件配置数据库
db.properties
username=root
password=123456
url=jdbc:mysql://192.168.58.129:3306/mybatis_0105
driver=com.mysql.cj.jdbc.Driver
<properties resource="db.properties"></properties>
<dataSource type="POOLED">
<!-- <property name="driver" value="com.mysql.cj.jdbc.Driver"/>-->
<!-- <property name="url" value="jdbc:mysql://192.168.58.129/mybatis_0105"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="123456"/>-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</configuration>
setttings
mapUnderscoreToCamelCase:是否开启自动驼峰命名规则映射,
mapUnderscoreToCamelCase
<!-- name:配置项的key value:值 驼峰命名bean:loginAccount 数据库:login_account-->
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
private String loginAccount;
数据库 列名login_account
typeAliases(白给)
typeAliases(白给)
typeHandlers
类型处理器(日期处理器3.4之后不用注册)
原生JDBC:获取连接 编写sql语句 预编译sql语句 设置参数 调用更新查询方法 关闭连接
数据库字符类型和javabean类型相互转换
插件plugins
插件通过动态代理机制,介入mybatis四大对象的任何一个方法的执行。
- Execute执行器:执行增删改查
- ParameterHandler:设置参数,调用类型处理器
- ResultSetHandler:结果集处理器
- StatementHandler:预编译参数sql语句
environment环境
由事务管理器transactionManager和数据源dataSource组成
id是当前环境的唯一标识,在environments处使用default切换环境
数据源和事务管理 都交给spring管理
databaseIdProvider
mybatis数据库移植性(了解)
mappers
<!-- 注册新增接口的实现xml文件名-->
<mappers>
<!-- resource表示从类路径下找资源-->
<mapper resource="EmployeeDao.xml"/>
</mappers>
当日完整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>
<!-- resource=类路径
url=网络资源
-->
<properties resource="db.properties"></properties>
<!-- name:配置项的key value:值 驼峰命名bean:loginAccount 数据库:login_account-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 为常用类型bean起别名-->
<!-- <typeAliases>-->
<!--<!– <typeAlias type="com.lwt.bean.Employee" alias="Emp"/>–>-->
<!--<!– name指定包名–>-->
<!-- <package name="com.lwt.bean"/>-->
<!-- </typeAliases>-->
<!-- 每一个环境由数据管理器+数据源组成-->
<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="jdbc:mysql://192.168.58.129/mybatis_0105"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="123456"/>-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 用来考虑数据库移植性,type固定:DB_VENDOR数据库供应商-->
<databaseIdProvider type="DB_VENDOR">
<!-- MySQL Oracle SQL Server-->
<property name="Mysql" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
<!-- *setting mappers*
url:可以从磁盘或网络路径引用
resource:类路径下找sql映射文件
class:接口全类名,小问题:需要将xml和dao接口java文件放在同一目录下
也可使用注解版dao,直接在接口中的方法上标明mybatis格式的sql语句,
配合使用:重要的dao可以写配置,简单dao直接标注解
-->
<!-- 批量注册 name dao所在的包名-->
<!-- <mappers>-->
<!-- <package name="com.lwt.dao"/>-->
<!-- </mappers>-->
<!-- 注册新增接口的实现xml文件名-->
<mappers>
<!-- resource表示从类路径下找资源-->
<mapper resource="EmployeeDao.xml"/>
</mappers>
</configuration>
sql映射文件
对Dao接口的实现描述
EmployeeDao.xml
<?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:名称空间,写(接口的全类名),告诉mybatis这个配置文件是实现哪个接口-->
<mapper namespace="com.lwt.dao.EmployeeDao">
<!-- select定义查询操作
id是方法名,这个配置是对于某个方法的实现(方法名)
resultType:方法运行后的返回值类型(返回对象的全类名)
Employee getEmpById(Integer id);
-->
<select id="getEmpById" resultType="com.lwt.bean.Employee">
-- {属性名}代表取出传递过来的某个参数的值
select * from t_emp where id=#{id}
</select>
<!-- int updateEmp(Employee employee);-->
<update id="updateEmp">
update t_emp set empName=#{empName},gender=#{gender},email=#{email} where id=#{id}
</update>
<!-- int deleteEmp(Integer id);-->
<delete id="deleteEmp">
delete from t_emp where id=#{id}
</delete>
<!-- int insertEmp(Employee employee);-->
<insert id="insertEmp">
insert into t_emp(empName,gender,email) values(#{empName},#{gender},#{email})
</insert>
</mapper>
增删改 出现异常未成功
2021-01-05 17:09.329 DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction:setDesiredAutoCommit) - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6ad82709]
解决:未自动提交事务
SqlSessionFactory和sqlSession对象
SqlSessionFactory创建sqlSession对象,工厂制创建一次。
sqlSession相当于connection和数据库进行交互的,和数据库的一次会话,就应该创建一个新的sqlSession
mapper中的名称空间
<mapper namespace="com.lwt.dao.EmployeeDao>
名称空间必须写src下的全类名
cache
cache-ref
resultMap:结果映射,自定义结果集的封装规则
sql:抽取可重用的sql
增删改
增删改:标签中的属性 id无重载方法名,
mysql支持主键自增如下:
场景:new Employee(null,“lwt”…) 获取id即为null,而不是自增id后的值。
此时让mybatis自动的将自增id赋值给传入的employee对象的id属性
功能:实现获取到插入数据后的自增id
useGeneratedKeys=“true”,使用自动生成的组件
keyProperty=“id”,将刚在自增的id封装给哪个属性
oracle不支持主键自增如下:
<insert>中的<selectKey>查询主键
在oracle无主键自增功能时,使用selectKey order=BEFORE,在核心sql语句之前先运行一个查询主键sql,keyProperty="id"赋值给javabean
查select:标签中的属性
当日完整EmployeeDao.xml
<?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:名称空间,写(接口的全类名),告诉mybatis这个配置文件是实现哪个接口-->
<mapper namespace="com.lwt.dao.EmployeeDao">
<!-- select定义查询操作
id是方法名,这个配置是对于某个方法的实现(方法名)
resultType:方法运行后的返回值类型(返回对象的全类名)
Employee getEmpById(Integer id);
-->
<!--不是批量级法:<typeAlias type="com.lwt.bean.Employee" alias="Emp"/>-->
<!--是批量级法:-->
<select id="getEmpById" resultType="com.lwt.bean.Employee">
-- {属性名}代表取出传递过来的某个参数的值
select * from t_emp where id=#{id}
</select>
<!-- int updateEmp(Employee employee);-->
<update id="updateEmp">
update t_emp set empName=#{empName},gender=#{gender},email=#{email} where id=#{id}
</update>
<!-- boolean deleteEmp(Integer id);-->
<delete id="deleteEmp">
delete from t_emp where id=#{id}
</delete>
<!-- int insertEmp(Employee employee);-->
<insert id="insertEmp" useGeneratedKeys="true" keyProperty="id">
-- 在oracle无主键自增功能时,使用selectKey order=BEFORE,在核心sql语句之前先运行一个查询主键sql,keyProperty="id"赋值给javabean
<!-- <selectKey order="BEFORE" keyProperty="id">-->
<!-- select max(id)+1 from t_emp-->
<!-- </selectKey>-->
insert into t_emp(empName,gender,email) values(#{empName},#{gender},#{email})
</insert>
</mapper>
EmployeeDao
public interface EmployeeDao {
Employee getEmpById(Integer id);
int updateEmp(Employee employee);
boolean deleteEmp(Integer id);
int insertEmp(Employee employee);
}
MybatisCRUDTest
public class MybatisCRUDTest {
SqlSessionFactory sqlSessionFactory;
// @Before
public void initSqlSessionFactory() throws IOException {
// 1.根据全局配置文件创建出SQLSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 是sqlSession工厂,负责创建sqlSeesion对象:sql会话,代表和数据库的一次会话
}
/**
* 测试查询
* @throws IOException
*/
@Test
public void testQuery() throws IOException {
// 1.根据全局配置文件创建出SQLSessionFactory
initSqlSessionFactory();
Employee employee = null;
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession();// 获取和数据库的一次会话:getConnection()
EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class); // 使用sqlSession操作数据库.获取到dao接口的映射器
employee = employeeDao.getEmpById(1);
System.out.println(employeeDao);
} catch (Exception e) {
e.printStackTrace();
}finally {
sqlSession.close();
}
System.out.println(employee);
}
@Test
public void testInsert() throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true); // true自动提交
try {
EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);
Employee employee = new Employee(null, "lwt3", "lwt@qq.com", 1);
int i = employeeDao.insertEmp(employee);
System.out.println("影响-->"+i);
System.out.println("自增的id如今值:"+employee.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
//法一:手动提交事务
// sqlSession.commit();
sqlSession.close();
}
}
}
Employee
public class Employee {
private Integer id;
private String empName;
private String email;
private Integer gender;
private String loginAccount;
public Employee() {
}
public Employee(Integer id, String empName, String email, Integer gender) {
this.id = id;
this.empName = empName;
this.email = email;
this.gender = gender;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", empName='" + empName + '\'' +
", email='" + email + '\'' +
", gender=" + gender +
", loginAccount='" + loginAccount + '\'' +
'}';
}
}
log4j.properties
log4j.rootLogger=debug,lwt.File
log4j.logger.com.lwt.dao=debug,lwt.dao.File
#执行日志文件记录方式为 每天滚动记录
log4j.appender.lwt.File=org.apache.log4j.DailyRollingFileAppender
#指定日志的文件保存位置
log4j.appender.lwt.File.file=d:\\Spring1202\\javaSE-mybatis\\0105.log
#每天滚动生成日志文件名的日期戳格式
log4j.appender.lwt.File.DatePattern=.yyyy-MM-dd
#指定日志自定义输出格式为灵活指定
log4j.appender.lwt.File.layout=org.apache.log4j.PatternLayout
#设置日志自定义输出格式内容 %d输出时间 %p输出日志级别(5p表示占5个字符长度)%c类完全限定名 %M方法名 %m输出的信息 %n回车换行
log4j.appender.lwt.File.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm.SSS} %5p (%C:%M) - %m%n
#输出日志到控制台
log4j.appender.lwt.Console=org.apache.log4j.ConsoleAppender
#log4j.appender.lwt.Console.layout=org.apache.log4j.SimpleLayout
log4j.appender.lwt.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.lwt.Console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %5p (%C:%M) - %m%n
log4j.appender.lwt.dao.File=org.apache.log4j.DailyRollingFileAppender
log4j.appender.lwt.dao.File.file=d:\\Spring1202\\javaSE-mybatis\\0105.log
log4j.appender.lwt.dao.File.DatePattern=.yyyy-MM-dd
log4j.appender.lwt.dao.File.layout=org.apache.log4j.PatternLayout
log4j.appender.lwt.dao.File.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm.SSS} %5p (%C:%M) - %m%n