MyBatisの概要
MyBatisは、元々はapacheのオープンソースプロジェクトiBatisでした。2010年に、このプロジェクトはapacheソフトウェアファンデーションからgoogleコードに移行され、MyBatisに名前が変更されました。本質的に、Mybatisはibatisにいくつかの改良を加えました。
MyBatisは優れた永続層フレームワークであり、jdbc操作データベースのプロセスをカプセル化するため、開発者はSQL自体に注意を払うだけでよく、ドライバーの登録、接続の作成、ステートメントの作成、パラメーターの手動設定などの処理にエネルギーを費やす必要はありません。結果セットの取得など、JDBCの複雑なプロセスコード。
Mybatisは、xmlまたはアノテーションを介して実行されるさまざまなステートメント(statement、preparedStatemnt、CallableStatement)を構成し、ステートメント内のjavaオブジェクトとsqlをマップして、最終的に実行されるSQLステートメントを生成します。最後に、MybatisフレームワークはSQLと結果を実行しますjavaオブジェクトにマップして戻ります。
MyBatisアーキテクチャ
1. SqlMapConfig.xml。このファイルは、mybatisの実行環境などの情報を構成するmybatisのグローバル構成ファイルとして使用されます。
mapper.xmlファイルはsqlマップファイルです。このファイルは、データベースを操作するためのsqlステートメントで構成されています。このファイルはSqlMapConfig.xmlにロードする必要があります。
2. mybatis環境などの構成情報を使用して、SqlSessionFactory、つまりセッションファクトリを構築します。
3. sqlSessionはセッションファクトリによって作成され、データベースの操作はsqlSessionを介して実行する必要があります。
4. mybatisの下部には、Executor executorインターフェースの操作データベースがカスタマイズされています。Executorインターフェースには、基本的なexecutorとキャッシュexecutorの2つの実装があります。
5.マップされたステートメントは、mybatisの低レベルのカプセル化オブジェクトでもあり、mybatis構成情報とSQLマッピング情報をカプセル化します。
mapper.xmlファイルのsqlはマップされたステートメントオブジェクトに対応し、sqlのIDはマップされたステートメントのIDです。
6.マップされたステートメントは、HashMap、基本タイプ、pojoなどのSQL実行の入力パラメーターを定義します。エグゼキューターは、マップされたステートメントを介してsqlを実行する前に、入力Javaオブジェクトをsqlにマップします。入力パラメーターのマッピングは、jdbcプログラミングでprepareStatementのパラメーターを設定することです。
7.マッピングされたステートメントは、HashMap、基本タイプ、pojoなどのsql実行の出力結果を定義します。Executorは、マッピングされたステートメントを通じてsqlを実行した後、出力結果をjavaオブジェクトにマッピングします。出力結果のマッピングプロセスは、jdbcプログラミングでの結果の分析と同等です。プロセス。
エントリーケース:2つのメソッドを使用したCRUD
1. MySQLデータベースを作成する
2. Webプロジェクトを作成する
3. jarパッケージをインポートする
4、log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
5、mybatisConfig.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>
<properties resource="db.properties"></properties>
<!-- setting:mybatis的全局配置项 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!-- typeAliases:别名 -->
<typeAliases>
<typeAlias alias="user" type="org.haiwen.entity.User" />
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/haiwen/entity/User.xml" />
<mapper resource="org/haiwen/mapper/UserMapper.xml" />
</mappers>
</configuration>
6、db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/data
jdbc.username=root
jdbc.password=root
7. User.java、エンティティークラスはデータテーブルに対応します
private Integer id;
private String username;
private String password;
方法1
1、User.xml
名前空間:SQLステートメントを分離するために使用される名前空間。現時点では、自由に名前を付けることができます。
parameterType:入力パラメーターのタイプを指定します。Mybatisは、OGNLを介して入力オブジェクトからパラメーター値を取得し、SQLで連結します。
resultType:出力結果タイプを指定します。Mybatisは、SQLクエリ結果のレコードデータの行を、resultTypeで指定されたタイプのオブジェクトにマップします。
#{}そして$ {}
#{}プレースホルダー記号を表します。#{}を介して、preparedStatementの値をプレースホルダーに設定すると、Javaタイプとjdbcタイプを自動的に変換できます。#{} SQLインジェクションを効果的に防ぐことができます。#{}単純型の値またはpojo属性値を受け取ることができます。parameterTypeが単一の単純型の値を送信する場合、#{}ブラケットは値または他の名前にすることができます。
$ {}は、SQL文字列のスプライシングを意味します。$ {}を使用すると、jdbc型変換なしで、sqlのparameterTypeに渡されたコンテンツをスプライスできます。parameterTypeが単一の単純型値を送信する場合、$ {}は、単純型値またはpojo属性値を受信できます。 、$ {}括弧内の値のみが可能です。
<?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="test">
<!-- 根据id获取用户信息 -->
<select id="findUserById" parameterType="int" resultType="org.haiwen.entity.User">
select * from user where id = #{id}
</select>
<!-- 自定义条件查询用户列表 -->
<select id="findUserByUsername" parameterType="java.lang.String" resultType="org.haiwen.entity.User">
select * from user where username like '%${value}%'
</select>
<!-- 添加用户 -->
<insert id="insertUser" parameterType="org.haiwen.entity.User">
<!-- selectKey将主键返回,需要时再返回 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,password) values(#{username},#{password});
</insert>
</mapper>
2、UserTest.java
selectOneはレコードをクエリします。selectOneを使用して複数のレコードをクエリすると、例外がスローされます。
selectListは1つ以上のレコードをクエリできます。
public class UserTest {
// 会话工厂
public SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException {
// 配置文件
String resource = "mybatisConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws IOException {
// 创建数据库会话实例sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 查询单个记录,根据用户id查询用户信息
User user = sqlSession.selectOne("test.findUserById", 1);
System.out.println(user);
sqlSession.close();
}
@Test
public void testFindUserByUsername() throws IOException {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByUsername", "马");
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void testInsertUser() throws IOException {
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsername("马云云");
user.setPassword("888");
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
sqlSession.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}
方法2:マッパー動的プロキシ
実施原則
Mapperインターフェース開発メソッドでは、プログラマーがMapperインターフェース(Daoインターフェースと同等)を作成するだけで済みます。Mybatisフレームワークは、インターフェース定義に従って、インターフェースの動的プロキシオブジェクトを作成します。プロキシオブジェクトのメソッド本体は、上記のDaoインターフェース実装クラスメソッドと同じです。
Mapperインターフェースの開発は、次の仕様に従う必要があります。
- Mapper.xmlファイルの名前空間は、マッパーインターフェースのクラスパスと同じです。
- Mapperインターフェースのメソッド名は、Mapper.xmlで定義されている各ステートメントのIDと同じです。
- Mapperインターフェースメソッドの入力パラメータータイプは、mapper.xmlで定義されている各SQLのparameterTypeタイプと同じです。
- Mapperインターフェースメソッドの出力パラメータータイプは、mapper.xmlで定義されている各SQLのresultTypeのタイプと同じです。
1、UserMapper.java
public interface UserMapper {
// 根据用户id查询用户信息
public User findUserById(int id) throws Exception;
// 查询用户列表
public List<User> findUserByUsername(String username) throws Exception;
// 添加用户信息
public void insertUser(User user) throws Exception;
}
2、UserMapper.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">
<mapper namespace="org.haiwen.mapper.UserMapper">
<!-- 根据id获取用户信息 -->
<select id="findUserById" parameterType="int" resultType="org.haiwen.entity.User">
select * from user where id = #{id}
</select>
<!-- 自定义条件查询用户列表 -->
<select id="findUserByUsername" parameterType="java.lang.String" resultType="org.haiwen.entity.User">
select * from user where username like '%${value}%'
</select>
<!-- 添加用户 -->
<insert id="insertUser" parameterType="org.haiwen.entity.User">
<!-- selectKey将主键返回,需要时再返回 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,password) values(#{username},#{password});
</insert>
</mapper>
3、UserMapperTest.java
public class UserMapperTest extends TestCase {
private SqlSessionFactory sqlSessionFactory;
@Override
protected void setUp() throws Exception {
// mybatis配置文件
String resource = "mybatisConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 使用SqlSessionFactoryBuilder创建sessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获取mapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//调用代理对象方法
User user = userMapper.findUserById(1);
System.out.println(user);
//关闭session
session.close();
}
@Test
public void testFindUserByUsername() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByUsername("马");
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testInsertUser() throws Exception {
// 获取session
SqlSession session = sqlSessionFactory.openSession();
// 获取mapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
// 要添加的数据
User user = new User();
user.setUsername("马云云");
user.setPassword("888");
// 通过mapper接口添加用户
userMapper.insertUser(user);
// 提交
session.commit();
// 关闭session
session.close();
}
}
MySQLが主キーを返す
keyProperty:返された主キーのどのプロパティがpojoに格納されているか
order:selectKeyの実行順序は、insertステートメントに対して相対的です。mysqlの自己インクリメントの原理は、insertステートメントの実行後に主キーを生成するため、selectKeyの実行順序は
resultType:返される主キーのタイプ
LAST_INSERT_ID():mysqlの関数で、auto_increment自己インクリメントカラムの新しいレコードID値を返します
<insert id="insertUser" parameterType="org.haiwen.entity.User">
<!-- selectKey将主键返回,需要时再返回 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,password) values(#{username},#{password});
</insert>
MySQLはuuidを使用して主キーを実現します
ここで使用される順序は「BEFORE」であることに注意してください
<insert id="insertUser" parameterType="org.haiwen.entity.User">
<!-- selectKey将主键返回,需要时再返回 -->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
select uuid()
</selectKey>
insert into user(id,username,password) values(#{id},#{username},#{password});
</insert>
Oracleはシーケンスを使用して主キーを生成します
<insert id="insertUser" parameterType="org.haiwen.entity.User">
<!-- selectKey将主键返回,需要时再返回 -->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
select 自定义序列.NEXTVAL from dual
</selectKey>
insert into user(id,username,password) values(#{id},#{username},#{password});
</insert>