<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.4version>
dependency>
思路->搭建环境->导入MyBatis->编写代码->测试!
CREATE DATABASE `mybatis`;
use `mybatis`;
CREATE TABLE `user`(
`id` INT (20) not null PRIMARY key,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`,`name`,`pwd`) VALUES
(1,'林青霞','123456'),
(2,'樱木花道','123456'),
(3,'孙悟空','123456')
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.4version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.15version>
dependency>
dependencies>
<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="jdbc:mysql://localhost:3306/mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="289989142"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/lhy/dao/userMapper.xml"/>
mappers>
configuration>
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
//获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//返回SqlSession对象
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
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;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", name='" + name + '\'' +
", 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;
}
}
public interface userDao {
List<user> getUserList();
}
<mapper namespace="com.lhy.dao.userDao" >
<select id="getUserList" resultType="com.lhy.pojo.user">
select * from mybatis.user
select>
mapper>
public class userDaoTest {
@Test
public void test(){
//通过自己写的工具类获取sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行sql方式1 getMapper
userDao mapper = sqlSession.getMapper(userDao.class);
List<user> userList = mapper.getUserList();
for (user user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
}
//查询全部用户
List<user> getUserList();
2.编写对应的mapper中的sal语句
<select id="getUserList" resultType="com.lhy.pojo.user">
select * from mybatis.user
select>
3.测试
@Test
public void test(){
//通过自己写的工具类获取sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行sql方式1 getMapper
userMapper mapper = sqlSession.getMapper(userMapper.class);
List<user> userList = mapper.getUserList();
for (user user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
<insert id="insertUser" parameterType="com.lhy.pojo.user" >
insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
insert>
<update id="updateUser" parameterType="com.lhy.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>
注意:增删改需要提交事务!!
假设我们的实体类或者数据库中的表,字段或者参数过多,我们应该考虑使用map
Map传递参数,直接在sql中取出key即可
<insert id="insertUser2" parameterType="map">
insert into mybatis.user (id, name, pwd ) values (#{userid},#{username},#{userpwd});
insert>
@Test
public void insertUser2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("userid",5);
map.put("username","map");
map.put("userpwd",5);
System.out.println(mapper.insertUser2(map));
sqlSession.commit();
sqlSession.close();
}
<select id="getUserLike" resultType="com.lhy.pojo.user">
select * from mybatis.user where name like #{value}
select>
@Test
public void likeSelect(){
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();
}
}
我们可以通过properties 属性来实现引用配置文件
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【db.properties】
编写一个配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=289989142
在核心配置文件中引入
<properties resource="db.properties">properties>
可以直接引入外部文件
可以在其中增加一些属性配置
如果两处配置有同一字段 优先使用外部配置文件的!
类型别名可为 Java 类型设置一个缩写名字。
它仅用于 XML 配置,意在降低冗余的全限定类名书写。
方法一,为某个指定类起别名
<typeAliases>
<typeAlias type="com.lhy.pojo.user" alias="user">typeAlias>
typeAliases>
方法二,扫描一个包为其中的实体类起别名,默认为这个类的类名首字母小写(可以通过注解修改 在实体类上加@Alias)
<typeAliases>
<package name="com.lhy.pojo"/>
typeAliases>
在实体类比较少的时候使用第一种,比较多的时候可以用第二种
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
自动转换驼峰和下划线
日志
MapperRegistry 注册绑定我们的Mapper文件
方式一:
<mappers>
<mapper resource="com/lhy/dao/userMapper.xml"/>
mappers>
方式二:使用class文件绑定注册
注意 接口和它的mapper配置文件必须同名 并且必须在同一个包里
<mappers>
<mapper class="com.lhy.dao.userMapper"/>
mappers>
方式三:
使用扫描包注册绑定 注意点与方式二一样
<mappers>
<package name="com.lhy.dao"/>
mappers>
作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
数据库中的字段
新建一个项目,拷贝之前的,测试实体类字段不一致的情况
public class user {
//实体类
private int id;
private String name;
private String password;
select id,name,pwd as password form mybatis.user where id = #{id}
结果集映射
id name pwd
id name password
column为数据库中的字段
property为实体类中的属性
<resultMap id="userMap" type="user">
<result column="pwd" property="password"/>
resultMap>
<select id="getUserById" parameterType="int" resultMap="userMap">
select * from mybatis.user where id=#{id}
select>
resultMap 元素是 MyBatis 中最重要最强大的元素。
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
如果一个数据库操作出现了异常需要排错,日志就是最好的帮手
在mybatis中具体使用哪个根据设置来定setting
STDOUT_LOGGING标准日志输出
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 690339675.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2925bf5b]
==> Preparing: select * from mybatis.user where id=?
==> Parameters: 3(Integer)
<== Columns: id, name, pwd
<== Row: 3, 孙悟空, 123456
<== Total: 1
user{id=3, name='孙悟空', password='123456'}
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2925bf5b]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2925bf5b]
Returned connection 690339675 to pool.
Process finished with exit code 0
什么是log4j?
1.Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
2.我们也可以控制每一条日志的输出格式
3.通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
4.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
1.先导包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.log4j properties
#将等级为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=./log/lhy.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
3.配置log4j为日志的实现
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
4.测试运行
??org.apache.ibatis.logging.LogFactory??-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
??org.apache.ibatis.logging.LogFactory??-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
??org.apache.ibatis.datasource.pooled.PooledDataSource??-PooledDataSource forcefully closed/removed all connections.
??org.apache.ibatis.datasource.pooled.PooledDataSource??-PooledDataSource forcefully closed/removed all connections.
??org.apache.ibatis.datasource.pooled.PooledDataSource??-PooledDataSource forcefully closed/removed all connections.
??org.apache.ibatis.datasource.pooled.PooledDataSource??-PooledDataSource forcefully closed/removed all connections.
??org.apache.ibatis.transaction.jdbc.JdbcTransaction??-Opening JDBC Connection
??org.apache.ibatis.datasource.pooled.PooledDataSource??-Created connection 681094281.
??org.apache.ibatis.transaction.jdbc.JdbcTransaction??-Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2898ac89]
??com.lhy.dao.userMapper.getUserById??-==> Preparing: select * from mybatis.user where id=?
??com.lhy.dao.userMapper.getUserById??-==> Parameters: 3(Integer)
??com.lhy.dao.userMapper.getUserById??-<== Total: 1
user{id=3, name='孙悟空', password='123456'}
??org.apache.ibatis.transaction.jdbc.JdbcTransaction??-Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2898ac89]
??org.apache.ibatis.transaction.jdbc.JdbcTransaction??-Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2898ac89]
??org.apache.ibatis.datasource.pooled.PooledDataSource??-Returned connection 681094281 to pool.
Process finished with exit code 0
1.在要使用log4j的类中导入包(apache的)
import org.apache.log4j.Logger;
2.日志对象,加载参数为当前类的class
static Logger logger = Logger.getLogger(userMapperTest.class);
3.日志级别
logger.info("info:进入了log4jTest");
logger.debug("debug:进入了debug");
logger.error("error:error");
SELECT * from user limit startIndex,pageSize
SELECT * from user limit 0,2 (从0开始 查询两个)
List<user> getUserByLimit (Map<String,Integer> map);
* mapper.xml
<select id="getUserByLimit" parameterType="map" resultMap="userMap">
select * from mybatis.user limit #{startIndex},#{pageSize}
</select>
* 测试
@Test
public void getUserByLimitTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("startIndex",0);
map.put("pageSize",2);
List<user> list = mapper.getUserByLimit(map);
for (user user : list) {
System.out.println(user);
}
sqlSession.close();
}
根本原因 解耦
接口
@Select("select * from user")
List<user> getUsers();
核心配置文件
<mappers>
<mapper class="com.lhy.dao.userMapper"/>
mappers>
本质:反射机制实现
底层:动态代理
关于@Param()注解
1.在IDEA中安装插件
2.导入依赖
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
3.使用注解偷懒
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
experimental @var
@UtilityClass
Lombok config system
@Data:无参构造,get,set,tostring,hashcode,equals
@AllArgsConstructor 有参构造
@NoArgsConstructor 无参构造
放在内存中的临时数据
将用户经常查询的数据放在缓存中
在一个sqlSession中有效
sqlSession自带一级缓存